Commit 00b3ed16 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Staging: add wlan-ng prism2 usb driver

This adds the wlan-ng prism2 USB driver to the drivers/staging tree.

The code was originally written by the linux-wlan-ng team, patched by
some Novell engineers to properly work on newer kernels, and then hacked
into place in order to get it to build properly in a single subdirectory
within the kernel tree by me.

It supports a wide range of older USB prism2 devices, and contains a
80211 stack to support this single driver.

Cc: Christian Zoz <zoz@suse.de>
Cc: Andreas Gruenbacher <agruen@suse.de>
Cc: linux-wireless <linux-wireless@vger.kernel.org>
Cc: John Linville <linville@tuxdriver.com>
Cc: Helmut Schaa <helmut.schaa@googlemail.com>
Cc: linux-wlan-ng <solomon@linux-wlan.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 66101de1
......@@ -37,4 +37,6 @@ source "drivers/staging/usbip/Kconfig"
source "drivers/staging/winbond/Kconfig"
source "drivers/staging/wlan-ng/Kconfig"
endif # STAGING
......@@ -7,3 +7,4 @@ obj-$(CONFIG_ME4000) += me4000/
obj-$(CONFIG_VIDEO_GO7007) += go7007/
obj-$(CONFIG_USB_IP_COMMON) += usbip/
obj-$(CONFIG_W35UND) += winbond/
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
config PRISM2_USB
tristate "Prism2.5 USB driver"
depends on USB
default n
---help---
This is the wlan-ng prism 2.5 USB driver for a wide range of
old USB wireless devices.
To compile this driver as a module, choose M here: the module
will be called prism2_usb.
obj-$(CONFIG_PRISM2_USB) += prism2_usb.o
obj-$(CONFIG_PRISM2_USB) += p80211.o
p80211-objs := p80211mod.o \
p80211conv.o \
p80211req.o \
p80211wep.o \
p80211wext.o \
p80211netdev.o
TODO:
- checkpatch.pl cleanups
- sparse warnings
- Lindent cleanups
- move to use the in-kernel wireless stack
- possible enable the pcmcia and pci portions of the driver
Please send all patches to Greg Kroah-Hartman <greg@kroah.com>
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/* src/p80211/p80211conv.c
*
* Ether/802.11 conversions and packet buffer routines
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file defines the functions that perform Ethernet to/from
* 802.11 frame conversions.
*
* --------------------------------------------------------------------
*/
/*================================================================*/
/* System Includes */
#define __NO_VERSION__ /* prevent the static definition */
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <asm/byteorder.h>
#include "version.h"
#include "wlan_compat.h"
/*================================================================*/
/* Project Includes */
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
#include "p80211mgmt.h"
#include "p80211msg.h"
#include "p80211netdev.h"
#include "p80211ioctl.h"
#include "p80211req.h"
/*================================================================*/
/* Local Constants */
/*================================================================*/
/* Local Macros */
/*================================================================*/
/* Local Types */
/*================================================================*/
/* Local Static Definitions */
static UINT8 oui_rfc1042[] = {0x00, 0x00, 0x00};
static UINT8 oui_8021h[] = {0x00, 0x00, 0xf8};
/*================================================================*/
/* Local Function Declarations */
/*================================================================*/
/* Function Definitions */
/*----------------------------------------------------------------
* p80211pb_ether_to_80211
*
* Uses the contents of the ether frame and the etherconv setting
* to build the elements of the 802.11 frame.
*
* We don't actually set
* up the frame header here. That's the MAC's job. We're only handling
* conversion of DIXII or 802.3+LLC frames to something that works
* with 802.11.
*
* Note -- 802.11 header is NOT part of the skb. Likewise, the 802.11
* FCS is also not present and will need to be added elsewhere.
*
* Arguments:
* ethconv Conversion type to perform
* skb skbuff containing the ether frame
* p80211_hdr 802.11 header
*
* Returns:
* 0 on success, non-zero otherwise
*
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
int skb_ether_to_p80211( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
{
UINT16 fc;
UINT16 proto;
wlan_ethhdr_t e_hdr;
wlan_llc_t *e_llc;
wlan_snap_t *e_snap;
int foo;
DBFENTER;
memcpy(&e_hdr, skb->data, sizeof(e_hdr));
if (skb->len <= 0) {
WLAN_LOG_DEBUG(1, "zero-length skb!\n");
return 1;
}
if ( ethconv == WLAN_ETHCONV_ENCAP ) { /* simplest case */
WLAN_LOG_DEBUG(3, "ENCAP len: %d\n", skb->len);
/* here, we don't care what kind of ether frm. Just stick it */
/* in the 80211 payload */
/* which is to say, leave the skb alone. */
} else {
/* step 1: classify ether frame, DIX or 802.3? */
proto = ntohs(e_hdr.type);
if ( proto <= 1500 ) {
WLAN_LOG_DEBUG(3, "802.3 len: %d\n", skb->len);
/* codes <= 1500 reserved for 802.3 lengths */
/* it's 802.3, pass ether payload unchanged, */
/* trim off ethernet header */
skb_pull(skb, WLAN_ETHHDR_LEN);
/* leave off any PAD octets. */
skb_trim(skb, proto);
} else {
WLAN_LOG_DEBUG(3, "DIXII len: %d\n", skb->len);
/* it's DIXII, time for some conversion */
/* trim off ethernet header */
skb_pull(skb, WLAN_ETHHDR_LEN);
/* tack on SNAP */
e_snap = (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t));
e_snap->type = htons(proto);
if ( ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto) ) {
memcpy( e_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN);
} else {
memcpy( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN);
}
/* tack on llc */
e_llc = (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t));
e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */
e_llc->ssap = 0xAA;
e_llc->ctl = 0x03;
}
}
/* Set up the 802.11 header */
/* It's a data frame */
fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
switch ( wlandev->macmode ) {
case WLAN_MACMODE_IBSS_STA:
memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
memcpy(p80211_hdr->a3.a3, wlandev->bssid, WLAN_ADDR_LEN);
break;
case WLAN_MACMODE_ESS_STA:
fc |= host2ieee16(WLAN_SET_FC_TODS(1));
memcpy(p80211_hdr->a3.a1, wlandev->bssid, WLAN_ADDR_LEN);
memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, WLAN_ADDR_LEN);
break;
case WLAN_MACMODE_ESS_AP:
fc |= host2ieee16(WLAN_SET_FC_FROMDS(1));
memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
memcpy(p80211_hdr->a3.a2, wlandev->bssid, WLAN_ADDR_LEN);
memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, WLAN_ADDR_LEN);
break;
default:
WLAN_LOG_ERROR("Error: Converting eth to wlan in unknown mode.\n");
return 1;
break;
}
p80211_wep->data = NULL;
if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && (wlandev->hostwep & HOSTWEP_ENCRYPT)) {
// XXXX need to pick keynum other than default?
#if 1
p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
#else
p80211_wep->data = skb->data;
#endif
if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
skb->len,
(wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK),
p80211_wep->iv, p80211_wep->icv))) {
WLAN_LOG_WARNING("Host en-WEP failed, dropping frame (%d).\n", foo);
return 2;
}
fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
}
// skb->nh.raw = skb->data;
p80211_hdr->a3.fc = fc;
p80211_hdr->a3.dur = 0;
p80211_hdr->a3.seq = 0;
DBFEXIT;
return 0;
}
/* jkriegl: from orinoco, modified */
static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
p80211_rxmeta_t *rxmeta)
{
int i;
/* Gather wireless spy statistics: for each packet, compare the
* source address with out list, and if match, get the stats... */
for (i = 0; i < wlandev->spy_number; i++) {
if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
memcpy(wlandev->spy_address[i], mac, ETH_ALEN);
wlandev->spy_stat[i].level = rxmeta->signal;
wlandev->spy_stat[i].noise = rxmeta->noise;
wlandev->spy_stat[i].qual = (rxmeta->signal > rxmeta->noise) ? \
(rxmeta->signal - rxmeta->noise) : 0;
wlandev->spy_stat[i].updated = 0x7;
}
}
}
/*----------------------------------------------------------------
* p80211pb_80211_to_ether
*
* Uses the contents of a received 802.11 frame and the etherconv
* setting to build an ether frame.
*
* This function extracts the src and dest address from the 802.11
* frame to use in the construction of the eth frame.
*
* Arguments:
* ethconv Conversion type to perform
* skb Packet buffer containing the 802.11 frame
*
* Returns:
* 0 on success, non-zero otherwise
*
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb)
{
netdevice_t *netdev = wlandev->netdev;
UINT16 fc;
UINT payload_length;
UINT payload_offset;
UINT8 daddr[WLAN_ETHADDR_LEN];
UINT8 saddr[WLAN_ETHADDR_LEN];
p80211_hdr_t *w_hdr;
wlan_ethhdr_t *e_hdr;
wlan_llc_t *e_llc;
wlan_snap_t *e_snap;
int foo;
DBFENTER;
payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
payload_offset = WLAN_HDR_A3_LEN;
w_hdr = (p80211_hdr_t *) skb->data;
/* setup some vars for convenience */
fc = ieee2host16(w_hdr->a3.fc);
if ( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
} else if( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1) ) {
memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
} else if( (WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
} else {
payload_offset = WLAN_HDR_A4_LEN;
payload_length -= ( WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN );
if (payload_length < 0 ) {
WLAN_LOG_ERROR("A4 frame too short!\n");
return 1;
}
memcpy(daddr, w_hdr->a4.a3, WLAN_ETHADDR_LEN);
memcpy(saddr, w_hdr->a4.a4, WLAN_ETHADDR_LEN);
}
/* perform de-wep if necessary.. */
if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
if (payload_length <= 8) {
WLAN_LOG_ERROR("WEP frame too short (%u).\n",
skb->len);
return 1;
}
if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
payload_length - 8, -1,
skb->data + payload_offset,
skb->data + payload_offset + payload_length - 4))) {
/* de-wep failed, drop skb. */
WLAN_LOG_DEBUG(1, "Host de-WEP failed, dropping frame (%d).\n", foo);
wlandev->rx.decrypt_err++;
return 2;
}
/* subtract the IV+ICV length off the payload */
payload_length -= 8;
/* chop off the IV */
skb_pull(skb, 4);
/* chop off the ICV. */
skb_trim(skb, skb->len - 4);
wlandev->rx.decrypt++;
}
e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset);
e_llc = (wlan_llc_t *) (skb->data + payload_offset);
e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
/* Test for the various encodings */
if ( (payload_length >= sizeof(wlan_ethhdr_t)) &&
( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) &&
((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
(memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {
WLAN_LOG_DEBUG(3, "802.3 ENCAP len: %d\n", payload_length);
/* 802.3 Encapsulated */
/* Test for an overlength frame */
if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
/* A bogus length ethfrm has been encap'd. */
/* Is someone trying an oflow attack? */
WLAN_LOG_ERROR("ENCAP frame too large (%d > %d)\n",
payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
return 1;
}
/* Chop off the 802.11 header. it's already sane. */
skb_pull(skb, payload_offset);
/* chop off the 802.11 CRC */
skb_trim(skb, skb->len - WLAN_CRC_LEN);
} else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
(e_llc->dsap == 0xaa) &&
(e_llc->ssap == 0xaa) &&
(e_llc->ctl == 0x03) &&
(((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) &&
(ethconv == WLAN_ETHCONV_8021h) &&
(p80211_stt_findproto(ieee2host16(e_snap->type)))) ||
(memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)!=0)))
{
WLAN_LOG_DEBUG(3, "SNAP+RFC1042 len: %d\n", payload_length);
/* it's a SNAP + RFC1042 frame && protocol is in STT */
/* build 802.3 + RFC1042 */
/* Test for an overlength frame */
if ( payload_length > netdev->mtu ) {
/* A bogus length ethfrm has been sent. */
/* Is someone trying an oflow attack? */
WLAN_LOG_ERROR("SNAP frame too large (%d > %d)\n",
payload_length, netdev->mtu);
return 1;
}
/* chop 802.11 header from skb. */
skb_pull(skb, payload_offset);
/* create 802.3 header at beginning of skb. */
e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
e_hdr->type = htons(payload_length);
/* chop off the 802.11 CRC */
skb_trim(skb, skb->len - WLAN_CRC_LEN);
} else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
(e_llc->dsap == 0xaa) &&
(e_llc->ssap == 0xaa) &&
(e_llc->ctl == 0x03) ) {
WLAN_LOG_DEBUG(3, "802.1h/RFC1042 len: %d\n", payload_length);
/* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */
/* build a DIXII + RFC894 */
/* Test for an overlength frame */
if ((payload_length - sizeof(wlan_llc_t) - sizeof(wlan_snap_t))
> netdev->mtu) {
/* A bogus length ethfrm has been sent. */
/* Is someone trying an oflow attack? */
WLAN_LOG_ERROR("DIXII frame too large (%ld > %d)\n",
(long int) (payload_length - sizeof(wlan_llc_t) -
sizeof(wlan_snap_t)),
netdev->mtu);
return 1;
}
/* chop 802.11 header from skb. */
skb_pull(skb, payload_offset);
/* chop llc header from skb. */
skb_pull(skb, sizeof(wlan_llc_t));
/* chop snap header from skb. */
skb_pull(skb, sizeof(wlan_snap_t));
/* create 802.3 header at beginning of skb. */
e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
e_hdr->type = e_snap->type;
memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
/* chop off the 802.11 CRC */
skb_trim(skb, skb->len - WLAN_CRC_LEN);
} else {
WLAN_LOG_DEBUG(3, "NON-ENCAP len: %d\n", payload_length);
/* any NON-ENCAP */
/* it's a generic 80211+LLC or IPX 'Raw 802.3' */
/* build an 802.3 frame */
/* allocate space and setup hostbuf */
/* Test for an overlength frame */
if ( payload_length > netdev->mtu ) {
/* A bogus length ethfrm has been sent. */
/* Is someone trying an oflow attack? */
WLAN_LOG_ERROR("OTHER frame too large (%d > %d)\n",
payload_length,
netdev->mtu);
return 1;
}
/* Chop off the 802.11 header. */
skb_pull(skb, payload_offset);
/* create 802.3 header at beginning of skb. */
e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
e_hdr->type = htons(payload_length);
/* chop off the 802.11 CRC */
skb_trim(skb, skb->len - WLAN_CRC_LEN);
}
skb->protocol = eth_type_trans(skb, netdev);
skb_reset_mac_header(skb);
/* jkriegl: process signal and noise as set in hfa384x_int_rx() */
/* jkriegl: only process signal/noise if requested by iwspy */
if (wlandev->spy_number)
orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, P80211SKB_RXMETA(skb));
/* Free the metadata */
p80211skb_rxmeta_detach(skb);
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* p80211_stt_findproto
*
* Searches the 802.1h Selective Translation Table for a given
* protocol.
*
* Arguments:
* proto protocl number (in host order) to search for.
*
* Returns:
* 1 - if the table is empty or a match is found.
* 0 - if the table is non-empty and a match is not found.
*
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
int p80211_stt_findproto(UINT16 proto)
{
/* Always return found for now. This is the behavior used by the */
/* Zoom Win95 driver when 802.1h mode is selected */
/* TODO: If necessary, add an actual search we'll probably
need this to match the CMAC's way of doing things.
Need to do some testing to confirm.
*/
if (proto == 0x80f3) /* APPLETALK */
return 1;
return 0;
}
/*----------------------------------------------------------------
* p80211skb_rxmeta_detach
*
* Disconnects the frmmeta and rxmeta from an skb.
*
* Arguments:
* wlandev The wlandev this skb belongs to.
* skb The skb we're attaching to.
*
* Returns:
* 0 on success, non-zero otherwise
*
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
void
p80211skb_rxmeta_detach(struct sk_buff *skb)
{
p80211_rxmeta_t *rxmeta;
p80211_frmmeta_t *frmmeta;
DBFENTER;
/* Sanity checks */
if ( skb==NULL ) { /* bad skb */
WLAN_LOG_DEBUG(1, "Called w/ null skb.\n");
goto exit;
}
frmmeta = P80211SKB_FRMMETA(skb);
if ( frmmeta == NULL ) { /* no magic */
WLAN_LOG_DEBUG(1, "Called w/ bad frmmeta magic.\n");
goto exit;
}
rxmeta = frmmeta->rx;
if ( rxmeta == NULL ) { /* bad meta ptr */
WLAN_LOG_DEBUG(1, "Called w/ bad rxmeta ptr.\n");
goto exit;
}
/* Free rxmeta */
kfree(rxmeta);
/* Clear skb->cb */
memset(skb->cb, 0, sizeof(skb->cb));
exit:
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* p80211skb_rxmeta_attach
*
* Allocates a p80211rxmeta structure, initializes it, and attaches
* it to an skb.
*
* Arguments:
* wlandev The wlandev this skb belongs to.
* skb The skb we're attaching to.
*
* Returns:
* 0 on success, non-zero otherwise
*
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
int
p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
{
int result = 0;
p80211_rxmeta_t *rxmeta;
p80211_frmmeta_t *frmmeta;
DBFENTER;
/* If these already have metadata, we error out! */
if (P80211SKB_RXMETA(skb) != NULL) {
WLAN_LOG_ERROR("%s: RXmeta already attached!\n",
wlandev->name);
result = 0;
goto exit;
}
/* Allocate the rxmeta */
rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC);
if ( rxmeta == NULL ) {
WLAN_LOG_ERROR("%s: Failed to allocate rxmeta.\n",
wlandev->name);
result = 1;
goto exit;
}
/* Initialize the rxmeta */
memset(rxmeta, 0, sizeof(p80211_rxmeta_t));
rxmeta->wlandev = wlandev;
rxmeta->hosttime = jiffies;
/* Overlay a frmmeta_t onto skb->cb */
memset(skb->cb, 0, sizeof(p80211_frmmeta_t));
frmmeta = (p80211_frmmeta_t*)(skb->cb);
frmmeta->magic = P80211_FRMMETA_MAGIC;
frmmeta->rx = rxmeta;
exit:
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* p80211skb_free
*
* Frees an entire p80211skb by checking and freeing the meta struct
* and then freeing the skb.
*
* Arguments:
* wlandev The wlandev this skb belongs to.
* skb The skb we're attaching to.
*
* Returns:
* 0 on success, non-zero otherwise
*
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
void
p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
{
p80211_frmmeta_t *meta;
DBFENTER;
meta = P80211SKB_FRMMETA(skb);
if ( meta && meta->rx) {
p80211skb_rxmeta_detach(skb);
} else {
WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb);
}
dev_kfree_skb(skb);
DBFEXIT;
return;
}
/* p80211conv.h
*
* Ether/802.11 conversions and packet buffer routines
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file declares the functions, types and macros that perform
* Ethernet to/from 802.11 frame conversions.
*
* --------------------------------------------------------------------
*/
#ifndef _LINUX_P80211CONV_H
#define _LINUX_P80211CONV_H
/*================================================================*/
/* Constants */
#define WLAN_ETHADDR_LEN 6
#define WLAN_IEEE_OUI_LEN 3
#define WLAN_ETHCONV_ENCAP 1
#define WLAN_ETHCONV_RFC1042 2
#define WLAN_ETHCONV_8021h 3
#define WLAN_MIN_ETHFRM_LEN 60
#define WLAN_MAX_ETHFRM_LEN 1514
#define WLAN_ETHHDR_LEN 14
#define P80211CAPTURE_VERSION 0x80211001
/*================================================================*/
/* Macros */
#define P80211_FRMMETA_MAGIC 0x802110
#define P80211SKB_FRMMETA(s) \
(((((p80211_frmmeta_t*)((s)->cb))->magic)==P80211_FRMMETA_MAGIC) ? \
((p80211_frmmeta_t*)((s)->cb)) : \
(NULL))
#define P80211SKB_RXMETA(s) \
(P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t*)(NULL)))
typedef struct p80211_rxmeta
{
struct wlandevice *wlandev;
UINT64 mactime; /* Hi-rez MAC-supplied time value */
UINT64 hosttime; /* Best-rez host supplied time value */
UINT rxrate; /* Receive data rate in 100kbps */
UINT priority; /* 0-15, 0=contention, 6=CF */
INT signal; /* An SSI, see p80211netdev.h */
INT noise; /* An SSI, see p80211netdev.h */
UINT channel; /* Receive channel (mostly for snifs) */
UINT preamble; /* P80211ENUM_preambletype_* */
UINT encoding; /* P80211ENUM_encoding_* */
} p80211_rxmeta_t;
typedef struct p80211_frmmeta
{
UINT magic;
p80211_rxmeta_t *rx;
} p80211_frmmeta_t;
void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb);
int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb);
void p80211skb_rxmeta_detach(struct sk_buff *skb);
/*================================================================*/
/* Types */
/*
* Frame capture header. (See doc/capturefrm.txt)
*/
typedef struct p80211_caphdr
{
UINT32 version;
UINT32 length;
UINT64 mactime;
UINT64 hosttime;
UINT32 phytype;
UINT32 channel;
UINT32 datarate;
UINT32 antenna;
UINT32 priority;
UINT32 ssi_type;
INT32 ssi_signal;
INT32 ssi_noise;
UINT32 preamble;
UINT32 encoding;
} p80211_caphdr_t;
/* buffer free method pointer type */
typedef void (* freebuf_method_t)(void *buf, int size);
typedef struct p80211_metawep {
void *data;
UINT8 iv[4];
UINT8 icv[4];
} p80211_metawep_t;
/* local ether header type */
typedef struct wlan_ethhdr
{
UINT8 daddr[WLAN_ETHADDR_LEN];
UINT8 saddr[WLAN_ETHADDR_LEN];
UINT16 type;
} __WLAN_ATTRIB_PACK__ wlan_ethhdr_t;
/* local llc header type */
typedef struct wlan_llc
{
UINT8 dsap;
UINT8 ssap;
UINT8 ctl;
} __WLAN_ATTRIB_PACK__ wlan_llc_t;
/* local snap header type */
typedef struct wlan_snap
{
UINT8 oui[WLAN_IEEE_OUI_LEN];
UINT16 type;
} __WLAN_ATTRIB_PACK__ wlan_snap_t;
/* Circular include trick */
struct wlandevice;
/*================================================================*/
/* Externs */
/*================================================================*/
/*Function Declarations */
int skb_p80211_to_ether( struct wlandevice *wlandev, UINT32 ethconv,
struct sk_buff *skb);
int skb_ether_to_p80211( struct wlandevice *wlandev, UINT32 ethconv,
struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
p80211_metawep_t *p80211_wep );
int p80211_stt_findproto(UINT16 proto);
int p80211_stt_addproto(UINT16 proto);
#endif
/* p80211hdr.h
*
* Macros, types, and functions for handling 802.11 MAC headers
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file declares the constants and types used in the interface
* between a wlan driver and the user mode utilities.
*
* Note:
* - Constant values are always in HOST byte order. To assign
* values to multi-byte fields they _must_ be converted to
* ieee byte order. To retrieve multi-byte values from incoming
* frames, they must be converted to host order.
*
* All functions declared here are implemented in p80211.c
* --------------------------------------------------------------------
*/
#ifndef _P80211HDR_H
#define _P80211HDR_H
/*================================================================*/
/* System Includes */
/*================================================================*/
/* Project Includes */
#ifndef _WLAN_COMPAT_H
#include "wlan_compat.h"
#endif
/*================================================================*/
/* Constants */
/*--- Sizes -----------------------------------------------*/
#define WLAN_ADDR_LEN 6
#define WLAN_CRC_LEN 4
#define WLAN_BSSID_LEN 6
#define WLAN_BSS_TS_LEN 8
#define WLAN_HDR_A3_LEN 24
#define WLAN_HDR_A4_LEN 30
#define WLAN_SSID_MAXLEN 32
#define WLAN_DATA_MAXLEN 2312
#define WLAN_A3FR_MAXLEN (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
#define WLAN_A4FR_MAXLEN (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
#define WLAN_BEACON_FR_MAXLEN (WLAN_HDR_A3_LEN + 334)
#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_A3_LEN + 0)
#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_A3_LEN + 2)
#define WLAN_ASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 48)
#define WLAN_ASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16)
#define WLAN_REASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 54)
#define WLAN_REASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16)
#define WLAN_PROBEREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 44)
#define WLAN_PROBERESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 78)
#define WLAN_AUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 261)
#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 2)
#define WLAN_WEP_NKEYS 4
#define WLAN_WEP_MAXKEYLEN 13
#define WLAN_CHALLENGE_IE_LEN 130
#define WLAN_CHALLENGE_LEN 128
#define WLAN_WEP_IV_LEN 4
#define WLAN_WEP_ICV_LEN 4
/*--- Frame Control Field -------------------------------------*/
/* Frame Types */
#define WLAN_FTYPE_MGMT 0x00
#define WLAN_FTYPE_CTL 0x01
#define WLAN_FTYPE_DATA 0x02
/* Frame subtypes */
/* Management */
#define WLAN_FSTYPE_ASSOCREQ 0x00
#define WLAN_FSTYPE_ASSOCRESP 0x01
#define WLAN_FSTYPE_REASSOCREQ 0x02
#define WLAN_FSTYPE_REASSOCRESP 0x03
#define WLAN_FSTYPE_PROBEREQ 0x04
#define WLAN_FSTYPE_PROBERESP 0x05
#define WLAN_FSTYPE_BEACON 0x08
#define WLAN_FSTYPE_ATIM 0x09
#define WLAN_FSTYPE_DISASSOC 0x0a
#define WLAN_FSTYPE_AUTHEN 0x0b
#define WLAN_FSTYPE_DEAUTHEN 0x0c
/* Control */
#define WLAN_FSTYPE_BLOCKACKREQ 0x8
#define WLAN_FSTYPE_BLOCKACK 0x9
#define WLAN_FSTYPE_PSPOLL 0x0a
#define WLAN_FSTYPE_RTS 0x0b
#define WLAN_FSTYPE_CTS 0x0c
#define WLAN_FSTYPE_ACK 0x0d
#define WLAN_FSTYPE_CFEND 0x0e
#define WLAN_FSTYPE_CFENDCFACK 0x0f
/* Data */
#define WLAN_FSTYPE_DATAONLY 0x00
#define WLAN_FSTYPE_DATA_CFACK 0x01
#define WLAN_FSTYPE_DATA_CFPOLL 0x02
#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03
#define WLAN_FSTYPE_NULL 0x04
#define WLAN_FSTYPE_CFACK 0x05
#define WLAN_FSTYPE_CFPOLL 0x06
#define WLAN_FSTYPE_CFACK_CFPOLL 0x07
/*================================================================*/
/* Macros */
/*--- FC Macros ----------------------------------------------*/
/* Macros to get/set the bitfields of the Frame Control Field */
/* GET_FC_??? - takes the host byte-order value of an FC */
/* and retrieves the value of one of the */
/* bitfields and moves that value so its lsb is */
/* in bit 0. */
/* SET_FC_??? - takes a host order value for one of the FC */
/* bitfields and moves it to the proper bit */
/* location for ORing into a host order FC. */
/* To send the FC produced from SET_FC_???, */
/* one must put the bytes in IEEE order. */
/* e.g. */
/* printf("the frame subtype is %x", */
/* GET_FC_FTYPE( ieee2host( rx.fc ))) */
/* */
/* tx.fc = host2ieee( SET_FC_FTYPE(WLAN_FTYP_CTL) | */
/* SET_FC_FSTYPE(WLAN_FSTYPE_RTS) ); */
/*------------------------------------------------------------*/
#define WLAN_GET_FC_PVER(n) (((UINT16)(n)) & (BIT0 | BIT1))
#define WLAN_GET_FC_FTYPE(n) ((((UINT16)(n)) & (BIT2 | BIT3)) >> 2)
#define WLAN_GET_FC_FSTYPE(n) ((((UINT16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
#define WLAN_GET_FC_TODS(n) ((((UINT16)(n)) & (BIT8)) >> 8)
#define WLAN_GET_FC_FROMDS(n) ((((UINT16)(n)) & (BIT9)) >> 9)
#define WLAN_GET_FC_MOREFRAG(n) ((((UINT16)(n)) & (BIT10)) >> 10)
#define WLAN_GET_FC_RETRY(n) ((((UINT16)(n)) & (BIT11)) >> 11)
#define WLAN_GET_FC_PWRMGT(n) ((((UINT16)(n)) & (BIT12)) >> 12)
#define WLAN_GET_FC_MOREDATA(n) ((((UINT16)(n)) & (BIT13)) >> 13)
#define WLAN_GET_FC_ISWEP(n) ((((UINT16)(n)) & (BIT14)) >> 14)
#define WLAN_GET_FC_ORDER(n) ((((UINT16)(n)) & (BIT15)) >> 15)
#define WLAN_SET_FC_PVER(n) ((UINT16)(n))
#define WLAN_SET_FC_FTYPE(n) (((UINT16)(n)) << 2)
#define WLAN_SET_FC_FSTYPE(n) (((UINT16)(n)) << 4)
#define WLAN_SET_FC_TODS(n) (((UINT16)(n)) << 8)
#define WLAN_SET_FC_FROMDS(n) (((UINT16)(n)) << 9)
#define WLAN_SET_FC_MOREFRAG(n) (((UINT16)(n)) << 10)
#define WLAN_SET_FC_RETRY(n) (((UINT16)(n)) << 11)
#define WLAN_SET_FC_PWRMGT(n) (((UINT16)(n)) << 12)
#define WLAN_SET_FC_MOREDATA(n) (((UINT16)(n)) << 13)
#define WLAN_SET_FC_ISWEP(n) (((UINT16)(n)) << 14)
#define WLAN_SET_FC_ORDER(n) (((UINT16)(n)) << 15)
/*--- Duration Macros ----------------------------------------*/
/* Macros to get/set the bitfields of the Duration Field */
/* - the duration value is only valid when bit15 is zero */
/* - the firmware handles these values, so I'm not going */
/* these macros right now. */
/*------------------------------------------------------------*/
/*--- Sequence Control Macros -------------------------------*/
/* Macros to get/set the bitfields of the Sequence Control */
/* Field. */
/*------------------------------------------------------------*/
#define WLAN_GET_SEQ_FRGNUM(n) (((UINT16)(n)) & (BIT0|BIT1|BIT2|BIT3))
#define WLAN_GET_SEQ_SEQNUM(n) ((((UINT16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
/*--- Data ptr macro -----------------------------------------*/
/* Creates a UINT8* to the data portion of a frame */
/* Assumes you're passing in a ptr to the beginning of the hdr*/
/*------------------------------------------------------------*/
#define WLAN_HDR_A3_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A3_LEN)
#define WLAN_HDR_A4_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A4_LEN)
#define DOT11_RATE5_ISBASIC_GET(r) (((UINT8)(r)) & BIT7)
/*================================================================*/
/* Types */
/* BSS Timestamp */
typedef UINT8 wlan_bss_ts_t[WLAN_BSS_TS_LEN];
/* Generic 802.11 Header types */
typedef struct p80211_hdr_a3
{
UINT16 fc;
UINT16 dur;
UINT8 a1[WLAN_ADDR_LEN];
UINT8 a2[WLAN_ADDR_LEN];
UINT8 a3[WLAN_ADDR_LEN];
UINT16 seq;
} __WLAN_ATTRIB_PACK__ p80211_hdr_a3_t;
typedef struct p80211_hdr_a4
{
UINT16 fc;
UINT16 dur;
UINT8 a1[WLAN_ADDR_LEN];
UINT8 a2[WLAN_ADDR_LEN];
UINT8 a3[WLAN_ADDR_LEN];
UINT16 seq;
UINT8 a4[WLAN_ADDR_LEN];
} __WLAN_ATTRIB_PACK__ p80211_hdr_a4_t;
typedef union p80211_hdr
{
p80211_hdr_a3_t a3;
p80211_hdr_a4_t a4;
} __WLAN_ATTRIB_PACK__ p80211_hdr_t;
/*================================================================*/
/* Extern Declarations */
/*================================================================*/
/* Function Declarations */
/* Frame and header lenght macros */
#define WLAN_CTL_FRAMELEN(fstype) (\
(fstype) == WLAN_FSTYPE_BLOCKACKREQ ? 24 : \
(fstype) == WLAN_FSTYPE_BLOCKACK ? 152 : \
(fstype) == WLAN_FSTYPE_PSPOLL ? 20 : \
(fstype) == WLAN_FSTYPE_RTS ? 20 : \
(fstype) == WLAN_FSTYPE_CTS ? 14 : \
(fstype) == WLAN_FSTYPE_ACK ? 14 : \
(fstype) == WLAN_FSTYPE_CFEND ? 20 : \
(fstype) == WLAN_FSTYPE_CFENDCFACK ? 20 : 4)
#define WLAN_FCS_LEN 4
/* ftcl in HOST order */
inline static UINT16 p80211_headerlen(UINT16 fctl)
{
UINT16 hdrlen = 0;
switch ( WLAN_GET_FC_FTYPE(fctl) ) {
case WLAN_FTYPE_MGMT:
hdrlen = WLAN_HDR_A3_LEN;
break;
case WLAN_FTYPE_DATA:
hdrlen = WLAN_HDR_A3_LEN;
if ( WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl) ) {
hdrlen += WLAN_ADDR_LEN;
}
break;
case WLAN_FTYPE_CTL:
hdrlen = WLAN_CTL_FRAMELEN(WLAN_GET_FC_FSTYPE(fctl)) -
WLAN_FCS_LEN;
break;
default:
hdrlen = WLAN_HDR_A3_LEN;
}
return hdrlen;
}
#endif /* _P80211HDR_H */
/* p80211ioctl.h
*
* Declares constants and types for the p80211 ioctls
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* While this file is called 'ioctl' is purpose goes a little beyond
* that. This file defines the types and contants used to implement
* the p80211 request/confirm/indicate interfaces on Linux. The
* request/confirm interface is, in fact, normally implemented as an
* ioctl. The indicate interface on the other hand, is implemented
* using the Linux 'netlink' interface.
*
* The reason I say that request/confirm is 'normally' implemented
* via ioctl is that we're reserving the right to be able to send
* request commands via the netlink interface. This will be necessary
* if we ever need to send request messages when there aren't any
* wlan network devices present (i.e. sending a message that only p80211
* cares about.
* --------------------------------------------------------------------
*/
#ifndef _P80211IOCTL_H
#define _P80211IOCTL_H
/*================================================================*/
/* Constants */
/*----------------------------------------------------------------*/
/* p80211 ioctl "request" codes. See argument 2 of ioctl(2). */
#define P80211_IFTEST (SIOCDEVPRIVATE + 0)
#define P80211_IFREQ (SIOCDEVPRIVATE + 1)
/*----------------------------------------------------------------*/
/* Magic number, a quick test to see we're getting the desired struct */
#define P80211_IOCTL_MAGIC (0x4a2d464dUL)
/*----------------------------------------------------------------*/
/* Netlink protocol numbers for the indication interface */
#define P80211_NL_SOCK_IND NETLINK_USERSOCK
/*----------------------------------------------------------------*/
/* Netlink multicast bits for different types of messages */
#define P80211_NL_MCAST_GRP_MLME BIT0 /* Local station messages */
#define P80211_NL_MCAST_GRP_SNIFF BIT1 /* Sniffer messages */
#define P80211_NL_MCAST_GRP_DIST BIT2 /* Distribution system messages */
/*================================================================*/
/* Macros */
/*================================================================*/
/* Types */
/*----------------------------------------------------------------*/
/* A ptr to the following structure type is passed as the third */
/* argument to the ioctl system call when issuing a request to */
/* the p80211 module. */
typedef struct p80211ioctl_req
{
char name[WLAN_DEVNAMELEN_MAX];
caddr_t data;
UINT32 magic;
UINT16 len;
UINT32 result;
} __WLAN_ATTRIB_PACK__ p80211ioctl_req_t;
/*================================================================*/
/* Extern Declarations */
/*================================================================*/
/* Function Declarations */
#endif /* _P80211IOCTL_H */
/* p80211meta.h
*
* Macros, constants, types, and funcs for p80211 metadata
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file declares some of the constants and types used in various
* parts of the linux-wlan system.
*
* Notes:
* - Constant values are always in HOST byte order.
*
* All functions and statics declared here are implemented in p80211types.c
* --------------------------------------------------------------------
*/
#ifndef _P80211META_H
#define _P80211META_H
/*================================================================*/
/* System Includes */
/*================================================================*/
/* Project Includes */
#ifndef _WLAN_COMPAT_H
#include "wlan_compat.h"
#endif
/*================================================================*/
/* Constants */
/*----------------------------------------------------------------*/
/* */
/*================================================================*/
/* Macros */
/*----------------------------------------------------------------*/
/* The following macros are used to ensure consistent naming */
/* conventions for all the different metadata lists. */
#define MKREQMETANAME(name) p80211meta_ ## req ## _ ## name
#define MKINDMETANAME(name) p80211meta_ ## ind ## _ ## name
#define MKMIBMETANAME(name) p80211meta_ ## mib ## _ ## name
#define MKGRPMETANAME(name) p80211meta_ ## grp ## _ ## name
#define MKREQMETASIZE(name) p80211meta_ ## req ## _ ## name ## _ ## size
#define MKINDMETASIZE(name) p80211meta_ ## ind ## _ ## name ## _ ## size
#define MKMIBMETASIZE(name) p80211meta_ ## mib ## _ ## name ## _ ## size
#define MKGRPMETASIZE(name) p80211meta_ ## grp ## _ ## name ## _ ## size
#define GETMETASIZE(aptr) (**((UINT32**)(aptr)))
/*----------------------------------------------------------------*/
/* The following ifdef depends on the following defines: */
/* P80211_NOINCLUDESTRINGS - if defined, all metadata name fields */
/* are empty strings */
#ifdef P80211_NOINCLUDESTRINGS
#define MKITEMNAME(s) ("")
#else
#define MKITEMNAME(s) (s)
#endif
/*================================================================*/
/* Types */
/*----------------------------------------------------------------*/
/* The following structure types are used for the metadata */
/* representation of category list metadata, group list metadata, */
/* and data item metadata for both Mib and Messages. */
typedef struct p80211meta
{
char *name; /* data item name */
UINT32 did; /* partial did */
UINT32 flags; /* set of various flag bits */
UINT32 min; /* min value of a BOUNDEDINT */
UINT32 max; /* max value of a BOUNDEDINT */
UINT32 maxlen; /* maxlen of a OCTETSTR or DISPLAYSTR */
UINT32 minlen; /* minlen of a OCTETSTR or DISPLAYSTR */
p80211enum_t *enumptr; /* ptr to the enum type for ENUMINT */
p80211_totext_t totextptr; /* ptr to totext conversion function */
p80211_fromtext_t fromtextptr; /* ptr to totext conversion function */
p80211_valid_t validfunptr; /* ptr to totext conversion function */
} p80211meta_t;
typedef struct grplistitem
{
char *name;
p80211meta_t *itemlist;
} grplistitem_t;
typedef struct catlistitem
{
char *name;
grplistitem_t *grplist;
} catlistitem_t;
/*================================================================*/
/* Extern Declarations */
/*----------------------------------------------------------------*/
/* */
/*================================================================*/
/* Function Declarations */
/*----------------------------------------------------------------*/
/* */
UINT32 p80211_text2did(catlistitem_t *catlist, char *catname, char *grpname, char *itemname);
UINT32 p80211_text2catdid(catlistitem_t *list, char *name );
UINT32 p80211_text2grpdid(grplistitem_t *list, char *name );
UINT32 p80211_text2itemdid(p80211meta_t *list, char *name );
UINT32 p80211_isvalid_did( catlistitem_t *catlist, UINT32 did );
UINT32 p80211_isvalid_catdid( catlistitem_t *catlist, UINT32 did );
UINT32 p80211_isvalid_grpdid( catlistitem_t *catlist, UINT32 did );
UINT32 p80211_isvalid_itemdid( catlistitem_t *catlist, UINT32 did );
catlistitem_t *p80211_did2cat( catlistitem_t *catlist, UINT32 did );
grplistitem_t *p80211_did2grp( catlistitem_t *catlist, UINT32 did );
p80211meta_t *p80211_did2item( catlistitem_t *catlist, UINT32 did );
UINT32 p80211item_maxdatalen( struct catlistitem *metalist, UINT32 did );
UINT32 p80211_metaname2did(struct catlistitem *metalist, char *itemname);
UINT32 p80211item_getoffset( struct catlistitem *metalist, UINT32 did );
int p80211item_gettype(p80211meta_t *meta);
#endif /* _P80211META_H */
/* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY.
* --------------------------------------------------------------------
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*/
#ifndef _P80211MKMETADEF_H
#define _P80211MKMETADEF_H
#define DIDmsg_cat_dot11req \
P80211DID_MKSECTION(1)
#define DIDmsg_dot11req_mibget \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(1))
#define DIDmsg_dot11req_mibget_mibattribute \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_mibget_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_mibset \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2))
#define DIDmsg_dot11req_mibset_mibattribute \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_mibset_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_powermgmt \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3))
#define DIDmsg_dot11req_powermgmt_powermgmtmode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_powermgmt_wakeup \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_powermgmt_receivedtims \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_powermgmt_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_dot11req_scan \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4))
#define DIDmsg_dot11req_scan_bsstype \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_scan_bssid \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_scan_ssid \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_scan_scantype \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_dot11req_scan_probedelay \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_dot11req_scan_channellist \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_dot11req_scan_minchanneltime \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_dot11req_scan_maxchanneltime \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_dot11req_scan_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(9) | 0x00000000)
#define DIDmsg_dot11req_scan_numbss \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(10) | 0x00000000)
#define DIDmsg_dot11req_scan_append \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(11) | 0x00000000)
#define DIDmsg_dot11req_scan_results \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5))
#define DIDmsg_dot11req_scan_results_bssindex \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_scan_results_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_scan_results_signal \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_scan_results_noise \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_dot11req_scan_results_bssid \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_dot11req_scan_results_ssid \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_dot11req_scan_results_bsstype \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_dot11req_scan_results_beaconperiod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_dot11req_scan_results_dtimperiod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(9) | 0x00000000)
#define DIDmsg_dot11req_scan_results_timestamp \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(10) | 0x00000000)
#define DIDmsg_dot11req_scan_results_localtime \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(11) | 0x00000000)
#define DIDmsg_dot11req_scan_results_fhdwelltime \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(12) | 0x00000000)
#define DIDmsg_dot11req_scan_results_fhhopset \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(13) | 0x00000000)
#define DIDmsg_dot11req_scan_results_fhhoppattern \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(14) | 0x00000000)
#define DIDmsg_dot11req_scan_results_fhhopindex \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(15) | 0x00000000)
#define DIDmsg_dot11req_scan_results_dschannel \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(16) | 0x00000000)
#define DIDmsg_dot11req_scan_results_cfpcount \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(17) | 0x00000000)
#define DIDmsg_dot11req_scan_results_cfpperiod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(18) | 0x00000000)
#define DIDmsg_dot11req_scan_results_cfpmaxduration \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(19) | 0x00000000)
#define DIDmsg_dot11req_scan_results_cfpdurremaining \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(20) | 0x00000000)
#define DIDmsg_dot11req_scan_results_ibssatimwindow \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(21) | 0x00000000)
#define DIDmsg_dot11req_scan_results_cfpollable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(22) | 0x00000000)
#define DIDmsg_dot11req_scan_results_cfpollreq \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(23) | 0x00000000)
#define DIDmsg_dot11req_scan_results_privacy \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(24) | 0x00000000)
#define DIDmsg_dot11req_scan_results_basicrate1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(25) | 0x00000000)
#define DIDmsg_dot11req_scan_results_basicrate2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(26) | 0x00000000)
#define DIDmsg_dot11req_scan_results_basicrate3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(27) | 0x00000000)
#define DIDmsg_dot11req_scan_results_basicrate4 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(28) | 0x00000000)
#define DIDmsg_dot11req_scan_results_basicrate5 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(29) | 0x00000000)
#define DIDmsg_dot11req_scan_results_basicrate6 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(30) | 0x00000000)
#define DIDmsg_dot11req_scan_results_basicrate7 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(31) | 0x00000000)
#define DIDmsg_dot11req_scan_results_basicrate8 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(32) | 0x00000000)
#define DIDmsg_dot11req_scan_results_supprate1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(33) | 0x00000000)
#define DIDmsg_dot11req_scan_results_supprate2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(34) | 0x00000000)
#define DIDmsg_dot11req_scan_results_supprate3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(35) | 0x00000000)
#define DIDmsg_dot11req_scan_results_supprate4 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(36) | 0x00000000)
#define DIDmsg_dot11req_scan_results_supprate5 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(37) | 0x00000000)
#define DIDmsg_dot11req_scan_results_supprate6 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(38) | 0x00000000)
#define DIDmsg_dot11req_scan_results_supprate7 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(39) | 0x00000000)
#define DIDmsg_dot11req_scan_results_supprate8 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(40) | 0x00000000)
#define DIDmsg_dot11req_join \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6))
#define DIDmsg_dot11req_join_bssid \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_join_joinfailuretimeout \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_join_basicrate1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_join_basicrate2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_dot11req_join_basicrate3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_dot11req_join_basicrate4 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_dot11req_join_basicrate5 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_dot11req_join_basicrate6 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_dot11req_join_basicrate7 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(9) | 0x00000000)
#define DIDmsg_dot11req_join_basicrate8 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(10) | 0x00000000)
#define DIDmsg_dot11req_join_operationalrate1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(11) | 0x00000000)
#define DIDmsg_dot11req_join_operationalrate2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(12) | 0x00000000)
#define DIDmsg_dot11req_join_operationalrate3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(13) | 0x00000000)
#define DIDmsg_dot11req_join_operationalrate4 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(14) | 0x00000000)
#define DIDmsg_dot11req_join_operationalrate5 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(15) | 0x00000000)
#define DIDmsg_dot11req_join_operationalrate6 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(16) | 0x00000000)
#define DIDmsg_dot11req_join_operationalrate7 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(17) | 0x00000000)
#define DIDmsg_dot11req_join_operationalrate8 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(18) | 0x00000000)
#define DIDmsg_dot11req_join_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(19) | 0x00000000)
#define DIDmsg_dot11req_authenticate \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(7))
#define DIDmsg_dot11req_authenticate_peerstaaddress \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_authenticate_authenticationtype \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_authenticate_authenticationfailuretimeout \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_authenticate_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_dot11req_deauthenticate \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(8))
#define DIDmsg_dot11req_deauthenticate_peerstaaddress \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_deauthenticate_reasoncode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_deauthenticate_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_associate \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(9))
#define DIDmsg_dot11req_associate_peerstaaddress \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_associate_associatefailuretimeout \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_associate_cfpollable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_associate_cfpollreq \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_dot11req_associate_privacy \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_dot11req_associate_listeninterval \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_dot11req_associate_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_dot11req_reassociate \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(10))
#define DIDmsg_dot11req_reassociate_newapaddress \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_reassociate_reassociatefailuretimeout \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_reassociate_cfpollable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_reassociate_cfpollreq \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_dot11req_reassociate_privacy \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_dot11req_reassociate_listeninterval \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_dot11req_reassociate_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_dot11req_disassociate \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(11))
#define DIDmsg_dot11req_disassociate_peerstaaddress \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(11) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_disassociate_reasoncode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(11) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_disassociate_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(11) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_reset \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(12))
#define DIDmsg_dot11req_reset_setdefaultmib \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(12) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_reset_macaddress \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(12) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_reset_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(12) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_start \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13))
#define DIDmsg_dot11req_start_ssid \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11req_start_bsstype \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_start_beaconperiod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11req_start_dtimperiod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_dot11req_start_cfpperiod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_dot11req_start_cfpmaxduration \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_dot11req_start_fhdwelltime \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_dot11req_start_fhhopset \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_dot11req_start_fhhoppattern \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(9) | 0x00000000)
#define DIDmsg_dot11req_start_dschannel \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(10) | 0x00000000)
#define DIDmsg_dot11req_start_ibssatimwindow \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(11) | 0x00000000)
#define DIDmsg_dot11req_start_probedelay \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(12) | 0x00000000)
#define DIDmsg_dot11req_start_cfpollable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(13) | 0x00000000)
#define DIDmsg_dot11req_start_cfpollreq \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(14) | 0x00000000)
#define DIDmsg_dot11req_start_basicrate1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(15) | 0x00000000)
#define DIDmsg_dot11req_start_basicrate2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(16) | 0x00000000)
#define DIDmsg_dot11req_start_basicrate3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(17) | 0x00000000)
#define DIDmsg_dot11req_start_basicrate4 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(18) | 0x00000000)
#define DIDmsg_dot11req_start_basicrate5 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(19) | 0x00000000)
#define DIDmsg_dot11req_start_basicrate6 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(20) | 0x00000000)
#define DIDmsg_dot11req_start_basicrate7 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(21) | 0x00000000)
#define DIDmsg_dot11req_start_basicrate8 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(22) | 0x00000000)
#define DIDmsg_dot11req_start_operationalrate1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(23) | 0x00000000)
#define DIDmsg_dot11req_start_operationalrate2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(24) | 0x00000000)
#define DIDmsg_dot11req_start_operationalrate3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(25) | 0x00000000)
#define DIDmsg_dot11req_start_operationalrate4 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(26) | 0x00000000)
#define DIDmsg_dot11req_start_operationalrate5 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(27) | 0x00000000)
#define DIDmsg_dot11req_start_operationalrate6 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(28) | 0x00000000)
#define DIDmsg_dot11req_start_operationalrate7 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(29) | 0x00000000)
#define DIDmsg_dot11req_start_operationalrate8 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(30) | 0x00000000)
#define DIDmsg_dot11req_start_resultcode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(31) | 0x00000000)
#define DIDmsg_cat_dot11ind \
P80211DID_MKSECTION(2)
#define DIDmsg_dot11ind_authenticate \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1))
#define DIDmsg_dot11ind_authenticate_peerstaaddress \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11ind_authenticate_authenticationtype \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11ind_deauthenticate \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2))
#define DIDmsg_dot11ind_deauthenticate_peerstaaddress \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11ind_deauthenticate_reasoncode \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11ind_associate \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3))
#define DIDmsg_dot11ind_associate_peerstaaddress \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11ind_associate_aid \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11ind_reassociate \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(4))
#define DIDmsg_dot11ind_reassociate_peerstaaddress \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11ind_reassociate_aid \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11ind_reassociate_oldapaddress \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_dot11ind_disassociate \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(5))
#define DIDmsg_dot11ind_disassociate_peerstaaddress \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_dot11ind_disassociate_reasoncode \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_cat_lnxreq \
P80211DID_MKSECTION(3)
#define DIDmsg_lnxreq_ifstate \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1))
#define DIDmsg_lnxreq_ifstate_ifstate \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_lnxreq_ifstate_resultcode \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2))
#define DIDmsg_lnxreq_wlansniff_enable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff_channel \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff_prismheader \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff_wlanheader \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff_keepwepflags \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff_stripfcs \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff_packet_trunc \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff_resultcode \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_lnxreq_hostwep \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3))
#define DIDmsg_lnxreq_hostwep_resultcode \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_lnxreq_hostwep_decrypt \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_lnxreq_hostwep_encrypt \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_lnxreq_commsquality \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4))
#define DIDmsg_lnxreq_commsquality_resultcode \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_lnxreq_commsquality_dbm \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_lnxreq_commsquality_link \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_lnxreq_commsquality_level \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_lnxreq_commsquality_noise \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_lnxreq_autojoin \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5))
#define DIDmsg_lnxreq_autojoin_ssid \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_lnxreq_autojoin_authtype \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_lnxreq_autojoin_resultcode \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_cat_lnxind \
P80211DID_MKSECTION(4)
#define DIDmsg_lnxind_wlansniffrm \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1))
#define DIDmsg_lnxind_wlansniffrm_hosttime \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_mactime \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_channel \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_rssi \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_sq \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_signal \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_noise \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_rate \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_istx \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(9) | 0x00000000)
#define DIDmsg_lnxind_wlansniffrm_frmlen \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(10) | 0x00000000)
#define DIDmsg_lnxind_roam \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(2))
#define DIDmsg_lnxind_roam_reason \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_cat_p2req \
P80211DID_MKSECTION(5)
#define DIDmsg_p2req_join \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1))
#define DIDmsg_p2req_join_bssid \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_join_basicrate1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_join_basicrate2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_join_basicrate3 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_join_basicrate4 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_p2req_join_basicrate5 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_p2req_join_basicrate6 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_p2req_join_basicrate7 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_p2req_join_basicrate8 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(9) | 0x00000000)
#define DIDmsg_p2req_join_operationalrate1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(10) | 0x00000000)
#define DIDmsg_p2req_join_operationalrate2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(11) | 0x00000000)
#define DIDmsg_p2req_join_operationalrate3 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(12) | 0x00000000)
#define DIDmsg_p2req_join_operationalrate4 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(13) | 0x00000000)
#define DIDmsg_p2req_join_operationalrate5 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(14) | 0x00000000)
#define DIDmsg_p2req_join_operationalrate6 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(15) | 0x00000000)
#define DIDmsg_p2req_join_operationalrate7 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(16) | 0x00000000)
#define DIDmsg_p2req_join_operationalrate8 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(17) | 0x00000000)
#define DIDmsg_p2req_join_ssid \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(18) | 0x00000000)
#define DIDmsg_p2req_join_channel \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(19) | 0x00000000)
#define DIDmsg_p2req_join_authtype \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(20) | 0x00000000)
#define DIDmsg_p2req_join_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(21) | 0x00000000)
#define DIDmsg_p2req_readpda \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2))
#define DIDmsg_p2req_readpda_pda \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_readpda_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_readcis \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3))
#define DIDmsg_p2req_readcis_cis \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_readcis_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_auxport_state \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(4))
#define DIDmsg_p2req_auxport_state_enable \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_auxport_state_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_auxport_read \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5))
#define DIDmsg_p2req_auxport_read_addr \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_auxport_read_len \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_auxport_read_data \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_auxport_read_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_auxport_write \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6))
#define DIDmsg_p2req_auxport_write_addr \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_auxport_write_len \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_auxport_write_data \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_auxport_write_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_low_level \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7))
#define DIDmsg_p2req_low_level_command \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_low_level_param0 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_low_level_param1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_low_level_param2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_low_level_resp0 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_p2req_low_level_resp1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_p2req_low_level_resp2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_p2req_low_level_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_p2req_test_command \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(8))
#define DIDmsg_p2req_test_command_testcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_test_command_testparam \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_test_command_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_test_command_status \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_test_command_resp0 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_p2req_test_command_resp1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_p2req_test_command_resp2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(7) | 0x00000000)
#define DIDmsg_p2req_mmi_read \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(9))
#define DIDmsg_p2req_mmi_read_addr \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_mmi_read_value \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_mmi_read_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_mmi_write \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(10))
#define DIDmsg_p2req_mmi_write_addr \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_mmi_write_data \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_mmi_write_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_ramdl_state \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(11))
#define DIDmsg_p2req_ramdl_state_enable \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(11) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_ramdl_state_exeaddr \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(11) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_ramdl_state_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(11) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_ramdl_write \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(12))
#define DIDmsg_p2req_ramdl_write_addr \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(12) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_ramdl_write_len \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(12) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_ramdl_write_data \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(12) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_ramdl_write_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(12) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_flashdl_state \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(13))
#define DIDmsg_p2req_flashdl_state_enable \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_flashdl_state_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(13) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_flashdl_write \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(14))
#define DIDmsg_p2req_flashdl_write_addr \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(14) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_flashdl_write_len \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(14) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_flashdl_write_data \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(14) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_flashdl_write_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(14) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_mm_state \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(15))
#define DIDmsg_p2req_mm_state_enable \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(15) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_mm_state_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(15) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_dump_state \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(16))
#define DIDmsg_p2req_dump_state_level \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(16) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_dump_state_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(16) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_channel_info \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(17))
#define DIDmsg_p2req_channel_info_channellist \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(17) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_channel_info_channeldwelltime \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(17) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_channel_info_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(17) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_channel_info_numchinfo \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(17) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_channel_info_results \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(18))
#define DIDmsg_p2req_channel_info_results_channel \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(18) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmsg_p2req_channel_info_results_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(18) | \
P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_channel_info_results_avgnoiselevel \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(18) | \
P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_channel_info_results_peaknoiselevel \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(18) | \
P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_channel_info_results_bssactive \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(18) | \
P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_p2req_channel_info_results_pcfactive \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(18) | \
P80211DID_MKITEM(6) | 0x00000000)
#define DIDmsg_p2req_enable \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(19))
#define DIDmsg_p2req_enable_resultcode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(19) | \
P80211DID_MKITEM(1) | 0x00000000)
#define DIDmib_cat_dot11smt \
P80211DID_MKSECTION(1)
#define DIDmib_dot11smt_p80211Table \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(1))
#define DIDmib_dot11smt_p80211Table_p80211_ifstate \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2))
#define DIDmib_dot11smt_dot11StationConfigTable_dot11StationID \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(4) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(5) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(6) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(7) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(8) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(9) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(10) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(11) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(12) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(13) | 0x18000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(14) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateReason \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(15) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateStation \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(16) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateReason \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(17) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateStation \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(18) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStatus \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(19) | 0x10000000)
#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStation \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(20) | 0x10000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3))
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(1) | 0x14000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(2) | 0x1c000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(3) | 0x14000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(4) | 0x1c000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(5) | 0x14000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(6) | 0x1c000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(7) | 0x14000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(8) | 0x1c000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(9) | 0x14000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(10) | 0x1c000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(11) | 0x14000000)
#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(12) | 0x1c000000)
#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4))
#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(1) | 0x0c000000)
#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(2) | 0x0c000000)
#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(3) | 0x0c000000)
#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3 \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(4) | 0x0c000000)
#define DIDmib_dot11smt_dot11WEPKeyMappingsTable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5))
#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(1) | 0x1c000000)
#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(2) | 0x1c000000)
#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(3) | 0x1c000000)
#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(4) | 0x1c000000)
#define DIDmib_dot11smt_dot11PrivacyTable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6))
#define DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(3) | 0x18000000)
#define DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(4) | 0x18000000)
#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_cat_dot11mac \
P80211DID_MKSECTION(2)
#define DIDmib_dot11mac_dot11OperationTable \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1))
#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(4) | 0x10000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(5) | 0x18000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(7) | 0x10000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(8) | 0x10000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11ProductID \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(9) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2))
#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(2) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11FailedCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11RetryCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(4) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(7) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(8) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(9) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(10) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(11) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(12) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(13) | 0x10000000)
#define DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(14) | 0x10000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3))
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(1) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(2) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(3) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(4) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(5) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(6) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(7) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(8) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(9) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(10) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(11) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(12) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(13) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(14) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(15) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(16) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(17) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(18) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(19) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(20) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(21) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(22) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(23) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(24) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(25) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(26) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(27) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(28) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(29) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(30) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(31) | 0x1c000000)
#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32 \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(32) | 0x1c000000)
#define DIDmib_cat_dot11phy \
P80211DID_MKSECTION(3)
#define DIDmib_dot11phy_dot11PhyOperationTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1))
#define DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyOperationTable_dot11CurrentRegDomain \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(4) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyAntennaTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2))
#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(2) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(3) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3))
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1 \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(2) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2 \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3 \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(4) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4 \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5 \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6 \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(7) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7 \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(8) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8 \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(9) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(10) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyFHSSTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4))
#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(4) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(5) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(6) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(7) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyDSSSTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5))
#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(2) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(4) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_dot11phy_dot11PhyIRTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(6))
#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(3) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(4) | 0x18000000)
#define DIDmib_dot11phy_dot11RegDomainsSupportedTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(7))
#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(1) | 0x1c000000)
#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(2) | 0x14000000)
#define DIDmib_dot11phy_dot11AntennasListTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(8))
#define DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(1) | 0x1c000000)
#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(2) | 0x1c000000)
#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(3) | 0x1c000000)
#define DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(8) | \
P80211DID_MKITEM(4) | 0x1c000000)
#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(9))
#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(1) | 0x1c000000)
#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(9) | \
P80211DID_MKITEM(2) | 0x14000000)
#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(10))
#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(1) | 0x1c000000)
#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(10) | \
P80211DID_MKITEM(2) | 0x14000000)
#define DIDmib_cat_lnx \
P80211DID_MKSECTION(4)
#define DIDmib_lnx_lnxConfigTable \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1))
#define DIDmib_lnx_lnxConfigTable_lnxRSNAIE \
(P80211DID_MKSECTION(4) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_cat_p2 \
P80211DID_MKSECTION(5)
#define DIDmib_p2_p2Table \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1))
#define DIDmib_p2_p2Table_p2MMTx \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_p2_p2Table_p2EarlyBeacon \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_p2_p2Table_p2ReceivedFrameStatistics \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_p2_p2Table_p2CommunicationTallies \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(4) | 0x10000000)
#define DIDmib_p2_p2Table_p2Authenticated \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_p2_p2Table_p2Associated \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_p2_p2Table_p2PowerSaveUserCount \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(7) | 0x10000000)
#define DIDmib_p2_p2Table_p2Comment \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(8) | 0x18000000)
#define DIDmib_p2_p2Table_p2AccessMode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(9) | 0x18000000)
#define DIDmib_p2_p2Table_p2AccessAllow \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(10) | 0x18000000)
#define DIDmib_p2_p2Table_p2AccessDeny \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(11) | 0x18000000)
#define DIDmib_p2_p2Table_p2ChannelInfoResults \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(12) | 0x10000000)
#define DIDmib_p2_p2Static \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2))
#define DIDmib_p2_p2Static_p2CnfPortType \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfOwnMACAddress \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfDesiredSSID \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(3) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfOwnChannel \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(4) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfOwnSSID \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(5) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfOwnATIMWindow \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(6) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfSystemScale \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(7) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfMaxDataLength \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(8) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWDSAddress \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(9) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfPMEnabled \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(10) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfPMEPS \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(11) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfMulticastReceive \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(12) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfMaxSleepDuration \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(13) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfPMHoldoverDuration \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(14) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfOwnName \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(15) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(16) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWDSAddress1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(17) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWDSAddress2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(18) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWDSAddress3 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(19) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWDSAddress4 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(20) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWDSAddress5 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(21) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWDSAddress6 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(22) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfMulticastPMBuffering \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(23) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(24) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey0 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(25) | 0x08000000)
#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(26) | 0x08000000)
#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(27) | 0x08000000)
#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey3 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(28) | 0x08000000)
#define DIDmib_p2_p2Static_p2CnfWEPFlags \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(29) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfAuthentication \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(30) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfMaxAssociatedStations \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(31) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfTxControl \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(32) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfRoamingMode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(33) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfHostAuthentication \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(34) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfRcvCrcError \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(35) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfAltRetryCount \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(36) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfBeaconInterval \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(37) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(38) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfCFPPeriod \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(39) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfCFPMaxDuration \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(40) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfCFPFlags \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(41) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfSTAPCFInfo \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(42) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfPriorityQUsage \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(43) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfTIMCtrl \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(44) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfThirty2Tally \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(45) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfEnhSecurity \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(46) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfShortPreamble \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(47) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfExcludeLongPreamble \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(48) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfAuthenticationRspTO \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(49) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfBasicRates \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(50) | 0x18000000)
#define DIDmib_p2_p2Static_p2CnfSupportedRates \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2) | \
P80211DID_MKITEM(51) | 0x18000000)
#define DIDmib_p2_p2Dynamic \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3))
#define DIDmib_p2_p2Dynamic_p2CreateIBSS \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(2) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2RTSThreshold \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(3) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2TxRateControl \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(4) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2PromiscuousMode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(5) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold0 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(6) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(7) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(8) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold3 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(9) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold4 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(10) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold5 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(11) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold6 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(12) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2RTSThreshold0 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(13) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2RTSThreshold1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(14) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2RTSThreshold2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(15) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2RTSThreshold3 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(16) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2RTSThreshold4 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(17) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2RTSThreshold5 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(18) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2RTSThreshold6 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(19) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2TxRateControl0 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(20) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2TxRateControl1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(21) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2TxRateControl2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(22) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2TxRateControl3 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(23) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2TxRateControl4 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(24) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2TxRateControl5 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(25) | 0x18000000)
#define DIDmib_p2_p2Dynamic_p2TxRateControl6 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(3) | \
P80211DID_MKITEM(26) | 0x18000000)
#define DIDmib_p2_p2Behavior \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(4))
#define DIDmib_p2_p2Behavior_p2TickTime \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(4) | \
P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_p2_p2NIC \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5))
#define DIDmib_p2_p2NIC_p2MaxLoadTime \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_p2_p2NIC_p2DLBufferPage \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(2) | 0x10000000)
#define DIDmib_p2_p2NIC_p2DLBufferOffset \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_p2_p2NIC_p2DLBufferLength \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(4) | 0x10000000)
#define DIDmib_p2_p2NIC_p2PRIIdentity \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_p2_p2NIC_p2PRISupRange \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_p2_p2NIC_p2CFIActRanges \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(7) | 0x10000000)
#define DIDmib_p2_p2NIC_p2NICSerialNumber \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(8) | 0x10000000)
#define DIDmib_p2_p2NIC_p2NICIdentity \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(9) | 0x10000000)
#define DIDmib_p2_p2NIC_p2MFISupRange \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(10) | 0x10000000)
#define DIDmib_p2_p2NIC_p2CFISupRange \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(11) | 0x10000000)
#define DIDmib_p2_p2NIC_p2ChannelList \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(12) | 0x10000000)
#define DIDmib_p2_p2NIC_p2RegulatoryDomains \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(13) | 0x10000000)
#define DIDmib_p2_p2NIC_p2TempType \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(14) | 0x10000000)
#define DIDmib_p2_p2NIC_p2STAIdentity \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(15) | 0x10000000)
#define DIDmib_p2_p2NIC_p2STASupRange \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(16) | 0x10000000)
#define DIDmib_p2_p2NIC_p2MFIActRanges \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(17) | 0x10000000)
#define DIDmib_p2_p2NIC_p2STACFIActRanges \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(18) | 0x10000000)
#define DIDmib_p2_p2NIC_p2BuildSequence \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(19) | 0x10000000)
#define DIDmib_p2_p2NIC_p2PrimaryFWID \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(20) | 0x10000000)
#define DIDmib_p2_p2NIC_p2SecondaryFWID \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(21) | 0x10000000)
#define DIDmib_p2_p2NIC_p2TertiaryFWID \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(5) | \
P80211DID_MKITEM(22) | 0x10000000)
#define DIDmib_p2_p2MAC \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6))
#define DIDmib_p2_p2MAC_p2PortStatus \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentSSID \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(2) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentBSSID \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CommsQuality \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(4) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CommsQualityCQ \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CommsQualityASL \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CommsQualityANL \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(7) | 0x10000000)
#define DIDmib_p2_p2MAC_p2dbmCommsQuality \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(8) | 0x10000000)
#define DIDmib_p2_p2MAC_p2dbmCommsQualityCQ \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(9) | 0x10000000)
#define DIDmib_p2_p2MAC_p2dbmCommsQualityASL \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(10) | 0x10000000)
#define DIDmib_p2_p2MAC_p2dbmCommsQualityANL \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(11) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentTxRate \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(12) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentBeaconInterval \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(13) | 0x10000000)
#define DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(14) | 0x10000000)
#define DIDmib_p2_p2MAC_p2APCurrentScaleThresholds \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(15) | 0x10000000)
#define DIDmib_p2_p2MAC_p2ProtocolRspTime \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(16) | 0x10000000)
#define DIDmib_p2_p2MAC_p2ShortRetryLimit \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(17) | 0x10000000)
#define DIDmib_p2_p2MAC_p2LongRetryLimit \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(18) | 0x10000000)
#define DIDmib_p2_p2MAC_p2MaxTransmitLifetime \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(19) | 0x10000000)
#define DIDmib_p2_p2MAC_p2MaxReceiveLifetime \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(20) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CFPollable \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(21) | 0x10000000)
#define DIDmib_p2_p2MAC_p2AuthenticationAlgorithms \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(22) | 0x10000000)
#define DIDmib_p2_p2MAC_p2PrivacyOptionImplemented \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(23) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentTxRate1 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(24) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentTxRate2 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(25) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentTxRate3 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(26) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentTxRate4 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(27) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentTxRate5 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(28) | 0x10000000)
#define DIDmib_p2_p2MAC_p2CurrentTxRate6 \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(29) | 0x10000000)
#define DIDmib_p2_p2MAC_p2OwnMACAddress \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(30) | 0x10000000)
#define DIDmib_p2_p2Modem \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7))
#define DIDmib_p2_p2Modem_p2PHYType \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(1) | 0x10000000)
#define DIDmib_p2_p2Modem_p2CurrentChannel \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(2) | 0x10000000)
#define DIDmib_p2_p2Modem_p2CurrentPowerState \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(3) | 0x10000000)
#define DIDmib_p2_p2Modem_p2CCAMode \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(4) | 0x10000000)
#define DIDmib_p2_p2Modem_p2SupportedDataRates \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(5) | 0x10000000)
#define DIDmib_p2_p2Modem_p2TxPowerMax \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(7) | \
P80211DID_MKITEM(6) | 0x18000000)
#endif
/* p80211metamib.h
*
* Macros, const, types, and funcs for p80211 mib metadata
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file declares some of the constants and types used in various
* parts of the linux-wlan system.
*
* Notes:
* - Constant values are always in HOST byte order.
*
* All functions and statics declared here are implemented in p80211types.c
* --------------------------------------------------------------------
*/
#ifndef _P80211METAMIB_H
#define _P80211METAMIB_H
/*================================================================*/
/* System Includes */
/*================================================================*/
/* Project Includes */
#ifndef _WLAN_COMPAT_H
#include "wlan_compat.h"
#endif
/*================================================================*/
/* Constants */
/*----------------------------------------------------------------*/
/* */
/*================================================================*/
/* Macros */
/*----------------------------------------------------------------*/
/* */
/*================================================================*/
/* Types */
/*----------------------------------------------------------------*/
/* */
/*================================================================*/
/* Extern Declarations */
/*----------------------------------------------------------------*/
/* The following is the external declaration for the mib */
/* category metadata list */
extern catlistitem_t mib_catlist[];
extern UINT32 mib_catlist_size;
/*================================================================*/
/* Function Declarations */
/*----------------------------------------------------------------*/
/* */
#endif /* _P80211METAMIB_H */
/* p80211metamsg.h
*
* Macros, const, types, and funcs for p80211 msg metadata
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file declares some of the constants and types used in various
* parts of the linux-wlan system.
*
* Notes:
* - Constant values are always in HOST byte order.
*
* All functions and statics declared here are implemented in p80211types.c
* --------------------------------------------------------------------
*/
#ifndef _P80211METAMSG_H
#define _P80211METAMSG_H
/*================================================================*/
/* System Includes */
/*================================================================*/
/* Project Includes */
#ifndef _WLAN_COMPAT_H
#include "wlan_compat.h"
#endif
/*================================================================*/
/* Constants */
/*----------------------------------------------------------------*/
/* */
/*================================================================*/
/* Macros */
/*----------------------------------------------------------------*/
/* */
/*================================================================*/
/* Types */
/*----------------------------------------------------------------*/
/* */
/*================================================================*/
/* Extern Declarations */
/*----------------------------------------------------------------*/
/* The following is the external declaration for the message */
/* category metadata list */
extern catlistitem_t msg_catlist[];
extern UINT32 msg_catlist_size;
/*================================================================*/
/* Function Declarations */
/*----------------------------------------------------------------*/
/* */
#endif /* _P80211METAMSG_H */
/* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY.
* --------------------------------------------------------------------
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*/
#ifndef _P80211MKMETASTRUCT_H
#define _P80211MKMETASTRUCT_H
typedef struct p80211msg_dot11req_mibget
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_unk392_t mibattribute ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibget_t;
typedef struct p80211msg_dot11req_mibset
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_unk392_t mibattribute ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibset_t;
typedef struct p80211msg_dot11req_powermgmt
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t powermgmtmode ;
p80211item_uint32_t wakeup ;
p80211item_uint32_t receivedtims ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_powermgmt_t;
typedef struct p80211msg_dot11req_scan
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t bsstype ;
p80211item_pstr6_t bssid ;
UINT8 pad_0C[1] ;
p80211item_pstr32_t ssid ;
UINT8 pad_1D[3] ;
p80211item_uint32_t scantype ;
p80211item_uint32_t probedelay ;
p80211item_pstr14_t channellist ;
UINT8 pad_2C[1] ;
p80211item_uint32_t minchanneltime ;
p80211item_uint32_t maxchanneltime ;
p80211item_uint32_t resultcode ;
p80211item_uint32_t numbss ;
p80211item_uint32_t append ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_t;
typedef struct p80211msg_dot11req_scan_results
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t bssindex ;
p80211item_uint32_t resultcode ;
p80211item_uint32_t signal ;
p80211item_uint32_t noise ;
p80211item_pstr6_t bssid ;
UINT8 pad_3C[1] ;
p80211item_pstr32_t ssid ;
UINT8 pad_4D[3] ;
p80211item_uint32_t bsstype ;
p80211item_uint32_t beaconperiod ;
p80211item_uint32_t dtimperiod ;
p80211item_uint32_t timestamp ;
p80211item_uint32_t localtime ;
p80211item_uint32_t fhdwelltime ;
p80211item_uint32_t fhhopset ;
p80211item_uint32_t fhhoppattern ;
p80211item_uint32_t fhhopindex ;
p80211item_uint32_t dschannel ;
p80211item_uint32_t cfpcount ;
p80211item_uint32_t cfpperiod ;
p80211item_uint32_t cfpmaxduration ;
p80211item_uint32_t cfpdurremaining ;
p80211item_uint32_t ibssatimwindow ;
p80211item_uint32_t cfpollable ;
p80211item_uint32_t cfpollreq ;
p80211item_uint32_t privacy ;
p80211item_uint32_t basicrate1 ;
p80211item_uint32_t basicrate2 ;
p80211item_uint32_t basicrate3 ;
p80211item_uint32_t basicrate4 ;
p80211item_uint32_t basicrate5 ;
p80211item_uint32_t basicrate6 ;
p80211item_uint32_t basicrate7 ;
p80211item_uint32_t basicrate8 ;
p80211item_uint32_t supprate1 ;
p80211item_uint32_t supprate2 ;
p80211item_uint32_t supprate3 ;
p80211item_uint32_t supprate4 ;
p80211item_uint32_t supprate5 ;
p80211item_uint32_t supprate6 ;
p80211item_uint32_t supprate7 ;
p80211item_uint32_t supprate8 ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_results_t;
typedef struct p80211msg_dot11req_join
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t bssid ;
UINT8 pad_5C[1] ;
p80211item_uint32_t joinfailuretimeout ;
p80211item_uint32_t basicrate1 ;
p80211item_uint32_t basicrate2 ;
p80211item_uint32_t basicrate3 ;
p80211item_uint32_t basicrate4 ;
p80211item_uint32_t basicrate5 ;
p80211item_uint32_t basicrate6 ;
p80211item_uint32_t basicrate7 ;
p80211item_uint32_t basicrate8 ;
p80211item_uint32_t operationalrate1 ;
p80211item_uint32_t operationalrate2 ;
p80211item_uint32_t operationalrate3 ;
p80211item_uint32_t operationalrate4 ;
p80211item_uint32_t operationalrate5 ;
p80211item_uint32_t operationalrate6 ;
p80211item_uint32_t operationalrate7 ;
p80211item_uint32_t operationalrate8 ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_join_t;
typedef struct p80211msg_dot11req_authenticate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_6C[1] ;
p80211item_uint32_t authenticationtype ;
p80211item_uint32_t authenticationfailuretimeout ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_authenticate_t;
typedef struct p80211msg_dot11req_deauthenticate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_7C[1] ;
p80211item_uint32_t reasoncode ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_deauthenticate_t;
typedef struct p80211msg_dot11req_associate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_8C[1] ;
p80211item_uint32_t associatefailuretimeout ;
p80211item_uint32_t cfpollable ;
p80211item_uint32_t cfpollreq ;
p80211item_uint32_t privacy ;
p80211item_uint32_t listeninterval ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_associate_t;
typedef struct p80211msg_dot11req_reassociate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t newapaddress ;
UINT8 pad_9C[1] ;
p80211item_uint32_t reassociatefailuretimeout ;
p80211item_uint32_t cfpollable ;
p80211item_uint32_t cfpollreq ;
p80211item_uint32_t privacy ;
p80211item_uint32_t listeninterval ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reassociate_t;
typedef struct p80211msg_dot11req_disassociate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_10C[1] ;
p80211item_uint32_t reasoncode ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_disassociate_t;
typedef struct p80211msg_dot11req_reset
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t setdefaultmib ;
p80211item_pstr6_t macaddress ;
UINT8 pad_11C[1] ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reset_t;
typedef struct p80211msg_dot11req_start
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr32_t ssid ;
UINT8 pad_12D[3] ;
p80211item_uint32_t bsstype ;
p80211item_uint32_t beaconperiod ;
p80211item_uint32_t dtimperiod ;
p80211item_uint32_t cfpperiod ;
p80211item_uint32_t cfpmaxduration ;
p80211item_uint32_t fhdwelltime ;
p80211item_uint32_t fhhopset ;
p80211item_uint32_t fhhoppattern ;
p80211item_uint32_t dschannel ;
p80211item_uint32_t ibssatimwindow ;
p80211item_uint32_t probedelay ;
p80211item_uint32_t cfpollable ;
p80211item_uint32_t cfpollreq ;
p80211item_uint32_t basicrate1 ;
p80211item_uint32_t basicrate2 ;
p80211item_uint32_t basicrate3 ;
p80211item_uint32_t basicrate4 ;
p80211item_uint32_t basicrate5 ;
p80211item_uint32_t basicrate6 ;
p80211item_uint32_t basicrate7 ;
p80211item_uint32_t basicrate8 ;
p80211item_uint32_t operationalrate1 ;
p80211item_uint32_t operationalrate2 ;
p80211item_uint32_t operationalrate3 ;
p80211item_uint32_t operationalrate4 ;
p80211item_uint32_t operationalrate5 ;
p80211item_uint32_t operationalrate6 ;
p80211item_uint32_t operationalrate7 ;
p80211item_uint32_t operationalrate8 ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_start_t;
typedef struct p80211msg_dot11ind_authenticate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_13C[1] ;
p80211item_uint32_t authenticationtype ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_authenticate_t;
typedef struct p80211msg_dot11ind_deauthenticate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_14C[1] ;
p80211item_uint32_t reasoncode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_deauthenticate_t;
typedef struct p80211msg_dot11ind_associate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_15C[1] ;
p80211item_uint32_t aid ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_associate_t;
typedef struct p80211msg_dot11ind_reassociate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_16C[1] ;
p80211item_uint32_t aid ;
p80211item_pstr6_t oldapaddress ;
UINT8 pad_17C[1] ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_reassociate_t;
typedef struct p80211msg_dot11ind_disassociate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t peerstaaddress ;
UINT8 pad_18C[1] ;
p80211item_uint32_t reasoncode ;
} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_disassociate_t;
typedef struct p80211msg_lnxreq_ifstate
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t ifstate ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_ifstate_t;
typedef struct p80211msg_lnxreq_wlansniff
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t enable ;
p80211item_uint32_t channel ;
p80211item_uint32_t prismheader ;
p80211item_uint32_t wlanheader ;
p80211item_uint32_t keepwepflags ;
p80211item_uint32_t stripfcs ;
p80211item_uint32_t packet_trunc ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_wlansniff_t;
typedef struct p80211msg_lnxreq_hostwep
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t resultcode ;
p80211item_uint32_t decrypt ;
p80211item_uint32_t encrypt ;
} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_hostwep_t;
typedef struct p80211msg_lnxreq_commsquality
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t resultcode ;
p80211item_uint32_t dbm ;
p80211item_uint32_t link ;
p80211item_uint32_t level ;
p80211item_uint32_t noise ;
} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_commsquality_t;
typedef struct p80211msg_lnxreq_autojoin
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr32_t ssid ;
UINT8 pad_19D[3] ;
p80211item_uint32_t authtype ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_autojoin_t;
typedef struct p80211msg_lnxind_wlansniffrm
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t hosttime ;
p80211item_uint32_t mactime ;
p80211item_uint32_t channel ;
p80211item_uint32_t rssi ;
p80211item_uint32_t sq ;
p80211item_uint32_t signal ;
p80211item_uint32_t noise ;
p80211item_uint32_t rate ;
p80211item_uint32_t istx ;
p80211item_uint32_t frmlen ;
} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_wlansniffrm_t;
typedef struct p80211msg_lnxind_roam
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t reason ;
} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_roam_t;
typedef struct p80211msg_p2req_join
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_pstr6_t bssid ;
UINT8 pad_20C[1] ;
p80211item_uint32_t basicrate1 ;
p80211item_uint32_t basicrate2 ;
p80211item_uint32_t basicrate3 ;
p80211item_uint32_t basicrate4 ;
p80211item_uint32_t basicrate5 ;
p80211item_uint32_t basicrate6 ;
p80211item_uint32_t basicrate7 ;
p80211item_uint32_t basicrate8 ;
p80211item_uint32_t operationalrate1 ;
p80211item_uint32_t operationalrate2 ;
p80211item_uint32_t operationalrate3 ;
p80211item_uint32_t operationalrate4 ;
p80211item_uint32_t operationalrate5 ;
p80211item_uint32_t operationalrate6 ;
p80211item_uint32_t operationalrate7 ;
p80211item_uint32_t operationalrate8 ;
p80211item_pstr32_t ssid ;
UINT8 pad_21D[3] ;
p80211item_uint32_t channel ;
p80211item_uint32_t authtype ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_join_t;
typedef struct p80211msg_p2req_readpda
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_unk1024_t pda ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readpda_t;
typedef struct p80211msg_p2req_readcis
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_unk1024_t cis ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readcis_t;
typedef struct p80211msg_p2req_auxport_state
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t enable ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_state_t;
typedef struct p80211msg_p2req_auxport_read
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t addr ;
p80211item_uint32_t len ;
p80211item_unk1024_t data ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_read_t;
typedef struct p80211msg_p2req_auxport_write
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t addr ;
p80211item_uint32_t len ;
p80211item_unk1024_t data ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_write_t;
typedef struct p80211msg_p2req_low_level
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t command ;
p80211item_uint32_t param0 ;
p80211item_uint32_t param1 ;
p80211item_uint32_t param2 ;
p80211item_uint32_t resp0 ;
p80211item_uint32_t resp1 ;
p80211item_uint32_t resp2 ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_low_level_t;
typedef struct p80211msg_p2req_test_command
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t testcode ;
p80211item_uint32_t testparam ;
p80211item_uint32_t resultcode ;
p80211item_uint32_t status ;
p80211item_uint32_t resp0 ;
p80211item_uint32_t resp1 ;
p80211item_uint32_t resp2 ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_test_command_t;
typedef struct p80211msg_p2req_mmi_read
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t addr ;
p80211item_uint32_t value ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_read_t;
typedef struct p80211msg_p2req_mmi_write
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t addr ;
p80211item_uint32_t data ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_write_t;
typedef struct p80211msg_p2req_ramdl_state
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t enable ;
p80211item_uint32_t exeaddr ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_state_t;
typedef struct p80211msg_p2req_ramdl_write
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t addr ;
p80211item_uint32_t len ;
p80211item_unk4096_t data ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_write_t;
typedef struct p80211msg_p2req_flashdl_state
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t enable ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_state_t;
typedef struct p80211msg_p2req_flashdl_write
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t addr ;
p80211item_uint32_t len ;
p80211item_unk4096_t data ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_write_t;
typedef struct p80211msg_p2req_mm_state
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t enable ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mm_state_t;
typedef struct p80211msg_p2req_dump_state
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t level ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_dump_state_t;
typedef struct p80211msg_p2req_channel_info
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t channellist ;
p80211item_uint32_t channeldwelltime ;
p80211item_uint32_t resultcode ;
p80211item_uint32_t numchinfo ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_t;
typedef struct p80211msg_p2req_channel_info_results
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t channel ;
p80211item_uint32_t resultcode ;
p80211item_uint32_t avgnoiselevel ;
p80211item_uint32_t peaknoiselevel ;
p80211item_uint32_t bssactive ;
p80211item_uint32_t pcfactive ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_results_t;
typedef struct p80211msg_p2req_enable
{
UINT32 msgcode ;
UINT32 msglen ;
UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
p80211item_uint32_t resultcode ;
} __WLAN_ATTRIB_PACK__ p80211msg_p2req_enable_t;
#endif
/* p80211mgmt.h
*
* Macros, types, and functions to handle 802.11 mgmt frames
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file declares the constants and types used in the interface
* between a wlan driver and the user mode utilities.
*
* Notes:
* - Constant values are always in HOST byte order. To assign
* values to multi-byte fields they _must_ be converted to
* ieee byte order. To retrieve multi-byte values from incoming
* frames, they must be converted to host order.
*
* - The len member of the frame structure does NOT!!! include
* the MAC CRC. Therefore, the len field on rx'd frames should
* have 4 subtracted from it.
*
* All functions declared here are implemented in p80211.c
*
* The types, macros, and functions defined here are primarily
* used for encoding and decoding management frames. They are
* designed to follow these patterns of use:
*
* DECODE:
* 1) a frame of length len is received into buffer b
* 2) using the hdr structure and macros, we determine the type
* 3) an appropriate mgmt frame structure, mf, is allocated and zeroed
* 4) mf.hdr = b
* mf.buf = b
* mf.len = len
* 5) call mgmt_decode( mf )
* 6) the frame field pointers in mf are now set. Note that any
* multi-byte frame field values accessed using the frame field
* pointers are in ieee byte order and will have to be converted
* to host order.
*
* ENCODE:
* 1) Library client allocates buffer space for maximum length
* frame of the desired type
* 2) Library client allocates a mgmt frame structure, called mf,
* of the desired type
* 3) Set the following:
* mf.type = <desired type>
* mf.buf = <allocated buffer address>
* 4) call mgmt_encode( mf )
* 5) all of the fixed field pointers and fixed length information element
* pointers in mf are now set to their respective locations in the
* allocated space (fortunately, all variable length information elements
* fall at the end of their respective frames).
* 5a) The length field is set to include the last of the fixed and fixed
* length fields. It may have to be updated for optional or variable
* length information elements.
* 6) Optional and variable length information elements are special cases
* and must be handled individually by the client code.
* --------------------------------------------------------------------
*/
#ifndef _P80211MGMT_H
#define _P80211MGMT_H
/*================================================================*/
/* System Includes */
/*================================================================*/
/* Project Includes */
#ifndef _WLAN_COMPAT_H
#include "wlan_compat.h"
#endif
#ifndef _P80211HDR_H
#include "p80211hdr.h"
#endif
/*================================================================*/
/* Constants */
/*-- Information Element IDs --------------------*/
#define WLAN_EID_SSID 0
#define WLAN_EID_SUPP_RATES 1
#define WLAN_EID_FH_PARMS 2
#define WLAN_EID_DS_PARMS 3
#define WLAN_EID_CF_PARMS 4
#define WLAN_EID_TIM 5
#define WLAN_EID_IBSS_PARMS 6
/*-- values 7-15 reserved --*/
#define WLAN_EID_CHALLENGE 16
/*-- values 17-31 reserved for challenge text extension --*/
/*-- values 32-255 reserved --*/
/*-- Reason Codes -------------------------------*/
#define WLAN_MGMT_REASON_RSVD 0
#define WLAN_MGMT_REASON_UNSPEC 1
#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2
#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3
#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4
#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5
#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6
#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7
#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8
#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9
/*-- Status Codes -------------------------------*/
#define WLAN_MGMT_STATUS_SUCCESS 0
#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1
#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10
#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11
#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12
#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13
#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14
#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15
#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16
#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17
#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18
/* p80211b additions */
#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19
#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20
#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21
/*-- Auth Algorithm Field ---------------------------*/
#define WLAN_AUTH_ALG_OPENSYSTEM 0
#define WLAN_AUTH_ALG_SHAREDKEY 1
/*-- Management Frame Field Offsets -------------*/
/* Note: Not all fields are listed because of variable lengths, */
/* see the code in p80211.c to see how we search for fields */
/* Note: These offsets are from the start of the frame data */
#define WLAN_BEACON_OFF_TS 0
#define WLAN_BEACON_OFF_BCN_INT 8
#define WLAN_BEACON_OFF_CAPINFO 10
#define WLAN_BEACON_OFF_SSID 12
#define WLAN_DISASSOC_OFF_REASON 0
#define WLAN_ASSOCREQ_OFF_CAP_INFO 0
#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2
#define WLAN_ASSOCREQ_OFF_SSID 4
#define WLAN_ASSOCRESP_OFF_CAP_INFO 0
#define WLAN_ASSOCRESP_OFF_STATUS 2
#define WLAN_ASSOCRESP_OFF_AID 4
#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6
#define WLAN_REASSOCREQ_OFF_CAP_INFO 0
#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2
#define WLAN_REASSOCREQ_OFF_CURR_AP 4
#define WLAN_REASSOCREQ_OFF_SSID 10
#define WLAN_REASSOCRESP_OFF_CAP_INFO 0
#define WLAN_REASSOCRESP_OFF_STATUS 2
#define WLAN_REASSOCRESP_OFF_AID 4
#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6
#define WLAN_PROBEREQ_OFF_SSID 0
#define WLAN_PROBERESP_OFF_TS 0
#define WLAN_PROBERESP_OFF_BCN_INT 8
#define WLAN_PROBERESP_OFF_CAP_INFO 10
#define WLAN_PROBERESP_OFF_SSID 12
#define WLAN_AUTHEN_OFF_AUTH_ALG 0
#define WLAN_AUTHEN_OFF_AUTH_SEQ 2
#define WLAN_AUTHEN_OFF_STATUS 4
#define WLAN_AUTHEN_OFF_CHALLENGE 6
#define WLAN_DEAUTHEN_OFF_REASON 0
/*================================================================*/
/* Macros */
/*-- Capability Field ---------------------------*/
#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT0)
#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1)
#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2)
#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT3) >> 3)
#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT4) >> 4)
/* p80211b additions */
#define WLAN_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT5) >> 5)
#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT6) >> 6)
#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT7) >> 7)
#define WLAN_SET_MGMT_CAP_INFO_ESS(n) (n)
#define WLAN_SET_MGMT_CAP_INFO_IBSS(n) ((n) << 1)
#define WLAN_SET_MGMT_CAP_INFO_CFPOLLABLE(n) ((n) << 2)
#define WLAN_SET_MGMT_CAP_INFO_CFPOLLREQ(n) ((n) << 3)
#define WLAN_SET_MGMT_CAP_INFO_PRIVACY(n) ((n) << 4)
/* p80211b additions */
#define WLAN_SET_MGMT_CAP_INFO_SHORT(n) ((n) << 5)
#define WLAN_SET_MGMT_CAP_INFO_PBCC(n) ((n) << 6)
#define WLAN_SET_MGMT_CAP_INFO_AGILITY(n) ((n) << 7)
/*================================================================*/
/* Types */
/*-- Information Element Types --------------------*/
/* prototype structure, all IEs start with these members */
typedef struct wlan_ie
{
UINT8 eid;
UINT8 len;
} __WLAN_ATTRIB_PACK__ wlan_ie_t;
/*-- Service Set Identity (SSID) -----------------*/
typedef struct wlan_ie_ssid
{
UINT8 eid;
UINT8 len;
UINT8 ssid[1]; /* may be zero, ptrs may overlap */
} __WLAN_ATTRIB_PACK__ wlan_ie_ssid_t;
/*-- Supported Rates -----------------------------*/
typedef struct wlan_ie_supp_rates
{
UINT8 eid;
UINT8 len;
UINT8 rates[1]; /* had better be at LEAST one! */
} __WLAN_ATTRIB_PACK__ wlan_ie_supp_rates_t;
/*-- FH Parameter Set ----------------------------*/
typedef struct wlan_ie_fh_parms
{
UINT8 eid;
UINT8 len;
UINT16 dwell;
UINT8 hopset;
UINT8 hoppattern;
UINT8 hopindex;
} __WLAN_ATTRIB_PACK__ wlan_ie_fh_parms_t;
/*-- DS Parameter Set ----------------------------*/
typedef struct wlan_ie_ds_parms
{
UINT8 eid;
UINT8 len;
UINT8 curr_ch;
} __WLAN_ATTRIB_PACK__ wlan_ie_ds_parms_t;
/*-- CF Parameter Set ----------------------------*/
typedef struct wlan_ie_cf_parms
{
UINT8 eid;
UINT8 len;
UINT8 cfp_cnt;
UINT8 cfp_period;
UINT16 cfp_maxdur;
UINT16 cfp_durremaining;
} __WLAN_ATTRIB_PACK__ wlan_ie_cf_parms_t;
/*-- TIM ------------------------------------------*/
typedef struct wlan_ie_tim
{
UINT8 eid;
UINT8 len;
UINT8 dtim_cnt;
UINT8 dtim_period;
UINT8 bitmap_ctl;
UINT8 virt_bm[1];
} __WLAN_ATTRIB_PACK__ wlan_ie_tim_t;
/*-- IBSS Parameter Set ---------------------------*/
typedef struct wlan_ie_ibss_parms
{
UINT8 eid;
UINT8 len;
UINT16 atim_win;
} __WLAN_ATTRIB_PACK__ wlan_ie_ibss_parms_t;
/*-- Challenge Text ------------------------------*/
typedef struct wlan_ie_challenge
{
UINT8 eid;
UINT8 len;
UINT8 challenge[1];
} __WLAN_ATTRIB_PACK__ wlan_ie_challenge_t;
/*-------------------------------------------------*/
/* Frame Types */
/* prototype structure, all mgmt frame types will start with these members */
typedef struct wlan_fr_mgmt
{
UINT16 type;
UINT16 len; /* DOES NOT include CRC !!!!*/
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
} wlan_fr_mgmt_t;
/*-- Beacon ---------------------------------------*/
typedef struct wlan_fr_beacon
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT64 *ts;
UINT16 *bcn_int;
UINT16 *cap_info;
/*-- info elements ----------*/
wlan_ie_ssid_t *ssid;
wlan_ie_supp_rates_t *supp_rates;
wlan_ie_fh_parms_t *fh_parms;
wlan_ie_ds_parms_t *ds_parms;
wlan_ie_cf_parms_t *cf_parms;
wlan_ie_ibss_parms_t *ibss_parms;
wlan_ie_tim_t *tim;
} wlan_fr_beacon_t;
/*-- IBSS ATIM ------------------------------------*/
typedef struct wlan_fr_ibssatim
{
UINT16 type;
UINT16 len;
UINT8* buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
/* this frame type has a null body */
} wlan_fr_ibssatim_t;
/*-- Disassociation -------------------------------*/
typedef struct wlan_fr_disassoc
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT16 *reason;
/*-- info elements ----------*/
} wlan_fr_disassoc_t;
/*-- Association Request --------------------------*/
typedef struct wlan_fr_assocreq
{
UINT16 type;
UINT16 len;
UINT8* buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT16 *cap_info;
UINT16 *listen_int;
/*-- info elements ----------*/
wlan_ie_ssid_t *ssid;
wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_assocreq_t;
/*-- Association Response -------------------------*/
typedef struct wlan_fr_assocresp
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT16 *cap_info;
UINT16 *status;
UINT16 *aid;
/*-- info elements ----------*/
wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_assocresp_t;
/*-- Reassociation Request ------------------------*/
typedef struct wlan_fr_reassocreq
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT16 *cap_info;
UINT16 *listen_int;
UINT8 *curr_ap;
/*-- info elements ----------*/
wlan_ie_ssid_t *ssid;
wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_reassocreq_t;
/*-- Reassociation Response -----------------------*/
typedef struct wlan_fr_reassocresp
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT16 *cap_info;
UINT16 *status;
UINT16 *aid;
/*-- info elements ----------*/
wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_reassocresp_t;
/*-- Probe Request --------------------------------*/
typedef struct wlan_fr_probereq
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
wlan_ie_ssid_t *ssid;
wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_probereq_t;
/*-- Probe Response -------------------------------*/
typedef struct wlan_fr_proberesp
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT64 *ts;
UINT16 *bcn_int;
UINT16 *cap_info;
/*-- info elements ----------*/
wlan_ie_ssid_t *ssid;
wlan_ie_supp_rates_t *supp_rates;
wlan_ie_fh_parms_t *fh_parms;
wlan_ie_ds_parms_t *ds_parms;
wlan_ie_cf_parms_t *cf_parms;
wlan_ie_ibss_parms_t *ibss_parms;
} wlan_fr_proberesp_t;
/*-- Authentication -------------------------------*/
typedef struct wlan_fr_authen
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT16 *auth_alg;
UINT16 *auth_seq;
UINT16 *status;
/*-- info elements ----------*/
wlan_ie_challenge_t *challenge;
} wlan_fr_authen_t;
/*-- Deauthenication -----------------------------*/
typedef struct wlan_fr_deauthen
{
UINT16 type;
UINT16 len;
UINT8 *buf;
p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
void *priv;
/*-- fixed fields -----------*/
UINT16 *reason;
/*-- info elements ----------*/
} wlan_fr_deauthen_t;
/*================================================================*/
/* Extern Declarations */
/*================================================================*/
/* Function Declarations */
void wlan_mgmt_encode_beacon( wlan_fr_beacon_t *f );
void wlan_mgmt_decode_beacon( wlan_fr_beacon_t *f );
void wlan_mgmt_encode_disassoc( wlan_fr_disassoc_t *f );
void wlan_mgmt_decode_disassoc( wlan_fr_disassoc_t *f );
void wlan_mgmt_encode_assocreq( wlan_fr_assocreq_t *f );
void wlan_mgmt_decode_assocreq( wlan_fr_assocreq_t *f );
void wlan_mgmt_encode_assocresp( wlan_fr_assocresp_t *f );
void wlan_mgmt_decode_assocresp( wlan_fr_assocresp_t *f );
void wlan_mgmt_encode_reassocreq( wlan_fr_reassocreq_t *f );
void wlan_mgmt_decode_reassocreq( wlan_fr_reassocreq_t *f );
void wlan_mgmt_encode_reassocresp( wlan_fr_reassocresp_t *f );
void wlan_mgmt_decode_reassocresp( wlan_fr_reassocresp_t *f );
void wlan_mgmt_encode_probereq( wlan_fr_probereq_t *f );
void wlan_mgmt_decode_probereq( wlan_fr_probereq_t *f );
void wlan_mgmt_encode_proberesp( wlan_fr_proberesp_t *f );
void wlan_mgmt_decode_proberesp( wlan_fr_proberesp_t *f );
void wlan_mgmt_encode_authen( wlan_fr_authen_t *f );
void wlan_mgmt_decode_authen( wlan_fr_authen_t *f );
void wlan_mgmt_encode_deauthen( wlan_fr_deauthen_t *f );
void wlan_mgmt_decode_deauthen( wlan_fr_deauthen_t *f );
#endif /* _P80211MGMT_H */
/* src/p80211/p80211mod.c
*
* Module entry and exit for p80211
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file contains the p80211.o entry and exit points defined for linux
* kernel modules.
*
* Notes:
* - all module parameters for p80211.o should be defined here.
*
* --------------------------------------------------------------------
*/
/*================================================================*/
/* System Includes */
#include <linux/version.h>
#include <linux/module.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25))
#include <linux/moduleparam.h>
#endif
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include "version.h"
#include "wlan_compat.h"
/*================================================================*/
/* Project Includes */
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211mgmt.h"
#include "p80211conv.h"
#include "p80211msg.h"
#include "p80211netdev.h"
#include "p80211req.h"
/*================================================================*/
/* Local Constants */
/*================================================================*/
/* Local Macros */
/*================================================================*/
/* Local Types */
/*================================================================*/
/* Local Static Definitions */
static char *version = "p80211.o: " WLAN_RELEASE;
/*----------------------------------------------------------------*/
/* --Module Parameters */
int wlan_watchdog = 5000;
module_param(wlan_watchdog, int, 0644);
MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");
int wlan_wext_write = 0;
#if WIRELESS_EXT > 12
module_param(wlan_wext_write, int, 0644);
MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
#endif
#ifdef WLAN_INCLUDE_DEBUG
int wlan_debug=0;
module_param(wlan_debug, int, 0644);
MODULE_PARM_DESC(wlan_debug, "p80211 debug level");
#endif
MODULE_LICENSE("Dual MPL/GPL");
/*================================================================*/
/* Local Function Declarations */
int init_module(void);
void cleanup_module(void);
/*================================================================*/
/* Function Definitions */
/*----------------------------------------------------------------
* init_module
*
* Module initialization routine, called once at module load time.
*
* Arguments:
* none
*
* Returns:
* 0 - success
* ~0 - failure, module is unloaded.
*
* Side effects:
* TODO: define
*
* Call context:
* process thread (insmod or modprobe)
----------------------------------------------------------------*/
int init_module(void)
{
DBFENTER;
#if 0
printk(KERN_NOTICE "%s (%s) Loaded\n", version, WLAN_BUILD_DATE);
#endif
p80211netdev_startup();
#ifdef CONFIG_HOTPLUG
p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_STARTUP);
#endif
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* cleanup_module
*
* Called at module unload time. This is our last chance to
* clean up after ourselves.
*
* Arguments:
* none
*
* Returns:
* nothing
*
* Side effects:
* TODO: define
*
* Call context:
* process thread
*
----------------------------------------------------------------*/
void cleanup_module(void)
{
DBFENTER;
#ifdef CONFIG_HOTPLUG
p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_SHUTDOWN);
#endif
p80211netdev_shutdown();
printk(KERN_NOTICE "%s Unloaded\n", version);
DBFEXIT;
return;
}
EXPORT_SYMBOL(p80211netdev_hwremoved);
EXPORT_SYMBOL(register_wlandev);
EXPORT_SYMBOL(p80211netdev_rx);
EXPORT_SYMBOL(unregister_wlandev);
EXPORT_SYMBOL(wlan_setup);
EXPORT_SYMBOL(wlan_unsetup);
EXPORT_SYMBOL(p80211_suspend);
EXPORT_SYMBOL(p80211_resume);
EXPORT_SYMBOL(p80211skb_free);
EXPORT_SYMBOL(p80211skb_rxmeta_attach);
EXPORT_SYMBOL(p80211wext_event_associated);
/* p80211msg.h
*
* Macros, constants, types, and funcs for req and ind messages
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*/
#ifndef _P80211MSG_H
#define _P80211MSG_H
/*================================================================*/
/* System Includes */
/*================================================================*/
/* Project Includes */
#ifndef _WLAN_COMPAT_H
#include "wlan_compat.h"
#endif
/*================================================================*/
/* Constants */
#define MSG_BUFF_LEN 4000
#define WLAN_DEVNAMELEN_MAX 16
/*================================================================*/
/* Macros */
/*================================================================*/
/* Types */
/*--------------------------------------------------------------------*/
/*----- Message Structure Types --------------------------------------*/
/*--------------------------------------------------------------------*/
/* Prototype msg type */
typedef struct p80211msg
{
UINT32 msgcode;
UINT32 msglen;
UINT8 devname[WLAN_DEVNAMELEN_MAX];
} __WLAN_ATTRIB_PACK__ p80211msg_t;
typedef struct p80211msgd
{
UINT32 msgcode;
UINT32 msglen;
UINT8 devname[WLAN_DEVNAMELEN_MAX];
UINT8 args[0];
} __WLAN_ATTRIB_PACK__ p80211msgd_t;
/*================================================================*/
/* Extern Declarations */
/*================================================================*/
/* Function Declarations */
#endif /* _P80211MSG_H */
/* src/p80211/p80211knetdev.c
*
* Linux Kernel net device interface
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* The functions required for a Linux network device are defined here.
*
* --------------------------------------------------------------------
*/
/*================================================================*/
/* System Includes */
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/kmod.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
#include <linux/sockios.h>
#include <linux/etherdevice.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
#endif
#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
#endif
#include <net/net_namespace.h>
/*================================================================*/
/* Project Includes */
#include "version.h"
#include "wlan_compat.h"
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
#include "p80211mgmt.h"
#include "p80211msg.h"
#include "p80211netdev.h"
#include "p80211ioctl.h"
#include "p80211req.h"
#include "p80211metastruct.h"
#include "p80211metadef.h"
/*================================================================*/
/* Local Constants */
/*================================================================*/
/* Local Macros */
/*================================================================*/
/* Local Types */
/*================================================================*/
/* Local Static Definitions */
#define __NO_VERSION__ /* prevent the static definition */
#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *proc_p80211;
#endif
/*================================================================*/
/* Local Function Declarations */
/* Support functions */
static void p80211netdev_rx_bh(unsigned long arg);
/* netdevice method functions */
static int p80211knetdev_init( netdevice_t *netdev);
static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev);
static int p80211knetdev_open( netdevice_t *netdev);
static int p80211knetdev_stop( netdevice_t *netdev );
static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev);
static void p80211knetdev_set_multicast_list(netdevice_t *dev);
static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);
static void p80211knetdev_tx_timeout(netdevice_t *netdev);
static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc);
#ifdef CONFIG_PROC_FS
static int
p80211netdev_proc_read(
char *page,
char **start,
off_t offset,
int count,
int *eof,
void *data);
#endif
/*================================================================*/
/* Function Definitions */
/*----------------------------------------------------------------
* p80211knetdev_startup
*
* Initialize the wlandevice/netdevice part of 802.11 services at
* load time.
*
* Arguments:
* none
*
* Returns:
* nothing
----------------------------------------------------------------*/
void p80211netdev_startup(void)
{
DBFENTER;
#ifdef CONFIG_PROC_FS
if (init_net.proc_net != NULL) {
proc_p80211 = create_proc_entry(
"p80211",
(S_IFDIR|S_IRUGO|S_IXUGO),
init_net.proc_net);
}
#endif
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* p80211knetdev_shutdown
*
* Shutdown the wlandevice/netdevice part of 802.11 services at
* unload time.
*
* Arguments:
* none
*
* Returns:
* nothing
----------------------------------------------------------------*/
void
p80211netdev_shutdown(void)
{
DBFENTER;
#ifdef CONFIG_PROC_FS
if (proc_p80211 != NULL) {
remove_proc_entry("p80211", init_net.proc_net);
}
#endif
DBFEXIT;
}
/*----------------------------------------------------------------
* p80211knetdev_init
*
* Init method for a Linux netdevice. Called in response to
* register_netdev.
*
* Arguments:
* none
*
* Returns:
* nothing
----------------------------------------------------------------*/
static int p80211knetdev_init( netdevice_t *netdev)
{
DBFENTER;
/* Called in response to register_netdev */
/* This is usually the probe function, but the probe has */
/* already been done by the MSD and the create_kdev */
/* function. All we do here is return success */
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* p80211knetdev_get_stats
*
* Statistics retrieval for linux netdevices. Here we're reporting
* the Linux i/f level statistics. Hence, for the primary numbers,
* we don't want to report the numbers from the MIB. Eventually,
* it might be useful to collect some of the error counters though.
*
* Arguments:
* netdev Linux netdevice
*
* Returns:
* the address of the statistics structure
----------------------------------------------------------------*/
static struct net_device_stats*
p80211knetdev_get_stats(netdevice_t *netdev)
{
wlandevice_t *wlandev = (wlandevice_t*)netdev->priv;
DBFENTER;
/* TODO: review the MIB stats for items that correspond to
linux stats */
DBFEXIT;
return &(wlandev->linux_stats);
}
/*----------------------------------------------------------------
* p80211knetdev_open
*
* Linux netdevice open method. Following a successful call here,
* the device is supposed to be ready for tx and rx. In our
* situation that may not be entirely true due to the state of the
* MAC below.
*
* Arguments:
* netdev Linux network device structure
*
* Returns:
* zero on success, non-zero otherwise
----------------------------------------------------------------*/
static int p80211knetdev_open( netdevice_t *netdev )
{
int result = 0; /* success */
wlandevice_t *wlandev = (wlandevice_t*)(netdev->priv);
DBFENTER;
/* Check to make sure the MSD is running */
if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
return -ENODEV;
}
/* Tell the MSD to open */
if ( wlandev->open != NULL) {
result = wlandev->open(wlandev);
if ( result == 0 ) {
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) )
netdev->interrupt = 0;
#endif
p80211netdev_start_queue(wlandev);
wlandev->state = WLAN_DEVICE_OPEN;
}
} else {
result = -EAGAIN;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* p80211knetdev_stop
*
* Linux netdevice stop (close) method. Following this call,
* no frames should go up or down through this interface.
*
* Arguments:
* netdev Linux network device structure
*
* Returns:
* zero on success, non-zero otherwise
----------------------------------------------------------------*/
static int p80211knetdev_stop( netdevice_t *netdev )
{
int result = 0;
wlandevice_t *wlandev = (wlandevice_t*)(netdev->priv);
DBFENTER;
if ( wlandev->close != NULL ) {
result = wlandev->close(wlandev);
}
p80211netdev_stop_queue(wlandev);
wlandev->state = WLAN_DEVICE_CLOSED;
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* p80211netdev_rx
*
* Frame receive function called by the mac specific driver.
*
* Arguments:
* wlandev WLAN network device structure
* skb skbuff containing a full 802.11 frame.
* Returns:
* nothing
* Side effects:
*
----------------------------------------------------------------*/
void
p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb )
{
DBFENTER;
/* Enqueue for post-irq processing */
skb_queue_tail(&wlandev->nsd_rxq, skb);
tasklet_schedule(&wlandev->rx_bh);
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* p80211netdev_rx_bh
*
* Deferred processing of all received frames.
*
* Arguments:
* wlandev WLAN network device structure
* skb skbuff containing a full 802.11 frame.
* Returns:
* nothing
* Side effects:
*
----------------------------------------------------------------*/
static void p80211netdev_rx_bh(unsigned long arg)
{
wlandevice_t *wlandev = (wlandevice_t *) arg;
struct sk_buff *skb = NULL;
netdevice_t *dev = wlandev->netdev;
p80211_hdr_a3_t *hdr;
UINT16 fc;
DBFENTER;
/* Let's empty our our queue */
while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
if (wlandev->state == WLAN_DEVICE_OPEN) {
if (dev->type != ARPHRD_ETHER) {
/* RAW frame; we shouldn't convert it */
// XXX Append the Prism Header here instead.
/* set up various data fields */
skb->dev = dev;
skb_reset_mac_header(skb);
skb->ip_summed = CHECKSUM_NONE;
skb->pkt_type = PACKET_OTHERHOST;
skb->protocol = htons(ETH_P_80211_RAW);
dev->last_rx = jiffies;
wlandev->linux_stats.rx_packets++;
wlandev->linux_stats.rx_bytes += skb->len;
netif_rx_ni(skb);
continue;
} else {
hdr = (p80211_hdr_a3_t *)skb->data;
fc = ieee2host16(hdr->fc);
if (p80211_rx_typedrop(wlandev, fc)) {
dev_kfree_skb(skb);
continue;
}
/* perform mcast filtering */
if (wlandev->netdev->flags & IFF_ALLMULTI) {
/* allow my local address through */
if (memcmp(hdr->a1, wlandev->netdev->dev_addr, WLAN_ADDR_LEN) != 0) {
/* but reject anything else that isn't multicast */
if (!(hdr->a1[0] & 0x01)) {
dev_kfree_skb(skb);
continue;
}
}
}
if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
skb->dev->last_rx = jiffies;
wlandev->linux_stats.rx_packets++;
wlandev->linux_stats.rx_bytes += skb->len;
netif_rx_ni(skb);
continue;
}
WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n");
}
}
dev_kfree_skb(skb);
}
DBFEXIT;
}
/*----------------------------------------------------------------
* p80211knetdev_hard_start_xmit
*
* Linux netdevice method for transmitting a frame.
*
* Arguments:
* skb Linux sk_buff containing the frame.
* netdev Linux netdevice.
*
* Side effects:
* If the lower layers report that buffers are full. netdev->tbusy
* will be set to prevent higher layers from sending more traffic.
*
* Note: If this function returns non-zero, higher layers retain
* ownership of the skb.
*
* Returns:
* zero on success, non-zero on failure.
----------------------------------------------------------------*/
static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev)
{
int result = 0;
int txresult = -1;
wlandevice_t *wlandev = (wlandevice_t*)netdev->priv;
p80211_hdr_t p80211_hdr;
p80211_metawep_t p80211_wep;
DBFENTER;
if (skb == NULL) {
return 0;
}
if (wlandev->state != WLAN_DEVICE_OPEN) {
result = 1;
goto failed;
}
memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));
memset(&p80211_wep, 0, sizeof(p80211_metawep_t));
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
if ( test_and_set_bit(0, (void*)&(netdev->tbusy)) != 0 ) {
/* We've been called w/ tbusy set, has the tx */
/* path stalled? */
WLAN_LOG_DEBUG(1, "called when tbusy set\n");
result = 1;
goto failed;
}
#else
if ( netif_queue_stopped(netdev) ) {
WLAN_LOG_DEBUG(1, "called when queue stopped.\n");
result = 1;
goto failed;
}
netif_stop_queue(netdev);
/* No timeout handling here, 2.3.38+ kernels call the
* timeout function directly.
* TODO: Add timeout handling.
*/
#endif
/* Check to see that a valid mode is set */
switch( wlandev->macmode ) {
case WLAN_MACMODE_IBSS_STA:
case WLAN_MACMODE_ESS_STA:
case WLAN_MACMODE_ESS_AP:
break;
default:
/* Mode isn't set yet, just drop the frame
* and return success .
* TODO: we need a saner way to handle this
*/
if(skb->protocol != ETH_P_80211_RAW) {
p80211netdev_start_queue(wlandev);
WLAN_LOG_NOTICE(
"Tx attempt prior to association, frame dropped.\n");
wlandev->linux_stats.tx_dropped++;
result = 0;
goto failed;
}
break;
}
/* Check for raw transmits */
if(skb->protocol == ETH_P_80211_RAW) {
if (!capable(CAP_NET_ADMIN)) {
result = 1;
goto failed;
}
/* move the header over */
memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t));
skb_pull(skb, sizeof(p80211_hdr_t));
} else {
if ( skb_ether_to_p80211(wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0 ) {
/* convert failed */
WLAN_LOG_DEBUG(1, "ether_to_80211(%d) failed.\n",
wlandev->ethconv);
result = 1;
goto failed;
}
}
if ( wlandev->txframe == NULL ) {
result = 1;
goto failed;
}
netdev->trans_start = jiffies;
wlandev->linux_stats.tx_packets++;
/* count only the packet payload */
wlandev->linux_stats.tx_bytes += skb->len;
txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
if ( txresult == 0) {
/* success and more buf */
/* avail, re: hw_txdata */
p80211netdev_wake_queue(wlandev);
result = 0;
} else if ( txresult == 1 ) {
/* success, no more avail */
WLAN_LOG_DEBUG(3, "txframe success, no more bufs\n");
/* netdev->tbusy = 1; don't set here, irqhdlr */
/* may have already cleared it */
result = 0;
} else if ( txresult == 2 ) {
/* alloc failure, drop frame */
WLAN_LOG_DEBUG(3, "txframe returned alloc_fail\n");
result = 1;
} else {
/* buffer full or queue busy, drop frame. */
WLAN_LOG_DEBUG(3, "txframe returned full or busy\n");
result = 1;
}
failed:
/* Free up the WEP buffer if it's not the same as the skb */
if ((p80211_wep.data) && (p80211_wep.data != skb->data))
kfree(p80211_wep.data);
/* we always free the skb here, never in a lower level. */
if (!result)
dev_kfree_skb(skb);
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* p80211knetdev_set_multicast_list
*
* Called from higher lavers whenever there's a need to set/clear
* promiscuous mode or rewrite the multicast list.
*
* Arguments:
* none
*
* Returns:
* nothing
----------------------------------------------------------------*/
static void p80211knetdev_set_multicast_list(netdevice_t *dev)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
DBFENTER;
/* TODO: real multicast support as well */
if (wlandev->set_multicast_list)
wlandev->set_multicast_list(wlandev, dev);
DBFEXIT;
}
#ifdef SIOCETHTOOL
static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
{
UINT32 ethcmd;
struct ethtool_drvinfo info;
struct ethtool_value edata;
memset(&info, 0, sizeof(info));
memset(&edata, 0, sizeof(edata));
if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
return -EFAULT;
switch (ethcmd) {
case ETHTOOL_GDRVINFO:
info.cmd = ethcmd;
snprintf(info.driver, sizeof(info.driver), "p80211_%s",
wlandev->nsdname);
snprintf(info.version, sizeof(info.version), "%s",
WLAN_RELEASE);
// info.fw_version
// info.bus_info
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
#ifdef ETHTOOL_GLINK
case ETHTOOL_GLINK:
edata.cmd = ethcmd;
if (wlandev->linkstatus &&
(wlandev->macmode != WLAN_MACMODE_NONE)) {
edata.data = 1;
} else {
edata.data = 0;
}
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
#endif
return -EOPNOTSUPP;
}
#endif
/*----------------------------------------------------------------
* p80211knetdev_do_ioctl
*
* Handle an ioctl call on one of our devices. Everything Linux
* ioctl specific is done here. Then we pass the contents of the
* ifr->data to the request message handler.
*
* Arguments:
* dev Linux kernel netdevice
* ifr Our private ioctl request structure, typed for the
* generic struct ifreq so we can use ptr to func
* w/o cast.
*
* Returns:
* zero on success, a negative errno on failure. Possible values:
* -ENETDOWN Device isn't up.
* -EBUSY cmd already in progress
* -ETIME p80211 cmd timed out (MSD may have its own timers)
* -EFAULT memory fault copying msg from user buffer
* -ENOMEM unable to allocate kernel msg buffer
* -ENOSYS bad magic, it the cmd really for us?
* -EINTR sleeping on cmd, awakened by signal, cmd cancelled.
*
* Call Context:
* Process thread (ioctl caller). TODO: SMP support may require
* locks.
----------------------------------------------------------------*/
static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
{
int result = 0;
p80211ioctl_req_t *req = (p80211ioctl_req_t*)ifr;
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
UINT8 *msgbuf;
DBFENTER;
WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
#if WIRELESS_EXT < 13
/* Is this a wireless extensions ioctl? */
if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
if ((result = p80211wext_support_ioctl(dev, ifr, cmd))
!= (-EOPNOTSUPP)) {
goto bail;
}
}
#endif
#ifdef SIOCETHTOOL
if (cmd == SIOCETHTOOL) {
result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data);
goto bail;
}
#endif
/* Test the magic, assume ifr is good if it's there */
if ( req->magic != P80211_IOCTL_MAGIC ) {
result = -ENOSYS;
goto bail;
}
if ( cmd == P80211_IFTEST ) {
result = 0;
goto bail;
} else if ( cmd != P80211_IFREQ ) {
result = -ENOSYS;
goto bail;
}
/* Allocate a buf of size req->len */
if ((msgbuf = kmalloc( req->len, GFP_KERNEL))) {
if ( copy_from_user( msgbuf, (void __user *) req->data, req->len) ) {
result = -EFAULT;
} else {
result = p80211req_dorequest( wlandev, msgbuf);
}
if ( result == 0 ) {
if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) {
result = -EFAULT;
}
}
kfree(msgbuf);
} else {
result = -ENOMEM;
}
bail:
DBFEXIT;
return result; /* If allocate,copyfrom or copyto fails, return errno */
}
/*----------------------------------------------------------------
* p80211knetdev_set_mac_address
*
* Handles the ioctl for changing the MACAddress of a netdevice
*
* references: linux/netdevice.h and drivers/net/net_init.c
*
* NOTE: [MSM] We only prevent address changes when the netdev is
* up. We don't control anything based on dot11 state. If the
* address is changed on a STA that's currently associated, you
* will probably lose the ability to send and receive data frames.
* Just be aware. Therefore, this should usually only be done
* prior to scan/join/auth/assoc.
*
* Arguments:
* dev netdevice struct
* addr the new MACAddress (a struct)
*
* Returns:
* zero on success, a negative errno on failure. Possible values:
* -EBUSY device is bussy (cmd not possible)
* -and errors returned by: p80211req_dorequest(..)
*
* by: Collin R. Mulliner <collin@mulliner.org>
----------------------------------------------------------------*/
static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
{
struct sockaddr *new_addr = addr;
p80211msg_dot11req_mibset_t dot11req;
p80211item_unk392_t *mibattr;
p80211item_pstr6_t *macaddr;
p80211item_uint32_t *resultcode;
int result = 0;
DBFENTER;
/* If we're running, we don't allow MAC address changes */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
if ( dev->start) {
return -EBUSY;
}
#else
if (netif_running(dev)) {
return -EBUSY;
}
#endif
/* Set up some convenience pointers. */
mibattr = &dot11req.mibattribute;
macaddr = (p80211item_pstr6_t*)&mibattr->data;
resultcode = &dot11req.resultcode;
/* Set up a dot11req_mibset */
memset(&dot11req, 0, sizeof(p80211msg_dot11req_mibset_t));
dot11req.msgcode = DIDmsg_dot11req_mibset;
dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t);
memcpy(dot11req.devname,
((wlandevice_t*)(dev->priv))->name,
WLAN_DEVNAMELEN_MAX - 1);
/* Set up the mibattribute argument */
mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
mibattr->status = P80211ENUM_msgitem_status_data_ok;
mibattr->len = sizeof(mibattr->data);
macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress;
macaddr->status = P80211ENUM_msgitem_status_data_ok;
macaddr->len = sizeof(macaddr->data);
macaddr->data.len = WLAN_ADDR_LEN;
memcpy(&macaddr->data.data, new_addr->sa_data, WLAN_ADDR_LEN);
/* Set up the resultcode argument */
resultcode->did = DIDmsg_dot11req_mibset_resultcode;
resultcode->status = P80211ENUM_msgitem_status_no_value;
resultcode->len = sizeof(resultcode->data);
resultcode->data = 0;
/* now fire the request */
result = p80211req_dorequest(dev->priv, (UINT8*)&dot11req);
/* If the request wasn't successful, report an error and don't
* change the netdev address
*/
if ( result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
WLAN_LOG_ERROR(
"Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
result = -EADDRNOTAVAIL;
} else {
/* everything's ok, change the addr in netdev */
memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
}
DBFEXIT;
return result;
}
static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
{
DBFENTER;
// 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
// and another 8 for wep.
if ( (new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
return -EINVAL;
dev->mtu = new_mtu;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* wlan_setup
*
* Roughly matches the functionality of ether_setup. Here
* we set up any members of the wlandevice structure that are common
* to all devices. Additionally, we allocate a linux 'struct device'
* and perform the same setup as ether_setup.
*
* Note: It's important that the caller have setup the wlandev->name
* ptr prior to calling this function.
*
* Arguments:
* wlandev ptr to the wlandev structure for the
* interface.
* Returns:
* zero on success, non-zero otherwise.
* Call Context:
* Should be process thread. We'll assume it might be
* interrupt though. When we add support for statically
* compiled drivers, this function will be called in the
* context of the kernel startup code.
----------------------------------------------------------------*/
int wlan_setup(wlandevice_t *wlandev)
{
int result = 0;
netdevice_t *dev;
DBFENTER;
/* Set up the wlandev */
wlandev->state = WLAN_DEVICE_CLOSED;
wlandev->ethconv = WLAN_ETHCONV_8021h;
wlandev->macmode = WLAN_MACMODE_NONE;
/* Set up the rx queue */
skb_queue_head_init(&wlandev->nsd_rxq);
tasklet_init(&wlandev->rx_bh,
p80211netdev_rx_bh,
(unsigned long)wlandev);
/* Allocate and initialize the struct device */
dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC);
if ( dev == NULL ) {
WLAN_LOG_ERROR("Failed to alloc netdev.\n");
result = 1;
} else {
memset( dev, 0, sizeof(netdevice_t));
ether_setup(dev);
wlandev->netdev = dev;
dev->priv = wlandev;
dev->hard_start_xmit = p80211knetdev_hard_start_xmit;
dev->get_stats = p80211knetdev_get_stats;
#ifdef HAVE_PRIVATE_IOCTL
dev->do_ioctl = p80211knetdev_do_ioctl;
#endif
#ifdef HAVE_MULTICAST
dev->set_multicast_list = p80211knetdev_set_multicast_list;
#endif
dev->init = p80211knetdev_init;
dev->open = p80211knetdev_open;
dev->stop = p80211knetdev_stop;
#ifdef CONFIG_NET_WIRELESS
#if ((WIRELESS_EXT < 17) && (WIRELESS_EXT < 21))
dev->get_wireless_stats = p80211wext_get_wireless_stats;
#endif
#if WIRELESS_EXT > 12
dev->wireless_handlers = &p80211wext_handler_def;
#endif
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
dev->tbusy = 1;
dev->start = 0;
#else
netif_stop_queue(dev);
#endif
#ifdef HAVE_CHANGE_MTU
dev->change_mtu = wlan_change_mtu;
#endif
#ifdef HAVE_SET_MAC_ADDR
dev->set_mac_address = p80211knetdev_set_mac_address;
#endif
#ifdef HAVE_TX_TIMEOUT
dev->tx_timeout = &p80211knetdev_tx_timeout;
dev->watchdog_timeo = (wlan_watchdog * HZ) / 1000;
#endif
netif_carrier_off(dev);
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* wlan_unsetup
*
* This function is paired with the wlan_setup routine. It should
* be called after unregister_wlandev. Basically, all it does is
* free the 'struct device' that's associated with the wlandev.
* We do it here because the 'struct device' isn't allocated
* explicitly in the driver code, it's done in wlan_setup. To
* do the free in the driver might seem like 'magic'.
*
* Arguments:
* wlandev ptr to the wlandev structure for the
* interface.
* Returns:
* zero on success, non-zero otherwise.
* Call Context:
* Should be process thread. We'll assume it might be
* interrupt though. When we add support for statically
* compiled drivers, this function will be called in the
* context of the kernel startup code.
----------------------------------------------------------------*/
int wlan_unsetup(wlandevice_t *wlandev)
{
int result = 0;
DBFENTER;
tasklet_kill(&wlandev->rx_bh);
if (wlandev->netdev == NULL ) {
WLAN_LOG_ERROR("called without wlandev->netdev set.\n");
result = 1;
} else {
free_netdev(wlandev->netdev);
wlandev->netdev = NULL;
}
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* register_wlandev
*
* Roughly matches the functionality of register_netdev. This function
* is called after the driver has successfully probed and set up the
* resources for the device. It's now ready to become a named device
* in the Linux system.
*
* First we allocate a name for the device (if not already set), then
* we call the Linux function register_netdevice.
*
* Arguments:
* wlandev ptr to the wlandev structure for the
* interface.
* Returns:
* zero on success, non-zero otherwise.
* Call Context:
* Can be either interrupt or not.
----------------------------------------------------------------*/
int register_wlandev(wlandevice_t *wlandev)
{
int i = 0;
netdevice_t *dev = wlandev->netdev;
DBFENTER;
i = dev_alloc_name(wlandev->netdev, "wlan%d");
if (i >= 0) {
i = register_netdev(wlandev->netdev);
}
if (i != 0) {
return -EIO;
}
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) )
dev->name = wlandev->name;
#else
strcpy(wlandev->name, dev->name);
#endif
#ifdef CONFIG_PROC_FS
if (proc_p80211) {
wlandev->procdir = proc_mkdir(wlandev->name, proc_p80211);
if ( wlandev->procdir )
wlandev->procwlandev =
create_proc_read_entry("wlandev", 0,
wlandev->procdir,
p80211netdev_proc_read,
wlandev);
if (wlandev->nsd_proc_read)
create_proc_read_entry("nsd", 0,
wlandev->procdir,
wlandev->nsd_proc_read,
wlandev);
}
#endif
#ifdef CONFIG_HOTPLUG
p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REGISTER);
#endif
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* unregister_wlandev
*
* Roughly matches the functionality of unregister_netdev. This
* function is called to remove a named device from the system.
*
* First we tell linux that the device should no longer exist.
* Then we remove it from the list of known wlan devices.
*
* Arguments:
* wlandev ptr to the wlandev structure for the
* interface.
* Returns:
* zero on success, non-zero otherwise.
* Call Context:
* Can be either interrupt or not.
----------------------------------------------------------------*/
int unregister_wlandev(wlandevice_t *wlandev)
{
struct sk_buff *skb;
DBFENTER;
#ifdef CONFIG_HOTPLUG
p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REMOVE);
#endif
#ifdef CONFIG_PROC_FS
if ( wlandev->procwlandev ) {
remove_proc_entry("wlandev", wlandev->procdir);
}
if ( wlandev->nsd_proc_read ) {
remove_proc_entry("nsd", wlandev->procdir);
}
if (wlandev->procdir) {
remove_proc_entry(wlandev->name, proc_p80211);
}
#endif
unregister_netdev(wlandev->netdev);
/* Now to clean out the rx queue */
while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
dev_kfree_skb(skb);
}
DBFEXIT;
return 0;
}
#ifdef CONFIG_PROC_FS
/*----------------------------------------------------------------
* proc_read
*
* Read function for /proc/net/p80211/<device>/wlandev
*
* Arguments:
* buf
* start
* offset
* count
* eof
* data
* Returns:
* zero on success, non-zero otherwise.
* Call Context:
* Can be either interrupt or not.
----------------------------------------------------------------*/
static int
p80211netdev_proc_read(
char *page,
char **start,
off_t offset,
int count,
int *eof,
void *data)
{
char *p = page;
wlandevice_t *wlandev = (wlandevice_t *) data;
DBFENTER;
if (offset != 0) {
*eof = 1;
goto exit;
}
p += sprintf(p, "p80211 version: %s (%s)\n\n",
WLAN_RELEASE, WLAN_BUILD_DATE);
p += sprintf(p, "name : %s\n", wlandev->name);
p += sprintf(p, "nsd name : %s\n", wlandev->nsdname);
p += sprintf(p, "address : %02x:%02x:%02x:%02x:%02x:%02x\n",
wlandev->netdev->dev_addr[0], wlandev->netdev->dev_addr[1], wlandev->netdev->dev_addr[2],
wlandev->netdev->dev_addr[3], wlandev->netdev->dev_addr[4], wlandev->netdev->dev_addr[5]);
p += sprintf(p, "nsd caps : %s%s%s%s%s%s%s%s%s%s\n",
(wlandev->nsdcaps & P80211_NSDCAP_HARDWAREWEP) ? "wep_hw " : "",
(wlandev->nsdcaps & P80211_NSDCAP_TIEDWEP) ? "wep_tied " : "",
(wlandev->nsdcaps & P80211_NSDCAP_NOHOSTWEP) ? "wep_hw_only " : "",
(wlandev->nsdcaps & P80211_NSDCAP_PBCC) ? "pbcc " : "",
(wlandev->nsdcaps & P80211_NSDCAP_SHORT_PREAMBLE) ? "short_preamble " : "",
(wlandev->nsdcaps & P80211_NSDCAP_AGILITY) ? "agility " : "",
(wlandev->nsdcaps & P80211_NSDCAP_AP_RETRANSMIT) ? "ap_retransmit " : "",
(wlandev->nsdcaps & P80211_NSDCAP_HWFRAGMENT) ? "hw_frag " : "",
(wlandev->nsdcaps & P80211_NSDCAP_AUTOJOIN) ? "autojoin " : "",
(wlandev->nsdcaps & P80211_NSDCAP_NOSCAN) ? "" : "scan ");
p += sprintf(p, "bssid : %02x:%02x:%02x:%02x:%02x:%02x\n",
wlandev->bssid[0], wlandev->bssid[1], wlandev->bssid[2],
wlandev->bssid[3], wlandev->bssid[4], wlandev->bssid[5]);
p += sprintf(p, "Enabled : %s%s\n",
(wlandev->shortpreamble) ? "short_preamble " : "",
(wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) ? "privacy" : "");
exit:
DBFEXIT;
return (p - page);
}
#endif
/*----------------------------------------------------------------
* p80211netdev_hwremoved
*
* Hardware removed notification. This function should be called
* immediately after an MSD has detected that the underlying hardware
* has been yanked out from under us. The primary things we need
* to do are:
* - Mark the wlandev
* - Prevent any further traffic from the knetdev i/f
* - Prevent any further requests from mgmt i/f
* - If there are any waitq'd mgmt requests or mgmt-frame exchanges,
* shut them down.
* - Call the MSD hwremoved function.
*
* The remainder of the cleanup will be handled by unregister().
* Our primary goal here is to prevent as much tickling of the MSD
* as possible since the MSD is already in a 'wounded' state.
*
* TODO: As new features are added, this function should be
* updated.
*
* Arguments:
* wlandev WLAN network device structure
* Returns:
* nothing
* Side effects:
*
* Call context:
* Usually interrupt.
----------------------------------------------------------------*/
void p80211netdev_hwremoved(wlandevice_t *wlandev)
{
DBFENTER;
wlandev->hwremoved = 1;
if ( wlandev->state == WLAN_DEVICE_OPEN) {
p80211netdev_stop_queue(wlandev);
}
netif_device_detach(wlandev->netdev);
DBFEXIT;
}
/*----------------------------------------------------------------
* p80211_rx_typedrop
*
* Classifies the frame, increments the appropriate counter, and
* returns 0|1|2 indicating whether the driver should handle, ignore, or
* drop the frame
*
* Arguments:
* wlandev wlan device structure
* fc frame control field
*
* Returns:
* zero if the frame should be handled by the driver,
* one if the frame should be ignored
* anything else means we drop it.
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc)
{
UINT16 ftype;
UINT16 fstype;
int drop = 0;
/* Classify frame, increment counter */
ftype = WLAN_GET_FC_FTYPE(fc);
fstype = WLAN_GET_FC_FSTYPE(fc);
#if 0
WLAN_LOG_DEBUG(4,
"rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
#endif
switch ( ftype ) {
case WLAN_FTYPE_MGMT:
if ((wlandev->netdev->flags & IFF_PROMISC) ||
(wlandev->netdev->flags & IFF_ALLMULTI)) {
drop = 1;
break;
}
WLAN_LOG_DEBUG(3, "rx'd mgmt:\n");
wlandev->rx.mgmt++;
switch( fstype ) {
case WLAN_FSTYPE_ASSOCREQ:
/* printk("assocreq"); */
wlandev->rx.assocreq++;
break;
case WLAN_FSTYPE_ASSOCRESP:
/* printk("assocresp"); */
wlandev->rx.assocresp++;
break;
case WLAN_FSTYPE_REASSOCREQ:
/* printk("reassocreq"); */
wlandev->rx.reassocreq++;
break;
case WLAN_FSTYPE_REASSOCRESP:
/* printk("reassocresp"); */
wlandev->rx.reassocresp++;
break;
case WLAN_FSTYPE_PROBEREQ:
/* printk("probereq"); */
wlandev->rx.probereq++;
break;
case WLAN_FSTYPE_PROBERESP:
/* printk("proberesp"); */
wlandev->rx.proberesp++;
break;
case WLAN_FSTYPE_BEACON:
/* printk("beacon"); */
wlandev->rx.beacon++;
break;
case WLAN_FSTYPE_ATIM:
/* printk("atim"); */
wlandev->rx.atim++;
break;
case WLAN_FSTYPE_DISASSOC:
/* printk("disassoc"); */
wlandev->rx.disassoc++;
break;
case WLAN_FSTYPE_AUTHEN:
/* printk("authen"); */
wlandev->rx.authen++;
break;
case WLAN_FSTYPE_DEAUTHEN:
/* printk("deauthen"); */
wlandev->rx.deauthen++;
break;
default:
/* printk("unknown"); */
wlandev->rx.mgmt_unknown++;
break;
}
/* printk("\n"); */
drop = 2;
break;
case WLAN_FTYPE_CTL:
if ((wlandev->netdev->flags & IFF_PROMISC) ||
(wlandev->netdev->flags & IFF_ALLMULTI)) {
drop = 1;
break;
}
WLAN_LOG_DEBUG(3, "rx'd ctl:\n");
wlandev->rx.ctl++;
switch( fstype ) {
case WLAN_FSTYPE_PSPOLL:
/* printk("pspoll"); */
wlandev->rx.pspoll++;
break;
case WLAN_FSTYPE_RTS:
/* printk("rts"); */
wlandev->rx.rts++;
break;
case WLAN_FSTYPE_CTS:
/* printk("cts"); */
wlandev->rx.cts++;
break;
case WLAN_FSTYPE_ACK:
/* printk("ack"); */
wlandev->rx.ack++;
break;
case WLAN_FSTYPE_CFEND:
/* printk("cfend"); */
wlandev->rx.cfend++;
break;
case WLAN_FSTYPE_CFENDCFACK:
/* printk("cfendcfack"); */
wlandev->rx.cfendcfack++;
break;
default:
/* printk("unknown"); */
wlandev->rx.ctl_unknown++;
break;
}
/* printk("\n"); */
drop = 2;
break;
case WLAN_FTYPE_DATA:
wlandev->rx.data++;
switch( fstype ) {
case WLAN_FSTYPE_DATAONLY:
wlandev->rx.dataonly++;
break;
case WLAN_FSTYPE_DATA_CFACK:
wlandev->rx.data_cfack++;
break;
case WLAN_FSTYPE_DATA_CFPOLL:
wlandev->rx.data_cfpoll++;
break;
case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
wlandev->rx.data__cfack_cfpoll++;
break;
case WLAN_FSTYPE_NULL:
WLAN_LOG_DEBUG(3, "rx'd data:null\n");
wlandev->rx.null++;
break;
case WLAN_FSTYPE_CFACK:
WLAN_LOG_DEBUG(3, "rx'd data:cfack\n");
wlandev->rx.cfack++;
break;
case WLAN_FSTYPE_CFPOLL:
WLAN_LOG_DEBUG(3, "rx'd data:cfpoll\n");
wlandev->rx.cfpoll++;
break;
case WLAN_FSTYPE_CFACK_CFPOLL:
WLAN_LOG_DEBUG(3, "rx'd data:cfack_cfpoll\n");
wlandev->rx.cfack_cfpoll++;
break;
default:
/* printk("unknown"); */
wlandev->rx.data_unknown++;
break;
}
break;
}
return drop;
}
#ifdef CONFIG_HOTPLUG
/* Notify userspace when a netdevice event occurs,
* by running '/sbin/hotplug net' with certain
* environment variables set.
*/
int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action)
{
char *argv[3], *envp[7], ifname[12 + IFNAMSIZ], action_str[32];
char nsdname[32], wlan_wext[32];
int i;
if (wlandev) {
sprintf(ifname, "INTERFACE=%s", wlandev->name);
sprintf(nsdname, "NSDNAME=%s", wlandev->nsdname);
} else {
sprintf(ifname, "INTERFACE=null");
sprintf(nsdname, "NSDNAME=null");
}
sprintf(wlan_wext, "WLAN_WEXT=%s", wlan_wext_write ? "y" : "");
sprintf(action_str, "ACTION=%s", action);
i = 0;
argv[i++] = hotplug_path;
argv[i++] = "wlan";
argv[i] = NULL;
i = 0;
/* minimal command environment */
envp [i++] = "HOME=/";
envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
envp [i++] = ifname;
envp [i++] = action_str;
envp [i++] = nsdname;
envp [i++] = wlan_wext;
envp [i] = NULL;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62))
return call_usermodehelper(argv [0], argv, envp);
#else
return call_usermodehelper(argv [0], argv, envp, 0);
#endif
}
#endif
void p80211_suspend(wlandevice_t *wlandev)
{
DBFENTER;
#ifdef CONFIG_HOTPLUG
p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_SUSPEND);
#endif
DBFEXIT;
}
void p80211_resume(wlandevice_t *wlandev)
{
DBFENTER;
#ifdef CONFIG_HOTPLUG
p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_RESUME);
#endif
DBFEXIT;
}
static void p80211knetdev_tx_timeout( netdevice_t *netdev)
{
wlandevice_t *wlandev = (wlandevice_t*)netdev->priv;
DBFENTER;
if (wlandev->tx_timeout) {
wlandev->tx_timeout(wlandev);
} else {
WLAN_LOG_WARNING("Implement tx_timeout for %s\n",
wlandev->nsdname);
p80211netdev_wake_queue(wlandev);
}
DBFEXIT;
}
/* p80211netdev.h
*
* WLAN net device structure and functions
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file declares the structure type that represents each wlan
* interface.
*
* --------------------------------------------------------------------
*/
#ifndef _LINUX_P80211NETDEV_H
#define _LINUX_P80211NETDEV_H
#include <linux/interrupt.h>
#include <linux/wireless.h>
/*================================================================*/
/* Constants */
#define WLAN_DEVICE_CLOSED 0
#define WLAN_DEVICE_OPEN 1
#define WLAN_MACMODE_NONE 0
#define WLAN_MACMODE_IBSS_STA 1
#define WLAN_MACMODE_ESS_STA 2
#define WLAN_MACMODE_ESS_AP 3
/* MSD States */
#define WLAN_MSD_START -1
#define WLAN_MSD_DRIVERLOADED 0
#define WLAN_MSD_HWPRESENT_PENDING 1
#define WLAN_MSD_HWFAIL 2
#define WLAN_MSD_HWPRESENT 3
#define WLAN_MSD_FWLOAD_PENDING 4
#define WLAN_MSD_FWLOAD 5
#define WLAN_MSD_RUNNING_PENDING 6
#define WLAN_MSD_RUNNING 7
#ifndef ETH_P_ECONET
#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */
#endif
#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
#ifndef ARPHRD_IEEE80211
#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */
#endif
#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */
#define ARPHRD_IEEE80211_PRISM 802
#endif
/*--- NSD Capabilities Flags ------------------------------*/
#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */
#define P80211_NSDCAP_TIEDWEP 0x02 /* can't decouple en/de */
#define P80211_NSDCAP_NOHOSTWEP 0x04 /* must use hardware wep */
#define P80211_NSDCAP_PBCC 0x08 /* hardware supports PBCC */
#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */
#define P80211_NSDCAP_AGILITY 0x20 /* hardware supports */
#define P80211_NSDCAP_AP_RETRANSMIT 0x40 /* nsd handles retransmits */
#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */
#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */
#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */
/*================================================================*/
/* Macros */
/*================================================================*/
/* Types */
/* Received frame statistics */
typedef struct p80211_frmrx_t
{
UINT32 mgmt;
UINT32 assocreq;
UINT32 assocresp;
UINT32 reassocreq;
UINT32 reassocresp;
UINT32 probereq;
UINT32 proberesp;
UINT32 beacon;
UINT32 atim;
UINT32 disassoc;
UINT32 authen;
UINT32 deauthen;
UINT32 mgmt_unknown;
UINT32 ctl;
UINT32 pspoll;
UINT32 rts;
UINT32 cts;
UINT32 ack;
UINT32 cfend;
UINT32 cfendcfack;
UINT32 ctl_unknown;
UINT32 data;
UINT32 dataonly;
UINT32 data_cfack;
UINT32 data_cfpoll;
UINT32 data__cfack_cfpoll;
UINT32 null;
UINT32 cfack;
UINT32 cfpoll;
UINT32 cfack_cfpoll;
UINT32 data_unknown;
UINT32 decrypt;
UINT32 decrypt_err;
} p80211_frmrx_t;
#ifdef WIRELESS_EXT
/* called by /proc/net/wireless */
struct iw_statistics* p80211wext_get_wireless_stats(netdevice_t *dev);
/* wireless extensions' ioctls */
int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
#if WIRELESS_EXT > 12
extern struct iw_handler_def p80211wext_handler_def;
#endif
int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
#endif /* wireless extensions */
/* WEP stuff */
#define NUM_WEPKEYS 4
#define MAX_KEYLEN 32
#define HOSTWEP_DEFAULTKEY_MASK (BIT1|BIT0)
#define HOSTWEP_DECRYPT BIT4
#define HOSTWEP_ENCRYPT BIT5
#define HOSTWEP_PRIVACYINVOKED BIT6
#define HOSTWEP_EXCLUDEUNENCRYPTED BIT7
extern int wlan_watchdog;
extern int wlan_wext_write;
/* WLAN device type */
typedef struct wlandevice
{
struct wlandevice *next; /* link for list of devices */
void *priv; /* private data for MSD */
/* Subsystem State */
char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev()*/
char *nsdname;
UINT32 state; /* Device I/F state (open/closed) */
UINT32 msdstate; /* state of underlying driver */
UINT32 hwremoved; /* Has the hw been yanked out? */
/* Hardware config */
UINT irq;
UINT iobase;
UINT membase;
UINT32 nsdcaps; /* NSD Capabilities flags */
/* Config vars */
UINT ethconv;
/* device methods (init by MSD, used by p80211 */
int (*open)(struct wlandevice *wlandev);
int (*close)(struct wlandevice *wlandev);
void (*reset)(struct wlandevice *wlandev );
int (*txframe)(struct wlandevice *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
int (*mlmerequest)(struct wlandevice *wlandev, p80211msg_t *msg);
int (*set_multicast_list)(struct wlandevice *wlandev,
netdevice_t *dev);
void (*tx_timeout)(struct wlandevice *wlandev);
#ifdef CONFIG_PROC_FS
int (*nsd_proc_read)(char *page, char **start, off_t offset, int count, int *eof, void *data);
#endif
/* 802.11 State */
UINT8 bssid[WLAN_BSSID_LEN];
p80211pstr32_t ssid;
UINT32 macmode;
int linkstatus;
int shortpreamble; /* C bool */
/* WEP State */
UINT8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN];
UINT8 wep_keylens[NUM_WEPKEYS];
int hostwep;
/* Request/Confirm i/f state (used by p80211) */
unsigned long request_pending; /* flag, access atomically */
/* netlink socket */
/* queue for indications waiting for cmd completion */
/* Linux netdevice and support */
netdevice_t *netdev; /* ptr to linux netdevice */
struct net_device_stats linux_stats;
#ifdef CONFIG_PROC_FS
/* Procfs support */
struct proc_dir_entry *procdir;
struct proc_dir_entry *procwlandev;
#endif
/* Rx bottom half */
struct tasklet_struct rx_bh;
struct sk_buff_head nsd_rxq;
/* 802.11 device statistics */
struct p80211_frmrx_t rx;
/* compatibility to wireless extensions */
#ifdef WIRELESS_EXT
struct iw_statistics wstats;
/* jkriegl: iwspy fields */
UINT8 spy_number;
char spy_address[IW_MAX_SPY][ETH_ALEN];
struct iw_quality spy_stat[IW_MAX_SPY];
#endif
} wlandevice_t;
/* WEP stuff */
int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen);
int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv);
int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv);
/*================================================================*/
/* Externs */
/*================================================================*/
/* Function Declarations */
void p80211netdev_startup(void);
void p80211netdev_shutdown(void);
int wlan_setup(wlandevice_t *wlandev);
int wlan_unsetup(wlandevice_t *wlandev);
int register_wlandev(wlandevice_t *wlandev);
int unregister_wlandev(wlandevice_t *wlandev);
void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
void p80211netdev_hwremoved(wlandevice_t *wlandev);
void p80211_suspend(wlandevice_t *wlandev);
void p80211_resume(wlandevice_t *wlandev);
/*================================================================*/
/* Function Definitions */
static inline void
p80211netdev_stop_queue(wlandevice_t *wlandev)
{
if ( !wlandev ) return;
if ( !wlandev->netdev ) return;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
wlandev->netdev->tbusy = 1;
wlandev->netdev->start = 0;
#else
netif_stop_queue(wlandev->netdev);
#endif
}
static inline void
p80211netdev_start_queue(wlandevice_t *wlandev)
{
if ( !wlandev ) return;
if ( !wlandev->netdev ) return;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
wlandev->netdev->tbusy = 0;
wlandev->netdev->start = 1;
#else
netif_start_queue(wlandev->netdev);
#endif
}
static inline void
p80211netdev_wake_queue(wlandevice_t *wlandev)
{
if ( !wlandev ) return;
if ( !wlandev->netdev ) return;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
wlandev->netdev->tbusy = 0;
mark_bh(NET_BH);
#else
netif_wake_queue(wlandev->netdev);
#endif
}
#ifdef CONFIG_HOTPLUG
#define WLAN_HOTPLUG_REGISTER "register"
#define WLAN_HOTPLUG_REMOVE "remove"
#define WLAN_HOTPLUG_STARTUP "startup"
#define WLAN_HOTPLUG_SHUTDOWN "shutdown"
#define WLAN_HOTPLUG_SUSPEND "suspend"
#define WLAN_HOTPLUG_RESUME "resume"
int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action);
#endif
#endif
/* src/p80211/p80211req.c
*
* Request/Indication/MacMgmt interface handling functions
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file contains the functions, types, and macros to support the
* MLME request interface that's implemented via the device ioctls.
*
* --------------------------------------------------------------------
*/
/*================================================================*/
/* System Includes */
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include "version.h"
#include "wlan_compat.h"
/*================================================================*/
/* Project Includes */
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211mgmt.h"
#include "p80211conv.h"
#include "p80211msg.h"
#include "p80211netdev.h"
#include "p80211ioctl.h"
#include "p80211metadef.h"
#include "p80211metastruct.h"
#include "p80211req.h"
/*================================================================*/
/* Local Constants */
/* Maximum amount of time we'll wait for a request to complete */
#define P80211REQ_MAXTIME 3*HZ /* 3 seconds */
/*================================================================*/
/* Local Macros */
/*================================================================*/
/* Local Types */
/*================================================================*/
/* Local Static Definitions */
/*================================================================*/
/* Local Function Declarations */
static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg);
static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mibget_t *mib_msg, int isget);
/*================================================================*/
/* Function Definitions */
/*----------------------------------------------------------------
* p80211req_dorequest
*
* Handles an MLME reqest/confirm message.
*
* Arguments:
* wlandev WLAN device struct
* msgbuf Buffer containing a request message
*
* Returns:
* 0 on success, an errno otherwise
*
* Call context:
* Potentially blocks the caller, so it's a good idea to
* not call this function from an interrupt context.
----------------------------------------------------------------*/
int p80211req_dorequest( wlandevice_t *wlandev, UINT8 *msgbuf)
{
int result = 0;
p80211msg_t *msg = (p80211msg_t*)msgbuf;
DBFENTER;
/* Check to make sure the MSD is running */
if (
!((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
msg->msgcode == DIDmsg_lnxreq_ifstate) ||
wlandev->msdstate == WLAN_MSD_RUNNING ||
wlandev->msdstate == WLAN_MSD_FWLOAD) ) {
return -ENODEV;
}
/* Check Permissions */
if (!capable(CAP_NET_ADMIN) &&
(msg->msgcode != DIDmsg_dot11req_mibget)) {
WLAN_LOG_ERROR("%s: only dot11req_mibget allowed for non-root.\n", wlandev->name);
return -EPERM;
}
/* Check for busy status */
if ( test_and_set_bit(1, &(wlandev->request_pending))) {
return -EBUSY;
}
/* Allow p80211 to look at msg and handle if desired. */
/* So far, all p80211 msgs are immediate, no waitq/timer necessary */
/* This may change. */
p80211req_handlemsg(wlandev, msg);
/* Pass it down to wlandev via wlandev->mlmerequest */
if ( wlandev->mlmerequest != NULL )
wlandev->mlmerequest(wlandev, msg);
clear_bit( 1, &(wlandev->request_pending));
DBFEXIT;
return result; /* if result==0, msg->status still may contain an err */
}
/*----------------------------------------------------------------
* p80211req_handlemsg
*
* p80211 message handler. Primarily looks for messages that
* belong to p80211 and then dispatches the appropriate response.
* TODO: we don't do anything yet. Once the linuxMIB is better
* defined we'll need a get/set handler.
*
* Arguments:
* wlandev WLAN device struct
* msg message structure
*
* Returns:
* nothing (any results are set in the status field of the msg)
*
* Call context:
* Process thread
----------------------------------------------------------------*/
static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg)
{
DBFENTER;
switch (msg->msgcode) {
case DIDmsg_lnxreq_hostwep: {
p80211msg_lnxreq_hostwep_t *req = (p80211msg_lnxreq_hostwep_t*) msg;
wlandev->hostwep &= ~(HOSTWEP_DECRYPT|HOSTWEP_ENCRYPT);
if (req->decrypt.data == P80211ENUM_truth_true)
wlandev->hostwep |= HOSTWEP_DECRYPT;
if (req->encrypt.data == P80211ENUM_truth_true)
wlandev->hostwep |= HOSTWEP_ENCRYPT;
break;
}
case DIDmsg_dot11req_mibget:
case DIDmsg_dot11req_mibset: {
int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
p80211msg_dot11req_mibget_t *mib_msg = (p80211msg_dot11req_mibget_t *) msg;
p80211req_mibset_mibget (wlandev, mib_msg, isget);
}
default:
// XXX do nothing!
;
} /* switch msg->msgcode */
DBFEXIT;
return;
}
static int p80211req_mibset_mibget(wlandevice_t *wlandev,
p80211msg_dot11req_mibget_t *mib_msg,
int isget)
{
p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
p80211pstrd_t *pstr = (p80211pstrd_t*) mibitem->data;
UINT8 *key = mibitem->data + sizeof(p80211pstrd_t);
DBFENTER;
switch (mibitem->did) {
case DIDmib_dot11smt_p80211Table_p80211_ifstate: {
UINT32 *data = (UINT32 *) mibitem->data;
if (isget)
switch (wlandev->msdstate) {
case WLAN_MSD_HWPRESENT:
*data = P80211ENUM_ifstate_disable;
break;
case WLAN_MSD_FWLOAD:
*data = P80211ENUM_ifstate_fwload;
break;
case WLAN_MSD_RUNNING:
*data = P80211ENUM_ifstate_enable;
break;
default:
*data = P80211ENUM_ifstate_enable;
}
break;
}
case DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled: {
UINT32 *data = (UINT32 *) mibitem->data;
if (isget)
*data = wlandev->shortpreamble;
else
wlandev->shortpreamble = *data;
break;
}
case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0: {
if (!isget)
wep_change_key(wlandev, 0, key, pstr->len);
break;
}
case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1: {
if (!isget)
wep_change_key(wlandev, 1, key, pstr->len);
break;
}
case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2: {
if (!isget)
wep_change_key(wlandev, 2, key, pstr->len);
break;
}
case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3: {
if (!isget)
wep_change_key(wlandev, 3, key, pstr->len);
break;
}
case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID: {
UINT32 *data = (UINT32 *) mibitem->data;
if (isget) {
*data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
} else {
wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK);
wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK);
}
break;
}
case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked: {
UINT32 *data = (UINT32 *) mibitem->data;
if (isget) {
if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
*data = P80211ENUM_truth_true;
else
*data = P80211ENUM_truth_false;
} else {
wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED);
if (*data == P80211ENUM_truth_true)
wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED;
}
break;
}
case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted: {
UINT32 *data = (UINT32 *) mibitem->data;
if (isget) {
if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
*data = P80211ENUM_truth_true;
else
*data = P80211ENUM_truth_false;
} else {
wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED);
if (*data == P80211ENUM_truth_true)
wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED;
}
break;
}
default:
// XXXX do nothing!
;
}
DBFEXIT;
return 0;
}
/* p80211req.h
*
* Request handling functions
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*/
#ifndef _LINUX_P80211REQ_H
#define _LINUX_P80211REQ_H
/*================================================================*/
/* Constants */
/*================================================================*/
/* Macros */
/*================================================================*/
/* Types */
/*================================================================*/
/* Externs */
/*================================================================*/
/* Function Declarations */
int p80211req_dorequest(wlandevice_t *wlandev, UINT8 *msgbuf);
#endif
/* p80211types.h
*
* Macros, constants, types, and funcs for p80211 data types
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file declares some of the constants and types used in various
* parts of the linux-wlan system.
*
* Notes:
* - Constant values are always in HOST byte order.
*
* All functions and statics declared here are implemented in p80211types.c
* --------------------------------------------------------------------
*/
#ifndef _P80211TYPES_H
#define _P80211TYPES_H
/*================================================================*/
/* System Includes */
/*================================================================*/
/*================================================================*/
/* Project Includes */
/*================================================================*/
#ifndef _WLAN_COMPAT_H
#include "wlan_compat.h"
#endif
/*================================================================*/
/* Constants */
/*================================================================*/
/*----------------------------------------------------------------*/
/* p80211 data type codes used for MIB items and message */
/* arguments. The various metadata structures provide additional */
/* information about these types. */
#define P80211_TYPE_OCTETSTR 1 /* pascal array of bytes */
#define P80211_TYPE_DISPLAYSTR 2 /* pascal array of bytes containing ascii */
#define P80211_TYPE_INT 4 /* UINT32 min and max limited by 32 bits */
#define P80211_TYPE_ENUMINT 5 /* UINT32 holding a numeric
code that can be mapped
to a textual name */
#define P80211_TYPE_UNKDATA 6 /* Data item containing an
unknown data type */
#define P80211_TYPE_INTARRAY 7 /* Array of 32-bit integers. */
#define P80211_TYPE_BITARRAY 8 /* Array of bits. */
#define P80211_TYPE_MACARRAY 9 /* Array of MAC addresses. */
/*----------------------------------------------------------------*/
/* The following constants are indexes into the Mib Category List */
/* and the Message Category List */
/* Mib Category List */
#define P80211_MIB_CAT_DOT11SMT 1
#define P80211_MIB_CAT_DOT11MAC 2
#define P80211_MIB_CAT_DOT11PHY 3
#define P80211SEC_DOT11SMT P80211_MIB_CAT_DOT11SMT
#define P80211SEC_DOT11MAC P80211_MIB_CAT_DOT11MAC
#define P80211SEC_DOT11PHY P80211_MIB_CAT_DOT11PHY
/* Message Category List */
#define P80211_MSG_CAT_DOT11REQ 1
#define P80211_MSG_CAT_DOT11IND 2
/* #define P80211_MSG_CAT_DOT11CFM 3 (doesn't exist at this time) */
#define P80211SEC_DOT11REQ P80211_MSG_CAT_DOT11REQ
#define P80211SEC_DOT11IND P80211_MSG_CAT_DOT11IND
/* #define P80211SEC_DOT11CFM P80211_MSG_CAT_DOT11CFM (doesn't exist at this time */
/*----------------------------------------------------------------*/
/* p80211 DID field codes that represent access type and */
/* is_table status. */
#define P80211DID_ACCESS_READ 0x10000000
#define P80211DID_ACCESS_WRITE 0x08000000
#define P80211DID_WRITEONLY 0x00000001
#define P80211DID_READONLY 0x00000002
#define P80211DID_READWRITE 0x00000003
#define P80211DID_ISTABLE_FALSE 0
#define P80211DID_ISTABLE_TRUE 1
/*----------------------------------------------------------------*/
/* p80211 enumeration constants. The value to text mappings for */
/* these is in p80211types.c. These defines were generated */
/* from the mappings. */
/* error codes for lookups */
#define P80211ENUM_BAD 0xffffffffUL
#define P80211ENUM_BADSTR "P80211ENUM_BAD"
#define P80211ENUM_truth_false 0
#define P80211ENUM_truth_true 1
#define P80211ENUM_ifstate_disable 0
#define P80211ENUM_ifstate_fwload 1
#define P80211ENUM_ifstate_enable 2
#define P80211ENUM_powermgmt_active 1
#define P80211ENUM_powermgmt_powersave 2
#define P80211ENUM_bsstype_infrastructure 1
#define P80211ENUM_bsstype_independent 2
#define P80211ENUM_bsstype_any 3
#define P80211ENUM_authalg_opensystem 1
#define P80211ENUM_authalg_sharedkey 2
#define P80211ENUM_phytype_fhss 1
#define P80211ENUM_phytype_dsss 2
#define P80211ENUM_phytype_irbaseband 3
#define P80211ENUM_temptype_commercial 1
#define P80211ENUM_temptype_industrial 2
#define P80211ENUM_regdomain_fcc 16
#define P80211ENUM_regdomain_doc 32
#define P80211ENUM_regdomain_etsi 48
#define P80211ENUM_regdomain_spain 49
#define P80211ENUM_regdomain_france 50
#define P80211ENUM_regdomain_mkk 64
#define P80211ENUM_ccamode_edonly 1
#define P80211ENUM_ccamode_csonly 2
#define P80211ENUM_ccamode_edandcs 4
#define P80211ENUM_ccamode_cswithtimer 8
#define P80211ENUM_ccamode_hrcsanded 16
#define P80211ENUM_diversity_fixedlist 1
#define P80211ENUM_diversity_notsupported 2
#define P80211ENUM_diversity_dynamic 3
#define P80211ENUM_scantype_active 1
#define P80211ENUM_scantype_passive 2
#define P80211ENUM_scantype_both 3
#define P80211ENUM_resultcode_success 1
#define P80211ENUM_resultcode_invalid_parameters 2
#define P80211ENUM_resultcode_not_supported 3
#define P80211ENUM_resultcode_timeout 4
#define P80211ENUM_resultcode_too_many_req 5
#define P80211ENUM_resultcode_refused 6
#define P80211ENUM_resultcode_bss_already 7
#define P80211ENUM_resultcode_invalid_access 8
#define P80211ENUM_resultcode_invalid_mibattribute 9
#define P80211ENUM_resultcode_cant_set_readonly_mib 10
#define P80211ENUM_resultcode_implementation_failure 11
#define P80211ENUM_resultcode_cant_get_writeonly_mib 12
#define P80211ENUM_reason_unspec_reason 1
#define P80211ENUM_reason_auth_not_valid 2
#define P80211ENUM_reason_deauth_lv_ss 3
#define P80211ENUM_reason_inactivity 4
#define P80211ENUM_reason_ap_overload 5
#define P80211ENUM_reason_class23_err 6
#define P80211ENUM_reason_class3_err 7
#define P80211ENUM_reason_disas_lv_ss 8
#define P80211ENUM_reason_asoc_not_auth 9
#define P80211ENUM_status_successful 0
#define P80211ENUM_status_unspec_failure 1
#define P80211ENUM_status_unsup_cap 10
#define P80211ENUM_status_reasoc_no_asoc 11
#define P80211ENUM_status_fail_other 12
#define P80211ENUM_status_unspt_alg 13
#define P80211ENUM_status_auth_seq_fail 14
#define P80211ENUM_status_chlng_fail 15
#define P80211ENUM_status_auth_timeout 16
#define P80211ENUM_status_ap_full 17
#define P80211ENUM_status_unsup_rate 18
#define P80211ENUM_status_unsup_shortpreamble 19
#define P80211ENUM_status_unsup_pbcc 20
#define P80211ENUM_status_unsup_agility 21
#define P80211ENUM_msgitem_status_data_ok 0
#define P80211ENUM_msgitem_status_no_value 1
#define P80211ENUM_msgitem_status_invalid_itemname 2
#define P80211ENUM_msgitem_status_invalid_itemdata 3
#define P80211ENUM_msgitem_status_missing_itemdata 4
#define P80211ENUM_msgitem_status_incomplete_itemdata 5
#define P80211ENUM_msgitem_status_invalid_msg_did 6
#define P80211ENUM_msgitem_status_invalid_mib_did 7
#define P80211ENUM_msgitem_status_missing_conv_func 8
#define P80211ENUM_msgitem_status_string_too_long 9
#define P80211ENUM_msgitem_status_data_out_of_range 10
#define P80211ENUM_msgitem_status_string_too_short 11
#define P80211ENUM_msgitem_status_missing_valid_func 12
#define P80211ENUM_msgitem_status_unknown 13
#define P80211ENUM_msgitem_status_invalid_did 14
#define P80211ENUM_msgitem_status_missing_print_func 15
#define P80211ENUM_lnxroam_reason_unknown 0
#define P80211ENUM_lnxroam_reason_beacon 1
#define P80211ENUM_lnxroam_reason_signal 2
#define P80211ENUM_lnxroam_reason_txretry 3
#define P80211ENUM_lnxroam_reason_notjoined 4
#define P80211ENUM_p2preamble_long 0
#define P80211ENUM_p2preamble_short 2
#define P80211ENUM_p2preamble_mixed 3
/*----------------------------------------------------------------*/
/* p80211 max length constants for the different pascal strings. */
#define MAXLEN_PSTR6 (6) /* pascal array of 6 bytes */
#define MAXLEN_PSTR14 (14) /* pascal array of 14 bytes */
#define MAXLEN_PSTR32 (32) /* pascal array of 32 bytes */
#define MAXLEN_PSTR255 (255) /* pascal array of 255 bytes */
#define MAXLEN_MIBATTRIBUTE (392) /* maximum mibattribute */
/* where the size of the DATA itself */
/* is a DID-LEN-DATA triple */
/* with a max size of 4+4+384 */
#define P80211_SET_INT(item, value) do { \
(item).data = (value); \
(item).status = P80211ENUM_msgitem_status_data_ok; \
} while(0)
/*----------------------------------------------------------------*/
/* string constants */
#define NOT_SET "NOT_SET"
#define NOT_SUPPORTED "NOT_SUPPORTED"
#define UNKNOWN_DATA "UNKNOWN_DATA"
/*--------------------------------------------------------------------*/
/* Metadata flags */
/* MSM: Do these belong in p80211meta.h? I'm not sure. */
#define ISREQUIRED (0x80000000UL)
#define ISREQUEST (0x40000000UL)
#define ISCONFIRM (0x20000000UL)
/*================================================================*/
/* Macros */
/*--------------------------------------------------------------------*/
/* The following macros are used to manipulate the 'flags' field in */
/* the metadata. These are only used when the metadata is for */
/* command arguments to determine if the data item is required, and */
/* whether the metadata item is for a request command, confirm */
/* command or both. */
/*--------------------------------------------------------------------*/
/* MSM: Do these belong in p80211meta.h? I'm not sure */
#define P80211ITEM_SETFLAGS(q, r, c) ( q | r | c )
#define P80211ITEM_ISREQUIRED(flags) (((UINT32)(flags & ISREQUIRED)) >> 31 )
#define P80211ITEM_ISREQUEST(flags) (((UINT32)(flags & ISREQUEST)) >> 30 )
#define P80211ITEM_ISCONFIRM(flags) (((UINT32)(flags & ISCONFIRM)) >> 29 )
/*----------------------------------------------------------------*/
/* The following macro creates a name for an enum */
#define MKENUMNAME(name) p80211enum_ ## name
/*----------------------------------------------------------------
* The following constants and macros are used to construct and
* deconstruct the Data ID codes. The coding is as follows:
*
* ...rwtnnnnnnnniiiiiiggggggssssss s - Section
* g - Group
* i - Item
* n - Index
* t - Table flag
* w - Write flag
* r - Read flag
* . - Unused
*/
#define P80211DID_INVALID 0xffffffffUL
#define P80211DID_VALID 0x00000000UL
#define P80211DID_LSB_SECTION (0)
#define P80211DID_LSB_GROUP (6)
#define P80211DID_LSB_ITEM (12)
#define P80211DID_LSB_INDEX (18)
#define P80211DID_LSB_ISTABLE (26)
#define P80211DID_LSB_ACCESS (27)
#define P80211DID_MASK_SECTION (0x0000003fUL)
#define P80211DID_MASK_GROUP (0x0000003fUL)
#define P80211DID_MASK_ITEM (0x0000003fUL)
#define P80211DID_MASK_INDEX (0x000000ffUL)
#define P80211DID_MASK_ISTABLE (0x00000001UL)
#define P80211DID_MASK_ACCESS (0x00000003UL)
#define P80211DID_MK(a,m,l) ((((UINT32)(a)) & (m)) << (l))
#define P80211DID_MKSECTION(a) P80211DID_MK(a, \
P80211DID_MASK_SECTION, \
P80211DID_LSB_SECTION )
#define P80211DID_MKGROUP(a) P80211DID_MK(a, \
P80211DID_MASK_GROUP, \
P80211DID_LSB_GROUP )
#define P80211DID_MKITEM(a) P80211DID_MK(a, \
P80211DID_MASK_ITEM, \
P80211DID_LSB_ITEM )
#define P80211DID_MKINDEX(a) P80211DID_MK(a, \
P80211DID_MASK_INDEX, \
P80211DID_LSB_INDEX )
#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \
P80211DID_MASK_ISTABLE, \
P80211DID_LSB_ISTABLE )
#define P80211DID_MKID(s,g,i,n,t,a) (P80211DID_MKSECTION(s) | \
P80211DID_MKGROUP(g) | \
P80211DID_MKITEM(i) | \
P80211DID_MKINDEX(n) | \
P80211DID_MKISTABLE(t) | \
(a) )
#define P80211DID_GET(a,m,l) ((((UINT32)(a)) >> (l)) & (m))
#define P80211DID_SECTION(a) P80211DID_GET(a, \
P80211DID_MASK_SECTION, \
P80211DID_LSB_SECTION)
#define P80211DID_GROUP(a) P80211DID_GET(a, \
P80211DID_MASK_GROUP, \
P80211DID_LSB_GROUP)
#define P80211DID_ITEM(a) P80211DID_GET(a, \
P80211DID_MASK_ITEM, \
P80211DID_LSB_ITEM)
#define P80211DID_INDEX(a) P80211DID_GET(a, \
P80211DID_MASK_INDEX, \
P80211DID_LSB_INDEX)
#define P80211DID_ISTABLE(a) P80211DID_GET(a, \
P80211DID_MASK_ISTABLE, \
P80211DID_LSB_ISTABLE)
#define P80211DID_ACCESS(a) P80211DID_GET(a, \
P80211DID_MASK_ACCESS, \
P80211DID_LSB_ACCESS)
/*================================================================*/
/* Types */
/*----------------------------------------------------------------*/
/* The following structure types are used for the represenation */
/* of ENUMINT type metadata. */
typedef struct p80211enumpair
{
UINT32 val;
char *name;
} p80211enumpair_t;
typedef struct p80211enum
{
INT nitems;
p80211enumpair_t *list;
} p80211enum_t;
/*----------------------------------------------------------------*/
/* The following structure types are used to store data items in */
/* messages. */
/* Template pascal string */
typedef struct p80211pstr
{
UINT8 len;
} __WLAN_ATTRIB_PACK__ p80211pstr_t;
typedef struct p80211pstrd
{
UINT8 len;
UINT8 data[0];
} __WLAN_ATTRIB_PACK__ p80211pstrd_t;
/* Maximum pascal string */
typedef struct p80211pstr255
{
UINT8 len;
UINT8 data[MAXLEN_PSTR255];
} __WLAN_ATTRIB_PACK__ p80211pstr255_t;
/* pascal string for macaddress and bssid */
typedef struct p80211pstr6
{
UINT8 len;
UINT8 data[MAXLEN_PSTR6];
} __WLAN_ATTRIB_PACK__ p80211pstr6_t;
/* pascal string for channel list */
typedef struct p80211pstr14
{
UINT8 len;
UINT8 data[MAXLEN_PSTR14];
} __WLAN_ATTRIB_PACK__ p80211pstr14_t;
/* pascal string for ssid */
typedef struct p80211pstr32
{
UINT8 len;
UINT8 data[MAXLEN_PSTR32];
} __WLAN_ATTRIB_PACK__ p80211pstr32_t;
/* MAC address array */
typedef struct p80211macarray
{
UINT32 cnt;
UINT8 data[1][MAXLEN_PSTR6];
} __WLAN_ATTRIB_PACK__ p80211macarray_t;
/* prototype template */
typedef struct p80211item
{
UINT32 did;
UINT16 status;
UINT16 len;
} __WLAN_ATTRIB_PACK__ p80211item_t;
/* prototype template w/ data item */
typedef struct p80211itemd
{
UINT32 did;
UINT16 status;
UINT16 len;
UINT8 data[0];
} __WLAN_ATTRIB_PACK__ p80211itemd_t;
/* message data item for INT, BOUNDEDINT, ENUMINT */
typedef struct p80211item_uint32
{
UINT32 did;
UINT16 status;
UINT16 len;
UINT32 data;
} __WLAN_ATTRIB_PACK__ p80211item_uint32_t;
/* message data item for OCTETSTR, DISPLAYSTR */
typedef struct p80211item_pstr6
{
UINT32 did;
UINT16 status;
UINT16 len;
p80211pstr6_t data;
} __WLAN_ATTRIB_PACK__ p80211item_pstr6_t;
/* message data item for OCTETSTR, DISPLAYSTR */
typedef struct p80211item_pstr14
{
UINT32 did;
UINT16 status;
UINT16 len;
p80211pstr14_t data;
} __WLAN_ATTRIB_PACK__ p80211item_pstr14_t;
/* message data item for OCTETSTR, DISPLAYSTR */
typedef struct p80211item_pstr32
{
UINT32 did;
UINT16 status;
UINT16 len;
p80211pstr32_t data;
} __WLAN_ATTRIB_PACK__ p80211item_pstr32_t;
/* message data item for OCTETSTR, DISPLAYSTR */
typedef struct p80211item_pstr255
{
UINT32 did;
UINT16 status;
UINT16 len;
p80211pstr255_t data;
} __WLAN_ATTRIB_PACK__ p80211item_pstr255_t;
/* message data item for UNK 392, namely mib items */
typedef struct p80211item_unk392
{
UINT32 did;
UINT16 status;
UINT16 len;
UINT8 data[MAXLEN_MIBATTRIBUTE];
} __WLAN_ATTRIB_PACK__ p80211item_unk392_t;
/* message data item for UNK 1025, namely p2 pdas */
typedef struct p80211item_unk1024
{
UINT32 did;
UINT16 status;
UINT16 len;
UINT8 data[1024];
} __WLAN_ATTRIB_PACK__ p80211item_unk1024_t;
/* message data item for UNK 4096, namely p2 download chunks */
typedef struct p80211item_unk4096
{
UINT32 did;
UINT16 status;
UINT16 len;
UINT8 data[4096];
} __WLAN_ATTRIB_PACK__ p80211item_unk4096_t;
struct catlistitem;
/*----------------------------------------------------------------*/
/* The following structure type is used to represent all of the */
/* metadata items. Some components may choose to use more, */
/* less or different metadata items. */
typedef void (*p80211_totext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf);
typedef void (*p80211_fromtext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf);
typedef UINT32 (*p80211_valid_t)( struct catlistitem *, UINT32 did, UINT8* itembuf);
/*================================================================*/
/* Extern Declarations */
/*----------------------------------------------------------------*/
/* Enumeration Lists */
/* The following are the external declarations */
/* for all enumerations */
extern p80211enum_t MKENUMNAME(truth);
extern p80211enum_t MKENUMNAME(ifstate);
extern p80211enum_t MKENUMNAME(powermgmt);
extern p80211enum_t MKENUMNAME(bsstype);
extern p80211enum_t MKENUMNAME(authalg);
extern p80211enum_t MKENUMNAME(phytype);
extern p80211enum_t MKENUMNAME(temptype);
extern p80211enum_t MKENUMNAME(regdomain);
extern p80211enum_t MKENUMNAME(ccamode);
extern p80211enum_t MKENUMNAME(diversity);
extern p80211enum_t MKENUMNAME(scantype);
extern p80211enum_t MKENUMNAME(resultcode);
extern p80211enum_t MKENUMNAME(reason);
extern p80211enum_t MKENUMNAME(status);
extern p80211enum_t MKENUMNAME(msgcode);
extern p80211enum_t MKENUMNAME(msgitem_status);
extern p80211enum_t MKENUMNAME(lnxroam_reason);
extern p80211enum_t MKENUMNAME(p2preamble);
/*================================================================*/
/* Function Declarations */
/*----------------------------------------------------------------*/
/* The following declare some utility functions for use with the */
/* p80211enum_t type. */
UINT32 p80211enum_text2int(p80211enum_t *ep, char *text);
UINT32 p80211enum_int2text(p80211enum_t *ep, UINT32 val, char *text);
void p80211_error2text(int err_code, char *err_str);
/*----------------------------------------------------------------*/
/* The following declare some utility functions for use with the */
/* p80211item_t and p80211meta_t types. */
/*----------------------------------------------------------------*/
/* The following declare functions that perform validation and */
/* text to binary conversions based on the metadata for interface */
/* and MIB data items. */
/*----------------------------------------------------------------*/
/*-- DISPLAYSTR ------------------------------------------------------*/
/* pstr ==> cstr */
void p80211_totext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* cstr ==> pstr */
void p80211_fromtext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* function that checks validity of a displaystr binary value */
UINT32 p80211_isvalid_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
/*-- OCTETSTR --------------------------------------------------------*/
/* pstr ==> "xx:xx:...." */
void p80211_totext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* "xx:xx:...." ==> pstr */
void p80211_fromtext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* function that checks validity of an octetstr binary value */
UINT32 p80211_isvalid_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
/*-- INT -------------------------------------------------------------*/
/* UINT32 ==> %d */
void p80211_totext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* %d ==> UINT32 */
void p80211_fromtext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* function that checks validity of an int's binary value (always successful) */
UINT32 p80211_isvalid_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
/*-- ENUMINT ---------------------------------------------------------*/
/* UINT32 ==> <valuename> */
void p80211_totext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* <valuename> ==> UINT32 */
void p80211_fromtext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* function that checks validity of an enum's binary value */
UINT32 p80211_isvalid_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
/*-- INTARRAY --------------------------------------------------------*/
/* UINT32[] => %d,%d,%d,... */
void p80211_totext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* %d,%d,%d,... ==> UINT32[] */
void p80211_fromtext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* function that checks validity of an integer array's value */
UINT32 p80211_isvalid_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
/*-- BITARRAY --------------------------------------------------------*/
/* UINT32 ==> %d,%d,%d,... */
void p80211_totext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* %d,%d,%d,... ==> UINT32 */
void p80211_fromtext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* function that checks validity of a bit array's value */
UINT32 p80211_isvalid_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
/*-- MACARRAY --------------------------------------------------------*/
void p80211_totext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
void p80211_fromtext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* function that checks validity of a MAC address array's value */
UINT32 p80211_isvalid_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
/*-- MIBATTRIUBTE ------------------------------------------------------*/
/* <mibvalue> ==> <textual representation identified in MIB metadata> */
void p80211_totext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
void p80211_totext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* <textual representation identified in MIB metadata> ==> <mibvalue> */
void p80211_fromtext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
void p80211_fromtext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
/* function that checks validity of a mibitem's binary value */
UINT32 p80211_isvalid_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
UINT32 p80211_isvalid_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
#endif /* _P80211TYPES_H */
/* src/p80211/p80211wep.c
*
* WEP encode/decode for P80211.
*
* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*/
/*================================================================*/
/* System Includes */
#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/slab.h>
#include <linux/random.h>
#include "version.h"
#include "wlan_compat.h"
// #define WEP_DEBUG
/*================================================================*/
/* Project Includes */
#include "version.h"
#include "p80211hdr.h"
#include "p80211types.h"
#include "p80211msg.h"
#include "p80211conv.h"
#include "p80211netdev.h"
/*================================================================*/
/* Local Constants */
#define SSWAP(a,b) {UINT8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
#define WEP_KEY(x) (((x) & 0xC0) >> 6)
/*================================================================*/
/* Local Macros */
/*================================================================*/
/* Local Types */
/*================================================================*/
/* Local Static Definitions */
static const UINT32 wep_crc32_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
/*================================================================*/
/* Local Function Declarations */
/*================================================================*/
/* Function Definitions */
/* keylen in bytes! */
int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen)
{
if (keylen < 0) return -1;
if (keylen >= MAX_KEYLEN) return -1;
if (key == NULL) return -1;
if (keynum < 0) return -1;
if (keynum >= NUM_WEPKEYS) return -1;
#ifdef WEP_DEBUG
printk(KERN_DEBUG "WEP key %d len %d = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
#endif
wlandev->wep_keylens[keynum] = keylen;
memcpy(wlandev->wep_keys[keynum], key, keylen);
return 0;
}
/*
4-byte IV at start of buffer, 4-byte ICV at end of buffer.
if successful, buf start is payload begin, length -= 8;
*/
int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv)
{
UINT32 i, j, k, crc, keylen;
UINT8 s[256], key[64], c_crc[4];
UINT8 keyidx;
/* Needs to be at least 8 bytes of payload */
if (len <= 0) return -1;
/* initialize the first bytes of the key from the IV */
key[0] = iv[0];
key[1] = iv[1];
key[2] = iv[2];
keyidx = WEP_KEY(iv[3]);
if (key_override >= 0)
keyidx = key_override;
if (keyidx >= NUM_WEPKEYS) return -2;
keylen = wlandev->wep_keylens[keyidx];
if (keylen == 0) return -3;
/* copy the rest of the key over from the designated key */
memcpy(key+3, wlandev->wep_keys[keyidx], keylen);
keylen+=3; /* add in IV bytes */
#ifdef WEP_DEBUG
printk(KERN_DEBUG "D %d: %02x %02x %02x (%d %d) %02x:%02x:%02x:%02x:%02x\n", len, key[0], key[1], key[2], keyidx, keylen, key[3], key[4], key[5], key[6], key[7]);
#endif
/* set up the RC4 state */
for (i = 0; i < 256; i++)
s[i] = i;
j = 0;
for (i = 0; i < 256; i++) {
j = (j + s[i] + key[i % keylen]) & 0xff;
SSWAP(i,j);
}
/* Apply the RC4 to the data, update the CRC32 */
crc = ~0;
i = j = 0;
for (k = 0; k < len; k++) {
i = (i+1) & 0xff;
j = (j+s[i]) & 0xff;
SSWAP(i,j);
buf[k] ^= s[(s[i] + s[j]) & 0xff];
crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
}
crc = ~crc;
/* now let's check the crc */
c_crc[0] = crc;
c_crc[1] = crc >> 8;
c_crc[2] = crc >> 16;
c_crc[3] = crc >> 24;
for (k = 0; k < 4; k++) {
i = (i + 1) & 0xff;
j = (j+s[i]) & 0xff;
SSWAP(i,j);
if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k])
return -(4 | (k << 4)) ; /* ICV mismatch */
}
return 0;
}
/* encrypts in-place. */
int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv)
{
UINT32 i, j, k, crc, keylen;
UINT8 s[256], key[64];
/* no point in WEPping an empty frame */
if (len <= 0) return -1;
/* we need to have a real key.. */
if (keynum >= NUM_WEPKEYS) return -2;
keylen = wlandev->wep_keylens[keynum];
if (keylen <= 0) return -3;
/* use a random IV. And skip known weak ones. */
get_random_bytes(iv, 3);
while ((iv[1] == 0xff) && (iv[0] >= 3) && (iv[0] < keylen))
get_random_bytes(iv, 3);
iv[3] = (keynum & 0x03) << 6;
key[0] = iv[0];
key[1] = iv[1];
key[2] = iv[2];
/* copy the rest of the key over from the designated key */
memcpy(key+3, wlandev->wep_keys[keynum], keylen);
keylen+=3; /* add in IV bytes */
#ifdef WEP_DEBUG
printk(KERN_DEBUG "E %d (%d/%d %d) %02x %02x %02x %02x:%02x:%02x:%02x:%02x\n", len, iv[3], keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
#endif
/* set up the RC4 state */
for (i = 0; i < 256; i++)
s[i] = i;
j = 0;
for (i = 0; i < 256; i++) {
j = (j + s[i] + key[i % keylen]) & 0xff;
SSWAP(i,j);
}
/* Update CRC32 then apply RC4 to the data */
crc = ~0;
i = j = 0;
for (k = 0; k < len; k++) {
crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
i = (i+1) & 0xff;
j = (j+s[i]) & 0xff;
SSWAP(i,j);
dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff];
}
crc = ~crc;
/* now let's encrypt the crc */
icv[0] = crc;
icv[1] = crc >> 8;
icv[2] = crc >> 16;
icv[3] = crc >> 24;
for (k = 0; k < 4; k++) {
i = (i + 1) & 0xff;
j = (j+s[i]) & 0xff;
SSWAP(i,j);
icv[k] ^= s[(s[i] + s[j]) & 0xff];
}
return 0;
}
/* src/p80211/p80211wext.c
*
* Glue code to make linux-wlan-ng a happy wireless extension camper.
*
* original author: Reyk Floeter <reyk@synack.de>
* Completely re-written by Solomon Peachy <solomon@linux-wlan.com>
*
* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*/
/*================================================================*/
/* System Includes */
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
#endif
#include <linux/if_arp.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
/*================================================================*/
/* Project Includes */
#include "version.h"
#include "wlan_compat.h"
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
#include "p80211mgmt.h"
#include "p80211msg.h"
#include "p80211metastruct.h"
#include "p80211metadef.h"
#include "p80211netdev.h"
#include "p80211ioctl.h"
#include "p80211req.h"
static int p80211wext_giwrate(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra);
static int p80211wext_giwessid(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *data, char *essid);
/* compatibility to wireless extensions */
#ifdef WIRELESS_EXT
static UINT8 p80211_mhz_to_channel(UINT16 mhz)
{
if (mhz >= 5000) {
return ((mhz - 5000) / 5);
}
if (mhz == 2482)
return 14;
if (mhz >= 2407) {
return ((mhz - 2407) / 5);
}
return 0;
}
static UINT16 p80211_channel_to_mhz(UINT8 ch, int dot11a)
{
if (ch == 0)
return 0;
if (ch > 200)
return 0;
/* 5G */
if (dot11a) {
return (5000 + (5 * ch));
}
/* 2.4G */
if (ch == 14)
return 2484;
if ((ch < 14) && (ch > 0)) {
return (2407 + (5 * ch));
}
return 0;
}
/* taken from orinoco.c ;-) */
static const long p80211wext_channel_freq[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484
};
#define NUM_CHANNELS (sizeof(p80211wext_channel_freq) / sizeof(p80211wext_channel_freq[0]))
/* steal a spare bit to store the shared/opensystems state. should default to open if not set */
#define HOSTWEP_SHAREDKEY BIT3
/** function declarations =============== */
static int qual_as_percent(int snr ) {
if ( snr <= 0 )
return 0;
if ( snr <= 40 )
return snr*5/2;
return 100;
}
static int p80211wext_dorequest(wlandevice_t *wlandev, UINT32 did, UINT32 data)
{
p80211msg_dot11req_mibset_t msg;
p80211item_uint32_t mibitem;
int result;
DBFENTER;
msg.msgcode = DIDmsg_dot11req_mibset;
mibitem.did = did;
mibitem.data = data;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
DBFEXIT;
return result;
}
static int p80211wext_autojoin(wlandevice_t *wlandev)
{
p80211msg_lnxreq_autojoin_t msg;
struct iw_point data;
char ssid[IW_ESSID_MAX_SIZE];
int result;
int err = 0;
DBFENTER;
/* Get ESSID */
result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid);
if (result) {
err = -EFAULT;
goto exit;
}
if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
msg.authtype.data = P80211ENUM_authalg_sharedkey;
else
msg.authtype.data = P80211ENUM_authalg_opensystem;
msg.msgcode = DIDmsg_lnxreq_autojoin;
/* Trim the last '\0' to fit the SSID format */
if (data.length && ssid[data.length-1] == '\0') {
data.length = data.length - 1;
}
memcpy(msg.ssid.data.data, ssid, data.length);
msg.ssid.data.len = data.length;
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
exit:
DBFEXIT;
return err;
}
/* called by /proc/net/wireless */
struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
{
p80211msg_lnxreq_commsquality_t quality;
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
struct iw_statistics* wstats = &wlandev->wstats;
int retval;
DBFENTER;
/* Check */
if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) )
return NULL;
/* XXX Only valid in station mode */
wstats->status = 0;
/* build request message */
quality.msgcode = DIDmsg_lnxreq_commsquality;
quality.dbm.data = P80211ENUM_truth_true;
quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
/* send message to nsd */
if ( wlandev->mlmerequest == NULL )
return NULL;
retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality);
wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */
wstats->qual.level = quality.level.data; /* instant signal level */
wstats->qual.noise = quality.noise.data; /* instant noise level */
#if WIRELESS_EXT > 18
wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
#else
wstats->qual.updated = 7;
#endif
wstats->discard.code = wlandev->rx.decrypt_err;
wstats->discard.nwid = 0;
wstats->discard.misc = 0;
#if WIRELESS_EXT > 11
wstats->discard.fragment = 0; // incomplete fragments
wstats->discard.retries = 0; // tx retries.
wstats->miss.beacon = 0;
#endif
DBFEXIT;
return wstats;
}
static int p80211wext_giwname(netdevice_t *dev,
struct iw_request_info *info,
char *name, char *extra)
{
struct iw_param rate;
int result;
int err = 0;
DBFENTER;
result = p80211wext_giwrate(dev, NULL, &rate, NULL);
if (result) {
err = -EFAULT;
goto exit;
}
switch (rate.value) {
case 1000000:
case 2000000:
strcpy(name, "IEEE 802.11-DS");
break;
case 5500000:
case 11000000:
strcpy(name, "IEEE 802.11-b");
break;
}
exit:
DBFEXIT;
return err;
}
static int p80211wext_giwfreq(netdevice_t *dev,
struct iw_request_info *info,
struct iw_freq *freq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
if (mibitem.data > NUM_CHANNELS) {
err = -EFAULT;
goto exit;
}
/* convert into frequency instead of a channel */
freq->e = 1;
freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000;
exit:
DBFEXIT;
return err;
}
static int p80211wext_siwfreq(netdevice_t *dev,
struct iw_request_info *info,
struct iw_freq *freq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
msg.msgcode = DIDmsg_dot11req_mibset;
mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
mibitem.status = P80211ENUM_msgitem_status_data_ok;
if ( (freq->e == 0) && (freq->m <= 1000) )
mibitem.data = freq->m;
else
mibitem.data = p80211_mhz_to_channel(freq->m);
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
exit:
DBFEXIT;
return err;
}
#if WIRELESS_EXT > 8
static int p80211wext_giwmode(netdevice_t *dev,
struct iw_request_info *info,
__u32 *mode, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
DBFENTER;
switch (wlandev->macmode) {
case WLAN_MACMODE_IBSS_STA:
*mode = IW_MODE_ADHOC;
break;
case WLAN_MACMODE_ESS_STA:
*mode = IW_MODE_INFRA;
break;
case WLAN_MACMODE_ESS_AP:
*mode = IW_MODE_MASTER;
break;
default:
/* Not set yet. */
*mode = IW_MODE_AUTO;
}
DBFEXIT;
return 0;
}
static int p80211wext_siwmode(netdevice_t *dev,
struct iw_request_info *info,
__u32 *mode, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
*mode != IW_MODE_MASTER) {
err = (-EOPNOTSUPP);
goto exit;
}
/* Operation mode is the same with current mode */
if (*mode == wlandev->macmode)
goto exit;
switch (*mode) {
case IW_MODE_ADHOC:
wlandev->macmode = WLAN_MACMODE_IBSS_STA;
break;
case IW_MODE_INFRA:
wlandev->macmode = WLAN_MACMODE_ESS_STA;
break;
case IW_MODE_MASTER:
wlandev->macmode = WLAN_MACMODE_ESS_AP;
break;
default:
/* Not set yet. */
WLAN_LOG_INFO("Operation mode: %d not support\n", *mode);
return -EOPNOTSUPP;
}
/* Set Operation mode to the PORT TYPE RID */
#warning "get rid of p2mib here"
msg.msgcode = DIDmsg_dot11req_mibset;
mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result)
err = -EFAULT;
exit:
DBFEXIT;
return err;
}
static int p80211wext_giwrange(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
struct iw_range *range = (struct iw_range *) extra;
int i, val;
DBFENTER;
// for backward compatability set size & zero everything we don't understand
data->length = sizeof(*range);
memset(range,0,sizeof(*range));
#if WIRELESS_EXT > 9
range->txpower_capa = IW_TXPOW_DBM;
// XXX what about min/max_pmp, min/max_pmt, etc.
#endif
#if WIRELESS_EXT > 10
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 13;
range->retry_capa = IW_RETRY_LIMIT;
range->retry_flags = IW_RETRY_LIMIT;
range->min_retry = 0;
range->max_retry = 255;
#endif /* WIRELESS_EXT > 10 */
#if WIRELESS_EXT > 16
range->event_capa[0] = (IW_EVENT_CAPA_K_0 | //mode/freq/ssid
IW_EVENT_CAPA_MASK(SIOCGIWAP) |
IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
range->event_capa[1] = IW_EVENT_CAPA_K_1; //encode
range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
IW_EVENT_CAPA_MASK(IWEVCUSTOM) );
#endif
range->num_channels = NUM_CHANNELS;
/* XXX need to filter against the regulatory domain &| active set */
val = 0;
for (i = 0; i < NUM_CHANNELS ; i++) {
range->freq[val].i = i + 1;
range->freq[val].m = p80211wext_channel_freq[i] * 100000;
range->freq[val].e = 1;
val++;
}
range->num_frequency = val;
/* Max of /proc/net/wireless */
range->max_qual.qual = 100;
range->max_qual.level = 0;
range->max_qual.noise = 0;
range->sensitivity = 3;
// XXX these need to be nsd-specific!
range->min_rts = 0;
range->max_rts = 2347;
range->min_frag = 256;
range->max_frag = 2346;
range->max_encoding_tokens = NUM_WEPKEYS;
range->num_encoding_sizes = 2;
range->encoding_size[0] = 5;
range->encoding_size[1] = 13;
// XXX what about num_bitrates/throughput?
range->num_bitrates = 0;
/* estimated max throughput */
// XXX need to cap it if we're running at ~2Mbps..
range->throughput = 5500000;
DBFEXIT;
return 0;
}
#endif
static int p80211wext_giwap(netdevice_t *dev,
struct iw_request_info *info,
struct sockaddr *ap_addr, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
DBFENTER;
memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);
ap_addr->sa_family = ARPHRD_ETHER;
DBFEXIT;
return 0;
}
#if WIRELESS_EXT > 8
static int p80211wext_giwencode(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *erq, char *key)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
int err = 0;
int i;
DBFENTER;
if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
erq->flags = IW_ENCODE_ENABLED;
else
erq->flags = IW_ENCODE_DISABLED;
if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
erq->flags |= IW_ENCODE_RESTRICTED;
else
erq->flags |= IW_ENCODE_OPEN;
i = (erq->flags & IW_ENCODE_INDEX) - 1;
if (i == -1)
i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
if ((i < 0) || (i >= NUM_WEPKEYS)) {
err = -EINVAL;
goto exit;
}
erq->flags |= i + 1;
/* copy the key from the driver cache as the keys are read-only MIBs */
erq->length = wlandev->wep_keylens[i];
memcpy(key, wlandev->wep_keys[i], erq->length);
exit:
DBFEXIT;
return err;
}
static int p80211wext_siwencode(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *erq, char *key)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211msg_dot11req_mibset_t msg;
p80211item_pstr32_t pstr;
int err = 0;
int result = 0;
int enable = 0;
int i;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
/* Check the Key index first. */
if((i = (erq->flags & IW_ENCODE_INDEX))) {
if ((i < 1) || (i > NUM_WEPKEYS)) {
err = -EINVAL;
goto exit;
}
else
i--;
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i);
if (result) {
err = -EFAULT;
goto exit;
}
else {
enable = 1;
}
}
else {
// Do not thing when no Key Index
}
/* Check if there is no key information in the iwconfig request */
if((erq->flags & IW_ENCODE_NOKEY) == 0 && enable == 1) {
/*------------------------------------------------------------
* If there is WEP Key for setting, check the Key Information
* and then set it to the firmware.
-------------------------------------------------------------*/
if (erq->length > 0) {
/* copy the key from the driver cache as the keys are read-only MIBs */
wlandev->wep_keylens[i] = erq->length;
memcpy(wlandev->wep_keys[i], key, erq->length);
/* Prepare data struture for p80211req_dorequest. */
memcpy(pstr.data.data, key, erq->length);
pstr.data.len = erq->length;
switch(i)
{
case 0:
pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
break;
case 1:
pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
break;
case 2:
pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
break;
case 3:
pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
break;
default:
err = -EINVAL;
goto exit;
}
msg.msgcode = DIDmsg_dot11req_mibset;
memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
}
}
/* Check the PrivacyInvoked flag */
if (erq->flags & IW_ENCODE_DISABLED) {
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
}
else if((erq->flags & IW_ENCODE_ENABLED) || enable == 1) {
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
}
if (result) {
err = -EFAULT;
goto exit;
}
/* Check the ExcludeUnencrypted flag */
if (erq->flags & IW_ENCODE_RESTRICTED) {
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
}
else if (erq->flags & IW_ENCODE_OPEN) {
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
}
if (result) {
err = -EFAULT;
goto exit;
}
exit:
DBFEXIT;
return err;
}
static int p80211wext_giwessid(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *data, char *essid)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
DBFENTER;
if (wlandev->ssid.len) {
data->length = wlandev->ssid.len;
data->flags = 1;
memcpy(essid, wlandev->ssid.data, data->length);
essid[data->length] = 0;
#if (WIRELESS_EXT < 21)
data->length++;
#endif
} else {
memset(essid, 0, sizeof(wlandev->ssid.data));
data->length = 0;
data->flags = 0;
}
DBFEXIT;
return 0;
}
static int p80211wext_siwessid(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *data, char *essid)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211msg_lnxreq_autojoin_t msg;
int result;
int err = 0;
int length = data->length;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
msg.authtype.data = P80211ENUM_authalg_sharedkey;
else
msg.authtype.data = P80211ENUM_authalg_opensystem;
msg.msgcode = DIDmsg_lnxreq_autojoin;
#if (WIRELESS_EXT < 21)
if (length) length--;
#endif
/* Trim the last '\0' to fit the SSID format */
if (length && essid[length-1] == '\0') {
length--;
}
memcpy(msg.ssid.data.data, essid, length);
msg.ssid.data.len = length;
WLAN_LOG_DEBUG(1,"autojoin_ssid for %s \n",essid);
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result);
if (result) {
err = -EFAULT;
goto exit;
}
exit:
DBFEXIT;
return err;
}
static int p80211wext_siwcommit(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *data, char *essid)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
int err = 0;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
/* Auto Join */
err = p80211wext_autojoin(wlandev);
exit:
DBFEXIT;
return err;
}
static int p80211wext_giwrate(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
rrq->fixed = 0; /* can it change? */
rrq->disabled = 0;
rrq->value = 0;
#define HFA384x_RATEBIT_1 ((UINT16)1)
#define HFA384x_RATEBIT_2 ((UINT16)2)
#define HFA384x_RATEBIT_5dot5 ((UINT16)4)
#define HFA384x_RATEBIT_11 ((UINT16)8)
switch (mibitem.data) {
case HFA384x_RATEBIT_1:
rrq->value = 1000000;
break;
case HFA384x_RATEBIT_2:
rrq->value = 2000000;
break;
case HFA384x_RATEBIT_5dot5:
rrq->value = 5500000;
break;
case HFA384x_RATEBIT_11:
rrq->value = 11000000;
break;
default:
err = -EINVAL;
}
exit:
DBFEXIT;
return err;
}
static int p80211wext_giwrts(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rts, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
rts->value = mibitem.data;
rts->disabled = (rts->value == 2347);
rts->fixed = 1;
exit:
DBFEXIT;
return err;
}
static int p80211wext_siwrts(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rts, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
if (rts->disabled)
mibitem.data = 2347;
else
mibitem.data = rts->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
exit:
DBFEXIT;
return err;
}
static int p80211wext_giwfrag(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *frag, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
frag->value = mibitem.data;
frag->disabled = (frag->value == 2346);
frag->fixed = 1;
exit:
DBFEXIT;
return err;
}
static int p80211wext_siwfrag(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *frag, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
msg.msgcode = DIDmsg_dot11req_mibset;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
if (frag->disabled)
mibitem.data = 2346;
else
mibitem.data = frag->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
exit:
DBFEXIT;
return err;
}
#endif /* WIRELESS_EXT > 8 */
#if WIRELESS_EXT > 10
#ifndef IW_RETRY_LONG
#define IW_RETRY_LONG IW_RETRY_MAX
#endif
#ifndef IW_RETRY_SHORT
#define IW_RETRY_SHORT IW_RETRY_MIN
#endif
static int p80211wext_giwretry(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
UINT16 shortretry, longretry, lifetime;
DBFENTER;
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
shortretry = mibitem.data;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
longretry = mibitem.data;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
lifetime = mibitem.data;
rrq->disabled = 0;
if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
rrq->flags = IW_RETRY_LIFETIME;
rrq->value = lifetime * 1024;
} else {
if (rrq->flags & IW_RETRY_LONG) {
rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
rrq->value = longretry;
} else {
rrq->flags = IW_RETRY_LIMIT;
rrq->value = shortretry;
if (shortretry != longretry)
rrq->flags |= IW_RETRY_SHORT;
}
}
exit:
DBFEXIT;
return err;
}
static int p80211wext_siwretry(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
if (rrq->disabled) {
err = -EINVAL;
goto exit;
}
msg.msgcode = DIDmsg_dot11req_mibset;
if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
mibitem.data = rrq->value /= 1024;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
} else {
if (rrq->flags & IW_RETRY_LONG) {
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
mibitem.data = rrq->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
}
if (rrq->flags & IW_RETRY_SHORT) {
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
mibitem.data = rrq->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
}
}
exit:
DBFEXIT;
return err;
}
#endif /* WIRELESS_EXT > 10 */
#if WIRELESS_EXT > 9
static int p80211wext_siwtxpow(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
msg.msgcode = DIDmsg_dot11req_mibset;
switch (rrq->value) {
case 1 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1; break;
case 2 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2; break;
case 3 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3; break;
case 4 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4; break;
case 5 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5; break;
case 6 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6; break;
case 7 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7; break;
case 8 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;
default: mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;
}
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
exit:
DBFEXIT;
return err;
}
static int p80211wext_giwtxpow(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211item_uint32_t mibitem;
p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
DBFENTER;
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
// XXX handle OFF by setting disabled = 1;
rrq->flags = 0; // IW_TXPOW_DBM;
rrq->disabled = 0;
rrq->fixed = 0;
rrq->value = mibitem.data;
exit:
DBFEXIT;
return err;
}
#endif /* WIRELESS_EXT > 9 */
static int p80211wext_siwspy(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
struct sockaddr address[IW_MAX_SPY];
int number = srq->length;
int i;
DBFENTER;
/* Copy the data from the input buffer */
memcpy(address, extra, sizeof(struct sockaddr)*number);
wlandev->spy_number = 0;
if (number > 0) {
/* extract the addresses */
for (i = 0; i < number; i++) {
memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN);
}
/* reset stats */
memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
/* set number of addresses */
wlandev->spy_number = number;
}
DBFEXIT;
return 0;
}
/* jkriegl: from orinoco, modified */
static int p80211wext_giwspy(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
struct sockaddr address[IW_MAX_SPY];
struct iw_quality spy_stat[IW_MAX_SPY];
int number;
int i;
DBFENTER;
number = wlandev->spy_number;
if (number > 0) {
/* populate address and spy struct's */
for (i = 0; i < number; i++) {
memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN);
address[i].sa_family = AF_UNIX;
memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality));
}
/* reset update flag */
for (i=0; i < number; i++)
wlandev->spy_stat[i].updated = 0;
}
/* push stuff to user space */
srq->length = number;
memcpy(extra, address, sizeof(struct sockaddr)*number);
memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number);
DBFEXIT;
return 0;
}
static int prism2_result2err (int prism2_result)
{
int err = 0;
switch (prism2_result) {
case P80211ENUM_resultcode_invalid_parameters:
err = -EINVAL;
break;
case P80211ENUM_resultcode_implementation_failure:
err = -EIO;
break;
case P80211ENUM_resultcode_not_supported:
err = -EOPNOTSUPP;
break;
default:
err = 0;
break;
}
return err;
}
#if WIRELESS_EXT > 13
static int p80211wext_siwscan(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211msg_dot11req_scan_t msg;
int result;
int err = 0;
int i = 0;
DBFENTER;
if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
WLAN_LOG_ERROR("Can't scan in AP mode\n");
err = (-EOPNOTSUPP);
goto exit;
}
memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t));
msg.msgcode = DIDmsg_dot11req_scan;
msg.bsstype.data = P80211ENUM_bsstype_any;
memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t));
msg.bssid.data.len = 6;
msg.scantype.data = P80211ENUM_scantype_active;
msg.probedelay.data = 0;
for (i = 1; i <= 14; i++)
msg.channellist.data.data[i-1] = i;
msg.channellist.data.len = 14;
msg.maxchanneltime.data = 250;
msg.minchanneltime.data = 200;
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if (result)
err = prism2_result2err (msg.resultcode.data);
exit:
DBFEXIT;
return err;
}
/* Helper to translate scan into Wireless Extensions scan results.
* Inspired by the prism54 code, which was in turn inspired by the
* airo driver code.
*/
static char *
wext_translate_bss(struct iw_request_info *info, char *current_ev,
char *end_buf, p80211msg_dot11req_scan_results_t *bss)
{
struct iw_event iwe; /* Temporary buffer */
/* The first entry must be the MAC address */
memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP;
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
/* The following entries will be displayed in the same order we give them */
/* The ESSID. */
if (bss->ssid.data.len > 0) {
char essid[IW_ESSID_MAX_SIZE + 1];
int size;
size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len);
memset(&essid, 0, sizeof (essid));
memcpy(&essid, bss->ssid.data.data, size);
WLAN_LOG_DEBUG(1, " essid size = %d\n", size);
iwe.u.data.length = size;
iwe.u.data.flags = 1;
iwe.cmd = SIOCGIWESSID;
current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &essid[0]);
WLAN_LOG_DEBUG(1, " essid size OK.\n");
}
switch (bss->bsstype.data) {
case P80211ENUM_bsstype_infrastructure:
iwe.u.mode = IW_MODE_MASTER;
break;
case P80211ENUM_bsstype_independent:
iwe.u.mode = IW_MODE_ADHOC;
break;
default:
iwe.u.mode = 0;
break;
}
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
/* Encryption capability */
if (bss->privacy.data == P80211ENUM_truth_true)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
iwe.cmd = SIOCGIWENCODE;
current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */
iwe.u.freq.m = bss->dschannel.data;
iwe.u.freq.e = 0;
iwe.cmd = SIOCGIWFREQ;
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.u.qual.level = bss->signal.data;
iwe.u.qual.noise = bss->noise.data;
/* do a simple SNR for quality */
iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data);
iwe.cmd = IWEVQUAL;
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
return current_ev;
}
static int p80211wext_giwscan(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
p80211msg_dot11req_scan_results_t msg;
int result = 0;
int err = 0;
int i = 0;
int scan_good = 0;
char *current_ev = extra;
DBFENTER;
/* Since wireless tools doesn't really have a way of passing how
* many scan results results there were back here, keep grabbing them
* until we fail.
*/
do {
memset(&msg, 0, sizeof(msg));
msg.msgcode = DIDmsg_dot11req_scan_results;
msg.bssindex.data = i;
result = p80211req_dorequest(wlandev, (UINT8*)&msg);
if ((result != 0) ||
(msg.resultcode.data != P80211ENUM_resultcode_success)) {
break;
}
current_ev = wext_translate_bss(info, current_ev, extra + IW_SCAN_MAX_DATA, &msg);
scan_good = 1;
i++;
} while (i < IW_MAX_AP);
srq->length = (current_ev - extra);
srq->flags = 0; /* todo */
if (result && !scan_good)
err = prism2_result2err (msg.resultcode.data);
DBFEXIT;
return err;
}
#endif
/*****************************************************/
//extra wireless extensions stuff to support NetworkManager (I hope)
#if WIRELESS_EXT > 17
/* SIOCSIWENCODEEXT */
static int p80211wext_set_encodeext(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
p80211msg_dot11req_mibset_t msg;
p80211item_pstr32_t *pstr;
int result = 0;
struct iw_point *encoding = &wrqu->encoding;
int idx = encoding->flags & IW_ENCODE_INDEX;
WLAN_LOG_DEBUG(1,"set_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
if ( ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY ) {
// set default key ? I'm not sure if this the the correct thing to do here
if ( idx ) {
if (idx < 1 || idx > NUM_WEPKEYS) {
return -EINVAL;
} else
idx--;
}
WLAN_LOG_DEBUG(1,"setting default key (%d)\n",idx);
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx);
if ( result )
return -EFAULT;
}
if ( ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY ) {
if ( ! ext->alg & IW_ENCODE_ALG_WEP) {
WLAN_LOG_DEBUG(1,"asked to set a non wep key :(");
return -EINVAL;
}
if (idx) {
if (idx <1 || idx > NUM_WEPKEYS)
return -EINVAL;
else
idx--;
}
WLAN_LOG_DEBUG(1,"Set WEP key (%d)\n",idx);
wlandev->wep_keylens[idx] = ext->key_len;
memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
memset( &msg,0,sizeof(msg));
pstr = (p80211item_pstr32_t*)&msg.mibattribute.data;
memcpy(pstr->data.data, ext->key,ext->key_len);
pstr->data.len = ext->key_len;
switch (idx) {
case 0:
pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
break;
case 1:
pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
break;
case 2:
pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
break;
case 3:
pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
break;
default:
break;
}
msg.msgcode = DIDmsg_dot11req_mibset;
result = p80211req_dorequest(wlandev,(UINT8*)&msg);
WLAN_LOG_DEBUG(1,"result (%d)\n",result);
}
return result;
}
/* SIOCGIWENCODEEXT */
static int p80211wext_get_encodeext(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
struct iw_point *encoding = &wrqu->encoding;
int result = 0;
int max_len;
int idx;
DBFENTER;
WLAN_LOG_DEBUG(1,"get_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
max_len = encoding->length - sizeof(*ext);
if ( max_len <= 0) {
WLAN_LOG_DEBUG(1,"get_encodeext max_len [%d] invalid\n",max_len);
result = -EINVAL;
goto exit;
}
idx = encoding->flags & IW_ENCODE_INDEX;
WLAN_LOG_DEBUG(1,"get_encode_ext index [%d]\n",idx);
if (idx) {
if (idx < 1 || idx > NUM_WEPKEYS ) {
WLAN_LOG_DEBUG(1,"get_encode_ext invalid key index [%d]\n",idx);
result = -EINVAL;
goto exit;
}
idx--;
} else {
/* default key ? not sure what to do */
/* will just use key[0] for now ! FIX ME */
}
encoding->flags = idx + 1;
memset(ext,0,sizeof(*ext));
ext->alg = IW_ENCODE_ALG_WEP;
ext->key_len = wlandev->wep_keylens[idx];
memcpy( ext->key, wlandev->wep_keys[idx] , ext->key_len );
encoding->flags |= IW_ENCODE_ENABLED;
exit:
DBFEXIT;
return result;
}
/* SIOCSIWAUTH */
static int p80211_wext_set_iwauth (struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
struct iw_param *param = &wrqu->param;
int result =0;
WLAN_LOG_DEBUG(1,"set_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_DROP_UNENCRYPTED:
WLAN_LOG_DEBUG(1,"drop_unencrypted %d\n",param->value);
if (param->value)
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
else
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
break;
case IW_AUTH_PRIVACY_INVOKED:
WLAN_LOG_DEBUG(1,"privacy invoked %d\n",param->value);
if ( param->value)
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
else
result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
break;
case IW_AUTH_80211_AUTH_ALG:
if ( param->value & IW_AUTH_ALG_OPEN_SYSTEM ) {
WLAN_LOG_DEBUG(1,"set open_system\n");
wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
} else if ( param->value & IW_AUTH_ALG_SHARED_KEY) {
WLAN_LOG_DEBUG(1,"set shared key\n");
wlandev->hostwep |= HOSTWEP_SHAREDKEY;
} else {
/* don't know what to do know :( */
WLAN_LOG_DEBUG(1,"unknown AUTH_ALG (%d)\n",param->value);
result = -EINVAL;
}
break;
default:
break;
}
return result;
}
/* SIOCSIWAUTH */
static int p80211_wext_get_iwauth (struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
struct iw_param *param = &wrqu->param;
int result =0;
WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_DROP_UNENCRYPTED:
param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0;
break;
case IW_AUTH_PRIVACY_INVOKED:
param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0;
break;
case IW_AUTH_80211_AUTH_ALG:
param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM;
break;
default:
break;
}
return result;
}
#endif
/*****************************************************/
/*
typedef int (*iw_handler)(netdevice_t *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
*/
#if WIRELESS_EXT > 12
static iw_handler p80211wext_handlers[] = {
(iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */
(iw_handler) p80211wext_giwname, /* SIOCGIWNAME */
(iw_handler) NULL, /* SIOCSIWNWID */
(iw_handler) NULL, /* SIOCGIWNWID */
(iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */
(iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */
(iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */
(iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */
(iw_handler) NULL, /* SIOCSIWSENS */
(iw_handler) NULL, /* SIOCGIWSENS */
(iw_handler) NULL, /* not used */ /* SIOCSIWRANGE */
(iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */
(iw_handler) NULL, /* not used */ /* SIOCSIWPRIV */
(iw_handler) NULL, /* kernel code */ /* SIOCGIWPRIV */
(iw_handler) NULL, /* not used */ /* SIOCSIWSTATS */
(iw_handler) NULL, /* kernel code */ /* SIOCGIWSTATS */
(iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */
(iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCSIWAP */
(iw_handler) p80211wext_giwap, /* SIOCGIWAP */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCGIWAPLIST */
#if WIRELESS_EXT > 13
(iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */
(iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */
#else /* WIRELESS_EXT > 13 */
(iw_handler) NULL, /* null */ /* SIOCSIWSCAN */
(iw_handler) NULL, /* null */ /* SIOCGIWSCAN */
#endif /* WIRELESS_EXT > 13 */
(iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */
(iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */
(iw_handler) NULL, /* SIOCSIWNICKN */
(iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCSIWRATE */
(iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */
(iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */
(iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */
(iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */
(iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */
(iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */
(iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */
(iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */
(iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */
(iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */
(iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
#if WIRELESS_EXT > 17
/* WPA operations */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCSIWGENIE set generic IE */
(iw_handler) NULL, /* SIOCGIWGENIE get generic IE */
(iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH set authentication mode params */
(iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH get authentication mode params */
(iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT set encoding token & mode */
(iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT get encoding token & mode */
(iw_handler) NULL, /* SIOCSIWPMKSA PMKSA cache operation */
#endif
};
struct iw_handler_def p80211wext_handler_def = {
.num_standard = sizeof(p80211wext_handlers) / sizeof(iw_handler),
.num_private = 0,
.num_private_args = 0,
.standard = p80211wext_handlers,
.private = NULL,
.private_args = NULL,
#if WIRELESS_EXT > 16
.get_wireless_stats = p80211wext_get_wireless_stats
#endif
};
#endif
/* wireless extensions' ioctls */
int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
{
wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
#if WIRELESS_EXT < 13
struct iwreq *iwr = (struct iwreq*)ifr;
#endif
p80211item_uint32_t mibitem;
int err = 0;
DBFENTER;
mibitem.status = P80211ENUM_msgitem_status_data_ok;
if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
err = -ENODEV;
goto exit;
}
WLAN_LOG_DEBUG(1, "Received wireless extension ioctl #%d.\n", cmd);
switch (cmd) {
#if WIRELESS_EXT < 13
case SIOCSIWNAME: /* unused */
err = (-EOPNOTSUPP);
break;
case SIOCGIWNAME: /* get name == wireless protocol */
err = p80211wext_giwname(dev, NULL, (char *) &iwr->u, NULL);
break;
case SIOCSIWNWID:
case SIOCGIWNWID:
err = (-EOPNOTSUPP);
break;
case SIOCSIWFREQ: /* set channel */
err = p80211wext_siwfreq(dev, NULL, &(iwr->u.freq), NULL);
break;
case SIOCGIWFREQ: /* get channel */
err = p80211wext_giwfreq(dev, NULL, &(iwr->u.freq), NULL);
break;
case SIOCSIWRANGE:
case SIOCSIWPRIV:
case SIOCSIWAP: /* set access point MAC addresses (BSSID) */
err = (-EOPNOTSUPP);
break;
case SIOCGIWAP: /* get access point MAC addresses (BSSID) */
err = p80211wext_giwap(dev, NULL, &(iwr->u.ap_addr), NULL);
break;
#if WIRELESS_EXT > 8
case SIOCSIWMODE: /* set operation mode */
case SIOCSIWESSID: /* set SSID (network name) */
case SIOCSIWRATE: /* set default bit rate (bps) */
err = (-EOPNOTSUPP);
break;
case SIOCGIWMODE: /* get operation mode */
err = p80211wext_giwmode(dev, NULL, &iwr->u.mode, NULL);
break;
case SIOCGIWNICKN: /* get node name/nickname */
case SIOCGIWESSID: /* get SSID */
if(iwr->u.essid.pointer) {
char ssid[IW_ESSID_MAX_SIZE+1];
memset(ssid, 0, sizeof(ssid));
err = p80211wext_giwessid(dev, NULL, &iwr->u.essid, ssid);
if(copy_to_user(iwr->u.essid.pointer, ssid, sizeof(ssid)))
err = (-EFAULT);
}
break;
case SIOCGIWRATE:
err = p80211wext_giwrate(dev, NULL, &iwr->u.bitrate, NULL);
break;
case SIOCGIWRTS:
err = p80211wext_giwrts(dev, NULL, &iwr->u.rts, NULL);
break;
case SIOCGIWFRAG:
err = p80211wext_giwfrag(dev, NULL, &iwr->u.rts, NULL);
break;
case SIOCGIWENCODE:
if (!capable(CAP_NET_ADMIN))
err = -EPERM;
else if (iwr->u.encoding.pointer) {
char keybuf[MAX_KEYLEN];
err = p80211wext_giwencode(dev, NULL,
&iwr->u.encoding, keybuf);
if (copy_to_user(iwr->u.encoding.pointer, keybuf,
iwr->u.encoding.length))
err = -EFAULT;
}
break;
case SIOCGIWAPLIST:
case SIOCSIWRTS:
case SIOCSIWFRAG:
case SIOCSIWSENS:
case SIOCGIWSENS:
case SIOCSIWNICKN: /* set node name/nickname */
case SIOCSIWENCODE: /* set encoding token & mode */
case SIOCSIWSPY:
case SIOCGIWSPY:
case SIOCSIWPOWER:
case SIOCGIWPOWER:
case SIOCGIWPRIV:
err = (-EOPNOTSUPP);
break;
case SIOCGIWRANGE:
if(iwr->u.data.pointer != NULL) {
struct iw_range range;
err = p80211wext_giwrange(dev, NULL, &iwr->u.data,
(char *) &range);
/* Push that up to the caller */
if (copy_to_user(iwr->u.data.pointer, &range, sizeof(range)))
err = -EFAULT;
}
break;
#endif /* WIRELESS_EXT > 8 */
#if WIRELESS_EXT > 9
case SIOCSIWTXPOW:
err = (-EOPNOTSUPP);
break;
case SIOCGIWTXPOW:
err = p80211wext_giwtxpow(dev, NULL, &iwr->u.txpower, NULL);
break;
#endif /* WIRELESS_EXT > 9 */
#if WIRELESS_EXT > 10
case SIOCSIWRETRY:
err = (-EOPNOTSUPP);
break;
case SIOCGIWRETRY:
err = p80211wext_giwretry(dev, NULL, &iwr->u.retry, NULL);
break;
#endif /* WIRELESS_EXT > 10 */
#endif /* WIRELESS_EXT <= 12 */
default:
err = (-EOPNOTSUPP);
break;
}
exit:
DBFEXIT;
return (err);
}
int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
{
union iwreq_data data;
DBFENTER;
#if WIRELESS_EXT > 13
/* Send the association state first */
data.ap_addr.sa_family = ARPHRD_ETHER;
if (assoc) {
memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN);
} else {
memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN);
}
if (wlan_wext_write)
wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
if (!assoc) goto done;
// XXX send association data, like IEs, etc etc.
#endif
done:
DBFEXIT;
return 0;
}
#endif /* compatibility to wireless extensions */
#define WLAN_HOSTIF WLAN_PCMCIA
#include "hfa384x.c"
#include "prism2mgmt.c"
#include "prism2mib.c"
#include "prism2sta.c"
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21) )
#if (WLAN_CPU_FAMILY == WLAN_Ix86)
#ifndef CONFIG_ISA
#warning "You may need to enable ISA support in your kernel."
#endif
#endif
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
static u_int irq_mask = 0xdeb8; /* Interrupt mask */
static int irq_list[4] = { -1 }; /* Interrupt list */
#endif
static u_int prism2_ignorevcc=1; /* Boolean, if set, we
* ignore what the Vcc
* is set to and what the CIS
* says.
*/
module_param( prism2_ignorevcc, int, 0644);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))
static int numlist = 4;
module_param_array(irq_list, int, numlist, 0444);
#else
module_param_array(irq_list, int, NULL, 0444);
#endif
module_param( irq_mask, int, 0644);
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
static int prism2_cs_suspend(struct pcmcia_device *pdev);
static int prism2_cs_resume(struct pcmcia_device *pdev);
static void prism2_cs_remove(struct pcmcia_device *pdev);
static int prism2_cs_probe(struct pcmcia_device *pdev);
#else
dev_link_t *prism2sta_attach(void);
static void prism2sta_detach(dev_link_t *link);
static void prism2sta_config(dev_link_t *link);
static void prism2sta_release(u_long arg);
static int prism2sta_event (event_t event, int priority, event_callback_args_t *args);
static dev_link_t *dev_list = NULL; /* head of instance list */
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
/*----------------------------------------------------------------
* cs_error
*
* Utility function to print card services error messages.
*
* Arguments:
* handle client handle identifying this CS client
* func CS function number that generated the error
* ret CS function return code
*
* Returns:
* nothing
* Side effects:
*
* Call context:
* process thread
* interrupt
----------------------------------------------------------------*/
static void cs_error(client_handle_t handle, int func, int ret)
{
#if (defined(CS_RELEASE_CODE) && (CS_RELEASE_CODE < 0x2911))
CardServices(ReportError, dev_info, (void *)func, (void *)ret);
#else
error_info_t err = { func, ret };
pcmcia_report_error(handle, &err);
#endif
}
#else // kernel_version
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
static struct pcmcia_device_id prism2_cs_ids[] = {
PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), // Intersil PRISM2 Reference Design 11Mb/s 802.11b WLAN Card
PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), // Compaq WL100/200 11Mb/s 802.11b WLAN Card
PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), // Compaq iPaq HNW-100 11Mb/s 802.11b WLAN Card
PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), // Samsung SWL2000-N 11Mb/s 802.11b WLAN Card
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), // Z-Com XI300 11Mb/s 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), // ZoomAir 4100 11Mb/s 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), // Linksys WPC11 11Mbps 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID123("Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02", 0xe6ec52ce, 0x8649af2, 0x4b74baa0), // Addtron AWP-100 11Mbps 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID123("D", "Link DWL-650 11Mbps WLAN Card", "Version 01.02", 0x71b18589, 0xb6f1b0ab, 0x4b74baa0), // D-Link DWL-650 11Mbps 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID123("SMC", "SMC2632W", "Version 01.02", 0xc4f8b18b, 0x474a1f2a, 0x4b74baa0), // SMC 2632W 11Mbps 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID1234("Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P", "Eval-RevA", 0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e), // BroMax Freeport 11Mbps 802.11b WLAN Card (Prism 2.5)
PCMCIA_DEVICE_PROD_ID123("U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02", 0xc7b8df9d, 0x1700d087, 0x4b74baa0), // U.S. Robotics IEEE 802.11b PC-CARD
PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146), // Level-One WPC-0100
PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), // Bromax OEM 11Mbps 802.11b WLAN Card (Prism 2.5)
PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), // Bromax OEM 11Mbps 802.11b WLAN Card (Prism 3)
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), // corega K.K. Wireless LAN PCC-11
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), // corega K.K. Wireless LAN PCCA-11
PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), // CONTEC FLEXSCAN/FX-DDS110-PCC
PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), // PLANEX GeoWave/GW-NS110
PCMCIA_DEVICE_PROD_ID123("OEM", "PRISM2 IEEE 802.11 PC-Card", "Version 01.02", 0xfea54c90, 0x48f2bdd6, 0x4b74baa0), // Ambicom WL1100 11Mbps 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID123("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", "Version 01.02", 0x7e3b326a, 0x49893e92, 0x4b74baa0), // LeArtery SYNCBYAIR 11Mbps 802.11b WLAN Card
PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), // Intermec MobileLAN 11Mbps 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID123("NETGEAR MA401 Wireless PC", "Card", "Version 01.00", 0xa37434e9, 0x9762e8f1, 0xa57adb8c), // NETGEAR MA401 11Mbps 802.11 WLAN Card
PCMCIA_DEVICE_PROD_ID1234("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", "Eval-RevA", 0x4b801a17, 0xf222ec2d, 0x630d52b2, 0xc23adc0e), // Intersil PRISM Freedom 11mbps 802.11 WLAN Card
PCMCIA_DEVICE_PROD_ID123("OTC", "Wireless AirEZY 2411-PCC WLAN Card", "Version 01.02", 0x4ac44287, 0x235a6bed, 0x4b74baa0), // OTC Wireless AirEZY 2411-PCC 11Mbps 802.11 WLAN Card
PCMCIA_DEVICE_PROD_ID1234("802.11", "11Mbps Wireless LAN Card", "v08C1", "" , 0xb67a610e, 0x655aa7b7, 0x264b451a, 0x0), // Dynalink L11HDT 11Mbps 802.11 WLAN Card
PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), // Dynalink L11HDT 11Mbps 802.11 WLAN Card
PCMCIA_DEVICE_PROD_ID12("PROXIM", "RangeLAN-DS/LAN PC CARD", 0xc6536a5e, 0x3f35797d), // PROXIM RangeLAN-DS/LAN PC CARD
PCMCIA_DEVICE_PROD_ID1234("ACTIONTEC", "PRISM Wireless LAN PC Card", "0381", "RevA", 0x393089da, 0xa71e69d5, 0x90471fa9, 0x57a66194), // ACTIONTEC PRISM Wireless LAN PC Card
PCMCIA_DEVICE_MANF_CARD(0x1668, 0x0101), // ACTIONTEC PRISM Wireless LAN PC Card
PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), // 3Com AirConnect 3CRWE737A
PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE777A AirConnect Wireless LAN PCI Card" , 0x41240e5b, 0xafc7c33e), // 3Com AirConnect 3CRWE777A
PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), // ASUS WL-100 802.11b WLAN PC Card
PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), // ASUS WL-110 802.11b WLAN CF Card
PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), // BUFFALO WLI-CF-S11G 802.11b WLAN Card
PCMCIA_DEVICE_PROD_ID1234("The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P", "RevA", 0xa5f472c2, 0x9c05598d, 0xc9049a39, 0x57a66194), // Linksys WCF11 11Mbps 802.11b WLAN Card (Prism 2.5)
PCMCIA_DEVICE_PROD_ID1234("Linksys", "Wireless CompactFlash Card", "", "", 0x733cc81, 0xc52f395, 0x0, 0x0), // Linksys WCF12 11Mbps 802.11b WLAN Card (Prism 3)
PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), // Linksys WCF12 11Mbps 802.11b WLAN Card (Prism 3)
PCMCIA_DEVICE_PROD_ID1234("NETGEAR MA401RA Wireless PC", "Card", "ISL37300P", "Eval-RevA", 0x306467f, 0x9762e8f1, 0xc9049a39, 0xc23adc0e), // NETGEAR MA401RA 11Mbps 802.11 WLAN Card
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), // D-Link DCF-660W 11Mbps 802.11b WLAN Card
PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001), // Microsoft Wireless Notebook Adapter MN-520
PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), // AnyPoint(TM) Wireless II PC Card
PCMCIA_DEVICE_PROD_ID1234("D", "Link DRC-650 11Mbps WLAN Card", "Version 01.02", "" , 0x71b18589, 0xf144e3ac, 0x4b74baa0, 0x0), // D-Link DRC-650 802.11b WLAN Card
PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), // Adaptec AWN-8030
PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7110), // D-Link DWL-650 rev P 802.11b WLAN card
// PCMCIA_DEVICE_PROD_ID1234("D-Link", "DWL-650 Wireless PC Card RevP", "ISL37101P-10", "A3", 0x1a424a1c, 0x6ea57632, 0xdd97a26b, 0x56b21f52), // D-Link DWL-650 rev P 802.11b WLAN card
PCMCIA_DEVICE_PROD_ID123("INTERSIL", "I-GATE 11M PC Card / PC Card plus", "Version 01.02", 0x74c5e40d, 0x8304ff77, 0x4b74baa0), // I-Gate 11M PC Card
PCMCIA_DEVICE_PROD_ID1234("BENQ", "AWL100 PCMCIA ADAPTER", "ISL37300P", "Eval-RevA", 0x35dadc74, 0x1f7fedb, 0xc9049a39, 0xc23adc0e), // benQ AWL100 802.11b WLAN Card
PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), // benQ AWL100 802.11b WLAN Card
// PCMCIA_DEVICE_PROD_ID1("INTERSIL", 0x74c5e40d), // Intersil Prism 2 card
// PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), // Intersil Prism 2 card
PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, prism2_cs_ids);
#endif
static struct pcmcia_driver prism2_cs_driver = {
.drv = {
.name = "prism2_cs",
},
.owner = THIS_MODULE,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
.suspend = prism2_cs_suspend,
.resume = prism2_cs_resume,
.remove = prism2_cs_remove,
.probe = prism2_cs_probe,
.id_table = prism2_cs_ids,
#else
.attach = prism2sta_attach,
.detach = prism2sta_detach,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
.id_table = prism2_cs_ids,
.event = prism2sta_event,
#endif // > 2.6.12
#endif // <= 2.6.15
};
#endif /* kernel_version */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define CFG_CHECK(fn, retf) \
do { int ret = (retf); \
if (ret != 0) { \
WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
cs_error(pdev, fn, ret); \
goto next_entry; \
} \
} while (0)
static void prism2_cs_remove(struct pcmcia_device *pdev)
{
struct wlandevice *wlandev;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
dev_link_t *link = dev_to_instance(pdev);
#endif
DBFENTER;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
wlandev = pdev->priv;
#else
wlandev = link->priv;
#endif
if (wlandev) {
p80211netdev_hwremoved(wlandev);
unregister_wlandev(wlandev);
wlan_unsetup(wlandev);
if (wlandev->priv) {
hfa384x_t *hw = wlandev->priv;
wlandev->priv = NULL;
if (hw) {
hfa384x_destroy(hw);
kfree(hw);
}
}
kfree(wlandev);
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->priv = NULL;
pcmcia_disable_device(pdev);
#else
if (link->state & DEV_CONFIG) {
if (link->win)
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
}
link->priv = NULL;
kfree(link);
#endif
DBFEXIT;
return;
}
static int prism2_cs_suspend(struct pcmcia_device *pdev)
{
struct wlandevice *wlandev;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
dev_link_t *link = dev_to_instance(pdev);
#endif
DBFENTER;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
wlandev = pdev->priv;
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
#else
wlandev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
pcmcia_release_configuration(link->handle);
}
#endif
DBFEXIT;
return 0;
}
static int prism2_cs_resume(struct pcmcia_device *pdev)
{
struct wlandevice *wlandev;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
dev_link_t *link = dev_to_instance(pdev);
#endif
DBFENTER;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
wlandev = pdev->priv;
// XXX do something here?
#else
wlandev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
// XXX do something here?
}
#endif
DBFEXIT;
return 0;
}
static int prism2_cs_probe(struct pcmcia_device *pdev)
{
int rval = 0;
struct wlandevice *wlandev = NULL;
hfa384x_t *hw = NULL;
config_info_t socketconf;
cisparse_t *parse = NULL;
tuple_t tuple;
uint8_t buf[64];
int last_fn, last_ret;
cistpl_cftable_entry_t dflt = { 0 };
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
dev_link_t *link;
#endif
DBFENTER;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
/* Set up interrupt type */
pdev->conf.IntType = INT_MEMORY_AND_IO;
#else
link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
if (link == NULL)
return -ENOMEM;
memset(link, 0, sizeof(dev_link_t));
link->conf.Vcc = 33;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = pdev;
pdev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
#endif
// VCC crap?
parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
wlandev = create_wlan();
if (!wlandev || !parse) {
WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
rval = -EIO;
goto failed;
}
hw = wlandev->priv;
if ( wlan_setup(wlandev) != 0 ) {
WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
rval = -EIO;
goto failed;
}
/* Initialize the hw struct for now */
hfa384x_create(hw, 0, 0, NULL);
hw->wlandev = wlandev;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
hw->pdev = pdev;
pdev->priv = wlandev;
#else
hw->link = link;
link->priv = wlandev;
#endif
tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(pdev, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(pdev, &tuple, parse));
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->conf.ConfigBase = parse->config.base;
pdev->conf.Present = parse->config.rmask[0];
#else
link->conf.ConfigBase = parse->config.base;
link->conf.Present = parse->config.rmask[0];
link->conf.Vcc = socketconf.Vcc;
#endif
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(pdev, &socketconf));
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
for (;;) {
cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
CFG_CHECK(GetTupleData,
pcmcia_get_tuple_data(pdev, &tuple));
CFG_CHECK(ParseTuple,
pcmcia_parse_tuple(pdev, &tuple, parse));
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
dflt = *cfg;
if (cfg->index == 0)
goto next_entry;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->conf.ConfigIndex = cfg->index;
#else
link->conf.ConfigIndex = cfg->index;
#endif
/* Does this card need audio output? */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->conf.Attributes |= CONF_ENABLE_SPKR;
pdev->conf.Status = CCSR_AUDIO_ENA;
#else
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
#endif
}
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (socketconf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
10000 && !prism2_ignorevcc) {
WLAN_LOG_DEBUG(1, " Vcc mismatch - skipping"
" this entry\n");
goto next_entry;
}
} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (socketconf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
10000 && !prism2_ignorevcc) {
WLAN_LOG_DEBUG(1, " Vcc (default) mismatch "
"- skipping this entry\n");
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
#else
link->conf.Vpp1 = link->conf.Vpp2 =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
#endif
} else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
#else
link->conf.Vpp1 = link->conf.Vpp2 =
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
#endif
}
/* Do we need to allocate an interrupt? */
/* HACK: due to a bad CIS....we ALWAYS need an interrupt */
/* if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->conf.Attributes |= CONF_ENABLE_IRQ;
#else
link->conf.Attributes |= CONF_ENABLE_IRQ;
#endif
/* IO window settings */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->io.NumPorts1 = pdev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
pdev->io.BasePort1 = io->win[0].base;
if ( pdev->io.BasePort1 != 0 ) {
WLAN_LOG_WARNING(
"Brain damaged CIS: hard coded iobase="
"0x%x, try letting pcmcia_cs decide...\n",
pdev->io.BasePort1 );
pdev->io.BasePort1 = 0;
}
pdev->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
pdev->io.Attributes2 = pdev->io.Attributes1;
pdev->io.BasePort2 = io->win[1].base;
pdev->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
CFG_CHECK(RequestIO, pcmcia_request_io(pdev, &pdev->io));
#else
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.BasePort1 = io->win[0].base;
if ( link->io.BasePort1 != 0 ) {
WLAN_LOG_WARNING(
"Brain damaged CIS: hard coded iobase="
"0x%x, try letting pcmcia_cs decide...\n",
link->io.BasePort1 );
link->io.BasePort1 = 0;
}
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
CFG_CHECK(RequestIO, pcmcia_request_io(pdev, &link->io));
#endif
/* If we got this far, we're cool! */
break;
next_entry:
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
dflt = *cfg;
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(pdev, &tuple));
}
/* Let pcmcia know the device name */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->dev_node = &hw->node;
#else
link->dev = &hw->node;
#endif
/* Register the network device and get assigned a name */
SET_MODULE_OWNER(wlandev->netdev);
SET_NETDEV_DEV(wlandev->netdev, &handle_to_dev(pdev));
if (register_wlandev(wlandev) != 0) {
WLAN_LOG_NOTICE("prism2sta_cs: register_wlandev() failed.\n");
goto failed;
}
strcpy(hw->node.dev_name, wlandev->name);
/* Allocate an interrupt line. Note that this does not assign a */
/* handler to the interrupt, unless the 'Handler' member of the */
/* irq structure is initialized. */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
if (pdev->conf.Attributes & CONF_ENABLE_IRQ) {
pdev->irq.IRQInfo1 = IRQ_LEVEL_ID;
pdev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
pdev->irq.Handler = hfa384x_interrupt;
pdev->irq.Instance = wlandev;
CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
}
#else
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
link->irq.Handler = hfa384x_interrupt;
link->irq.Instance = wlandev;
CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &link->irq));
}
#endif
/* This actually configures the PCMCIA socket -- setting up */
/* the I/O windows and the interrupt mapping, and putting the */
/* card and host interface into "Memory and IO" mode. */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
#else
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &link->conf));
#endif
/* Fill the netdevice with this info */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
wlandev->netdev->irq = pdev->irq.AssignedIRQ;
wlandev->netdev->base_addr = pdev->io.BasePort1;
#else
wlandev->netdev->irq = link->irq.AssignedIRQ;
wlandev->netdev->base_addr = link->io.BasePort1;
#endif
/* And the rest of the hw structure */
hw->irq = wlandev->netdev->irq;
hw->iobase = wlandev->netdev->base_addr;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
link->state |= DEV_CONFIG;
link->state &= ~DEV_CONFIG_PENDING;
#endif
/* And now we're done! */
wlandev->msdstate = WLAN_MSD_HWPRESENT;
goto done;
cs_failed:
cs_error(pdev, last_fn, last_ret);
failed:
// wlandev, hw, etc etc..
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
pdev->priv = NULL;
#else
pdev->instance = NULL;
if (link) {
link->priv = NULL;
kfree(link);
}
#endif
if (wlandev) {
wlan_unsetup(wlandev);
if (wlandev->priv) {
hw = wlandev->priv;
wlandev->priv = NULL;
if (hw) {
hfa384x_destroy(hw);
kfree(hw);
}
}
kfree(wlandev);
}
done:
if (parse) kfree(parse);
DBFEXIT;
return rval;
}
#else // <= 2.6.15
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define CFG_CHECK(fn, retf) \
do { int ret = (retf); \
if (ret != 0) { \
WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
cs_error(link->handle, fn, ret); \
goto next_entry; \
} \
} while (0)
/*----------------------------------------------------------------
* prism2sta_attach
*
* Half of the attach/detach pair. Creates and registers a device
* instance with Card Services. In this case, it also creates the
* wlandev structure and device private structure. These are
* linked to the device instance via its priv member.
*
* Arguments:
* none
*
* Returns:
* A valid ptr to dev_link_t on success, NULL otherwise
*
* Side effects:
*
*
* Call context:
* process thread (insmod/init_module/register_pccard_driver)
----------------------------------------------------------------*/
dev_link_t *prism2sta_attach(void)
{
client_reg_t client_reg;
int result;
dev_link_t *link = NULL;
wlandevice_t *wlandev = NULL;
hfa384x_t *hw = NULL;
DBFENTER;
/* Alloc our structures */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link || ((wlandev = create_wlan()) == NULL)) {
WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
result = -EIO;
goto failed;
}
hw = wlandev->priv;
/* Clear all the structs */
memset(link, 0, sizeof(struct dev_link_t));
if ( wlan_setup(wlandev) != 0 ) {
WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
result = -EIO;
goto failed;
}
/* Initialize the hw struct for now */
hfa384x_create(hw, 0, 0, NULL);
hw->wlandev = wlandev;
/* Initialize the PC card device object. */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
init_timer(&link->release);
link->release.function = &prism2sta_release;
link->release.data = (u_long)link;
#endif
link->conf.IntType = INT_MEMORY_AND_IO;
link->priv = wlandev;
#if (defined(CS_RELEASE_CODE) && (CS_RELEASE_CODE < 0x2911))
link->irq.Instance = wlandev;
#endif
/* Link in to the list of devices managed by this driver */
link->next = dev_list;
dev_list = link;
/* Register with Card Services */
client_reg.dev_info = &dev_info;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
client_reg.EventMask =
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
CS_EVENT_RESET_REQUEST |
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.event_handler = &prism2sta_event;
#endif
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
result = pcmcia_register_client(&link->handle, &client_reg);
if (result != 0) {
cs_error(link->handle, RegisterClient, result);
prism2sta_detach(link);
return NULL;
}
goto done;
failed:
if (link) kfree(link);
if (wlandev) kfree(wlandev);
if (hw) kfree(hw);
link = NULL;
done:
DBFEXIT;
return link;
}
/*----------------------------------------------------------------
* prism2sta_detach
*
* Remove one of the device instances managed by this driver.
* Search the list for the given instance,
* check our flags for a waiting timer'd release call
* call release
* Deregister the instance with Card Services
* (netdevice) unregister the network device.
* unlink the instance from the list
* free the link, priv, and priv->priv memory
* Note: the dev_list variable is a driver scoped static used to
* maintain a list of device instances managed by this
* driver.
*
* Arguments:
* link ptr to the instance to detach
*
* Returns:
* nothing
*
* Side effects:
* the link structure is gone, the netdevice is gone
*
* Call context:
* Might be interrupt, don't block.
----------------------------------------------------------------*/
void prism2sta_detach(dev_link_t *link)
{
dev_link_t **linkp;
wlandevice_t *wlandev;
hfa384x_t *hw;
DBFENTER;
/* Locate prev device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
if (*linkp == link) break;
}
if (*linkp != NULL) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
unsigned long flags;
/* Get rid of any timer'd release call */
save_flags(flags);
cli();
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
if (link->state & DEV_RELEASE_PENDING) {
del_timer_sync(&link->release);
link->state &= ~DEV_RELEASE_PENDING;
}
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
restore_flags(flags);
#endif
/* If link says we're still config'd, call release */
if (link->state & DEV_CONFIG) {
prism2sta_release((u_long)link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
}
}
/* Tell Card Services we're not around any more */
if (link->handle) {
pcmcia_deregister_client(link->handle);
}
/* Unlink device structure, free bits */
*linkp = link->next;
if ( link->priv != NULL ) {
wlandev = (wlandevice_t*)link->priv;
p80211netdev_hwremoved(wlandev);
if (link->dev != NULL) {
unregister_wlandev(wlandev);
}
wlan_unsetup(wlandev);
if (wlandev->priv) {
hw = wlandev->priv;
wlandev->priv = NULL;
if (hw) {
hfa384x_destroy(hw);
kfree(hw);
}
}
link->priv = NULL;
kfree(wlandev);
}
kfree(link);
}
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_config
*
* Half of the config/release pair. Usually called in response to
* a card insertion event. At this point, we _know_ there's some
* physical device present. That means we can start poking around
* at the CIS and at any device specific config data we want.
*
* Note the gotos and the macros. I recoded this once without
* them, and it got incredibly ugly. It's actually simpler with
* them.
*
* Arguments:
* link the dev_link_t structure created in attach that
* represents this device instance.
*
* Returns:
* nothing
*
* Side effects:
* Resources (irq, io, mem) are allocated
* The pcmcia dev_link->node->name is set
* (For netcards) The device structure is finished and,
* most importantly, registered. This means that there
* is now a _named_ device that can be configured from
* userland.
*
* Call context:
* May be called from a timer. Don't block!
----------------------------------------------------------------*/
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define CFG_CHECK(fn, retf) \
do { int ret = (retf); \
if (ret != 0) { \
WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
cs_error(link->handle, fn, ret); \
goto next_entry; \
} \
} while (0)
void prism2sta_config(dev_link_t *link)
{
client_handle_t handle;
wlandevice_t *wlandev;
hfa384x_t *hw;
int last_fn;
int last_ret;
tuple_t tuple;
cisparse_t parse;
config_info_t socketconf;
UINT8 buf[64];
int minVcc = 0;
int maxVcc = 0;
cistpl_cftable_entry_t dflt = { 0 };
DBFENTER;
handle = link->handle;
wlandev = (wlandevice_t*)link->priv;
hw = wlandev->priv;
/* Collect the config register info */
tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
/* Acquire the current socket config (need Vcc setting) */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &socketconf));
/* Loop through the config table entries until we find one that works */
/* Assumes a complete and valid CIS */
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
CFG_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CFG_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
if (cfg->index == 0) goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* Lets print out the Vcc that the controller+pcmcia-cs set
* for us, cause that's what we're going to use.
*/
WLAN_LOG_DEBUG(1,"Initial Vcc=%d/10v\n", socketconf.Vcc);
if (prism2_ignorevcc) {
link->conf.Vcc = socketconf.Vcc;
goto skipvcc;
}
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
WLAN_LOG_DEBUG(1, "Vcc obtained from curtupl.VNOM\n");
minVcc = maxVcc =
cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
WLAN_LOG_DEBUG(1, "Vcc set from dflt.VNOM\n");
minVcc = maxVcc =
dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
} else if ((cfg->vcc.present & (1<<CISTPL_POWER_VMAX)) &&
(cfg->vcc.present & (1<<CISTPL_POWER_VMIN)) ) {
WLAN_LOG_DEBUG(1, "Vcc set from curtupl(VMIN,VMAX)\n"); minVcc = cfg->vcc.param[CISTPL_POWER_VMIN]/10000;
maxVcc = cfg->vcc.param[CISTPL_POWER_VMAX]/10000;
} else if ((dflt.vcc.present & (1<<CISTPL_POWER_VMAX)) &&
(dflt.vcc.present & (1<<CISTPL_POWER_VMIN)) ) {
WLAN_LOG_DEBUG(1, "Vcc set from dflt(VMIN,VMAX)\n");
minVcc = dflt.vcc.param[CISTPL_POWER_VMIN]/10000;
maxVcc = dflt.vcc.param[CISTPL_POWER_VMAX]/10000;
}
if ( socketconf.Vcc >= minVcc && socketconf.Vcc <= maxVcc) {
link->conf.Vcc = socketconf.Vcc;
} else {
/* [MSM]: Note that I've given up trying to change
* the Vcc if a change is indicated. It seems the
* system&socketcontroller&card vendors can't seem
* to get it right, so I'm tired of trying to hack
* my way around it. pcmcia-cs does its best using
* the voltage sense pins but sometimes the controller
* lies. Then, even if we have a good read on the VS
* pins, some system designs will silently ignore our
* requests to set the voltage. Additionally, some
* vendors have 3.3v indicated on their sense pins,
* but 5v specified in the CIS or vice-versa. I've
* had it. My only recommendation is "let the buyer
* beware". Your system might supply 5v to a 3v card
* (possibly causing damage) or a 3v capable system
* might supply 5v to a 3v capable card (wasting
* precious battery life).
* My only recommendation (if you care) is to get
* yourself an extender card (I don't know where, I
* have only one myself) and a meter and test it for
* yourself.
*/
goto next_entry;
}
skipvcc:
WLAN_LOG_DEBUG(1, "link->conf.Vcc=%d\n", link->conf.Vcc);
/* Do we need to allocate an interrupt? */
/* HACK: due to a bad CIS....we ALWAYS need an interrupt */
/* if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) */
link->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.BasePort1 = io->win[0].base;
if ( link->io.BasePort1 != 0 ) {
WLAN_LOG_WARNING(
"Brain damaged CIS: hard coded iobase="
"0x%x, try letting pcmcia_cs decide...\n",
link->io.BasePort1 );
link->io.BasePort1 = 0;
}
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
CFG_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
/* If we got this far, we're cool! */
break;
next_entry:
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
dflt = *cfg;
CS_CHECK(GetNextTuple,
pcmcia_get_next_tuple(handle, &tuple));
}
/* Allocate an interrupt line. Note that this does not assign a */
/* handler to the interrupt, unless the 'Handler' member of the */
/* irq structure is initialized. */
if (link->conf.Attributes & CONF_ENABLE_IRQ)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
int i;
link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
if (irq_list[0] == -1)
link->irq.IRQInfo2 = irq_mask;
else
for (i=0; i<4; i++)
link->irq.IRQInfo2 |= 1 << irq_list[i];
#else
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
#endif
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
link->irq.Handler = hfa384x_interrupt;
link->irq.Instance = wlandev;
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
}
/* This actually configures the PCMCIA socket -- setting up */
/* the I/O windows and the interrupt mapping, and putting the */
/* card and host interface into "Memory and IO" mode. */
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
/* Fill the netdevice with this info */
wlandev->netdev->irq = link->irq.AssignedIRQ;
wlandev->netdev->base_addr = link->io.BasePort1;
/* Report what we've done */
WLAN_LOG_INFO("%s: index 0x%02x: Vcc %d.%d",
dev_info, link->conf.ConfigIndex,
link->conf.Vcc/10, link->conf.Vcc%10);
if (link->conf.Vpp1)
printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ);
if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1);
if (link->io.NumPorts2)
printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1);
printk("\n");
link->state &= ~DEV_CONFIG_PENDING;
/* Let pcmcia know the device name */
link->dev = &hw->node;
/* Register the network device and get assigned a name */
SET_MODULE_OWNER(wlandev->netdev);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) )
SET_NETDEV_DEV(wlandev->netdev, &handle_to_dev(link->handle));
#endif
if (register_wlandev(wlandev) != 0) {
WLAN_LOG_NOTICE("prism2sta_cs: register_wlandev() failed.\n");
goto failed;
}
strcpy(hw->node.dev_name, wlandev->name);
/* Any device custom config/query stuff should be done here */
/* For a netdevice, we should at least grab the mac address */
return;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
WLAN_LOG_ERROR("NextTuple failure? It's probably a Vcc mismatch.\n");
failed:
prism2sta_release((u_long)link);
return;
}
/*----------------------------------------------------------------
* prism2sta_release
*
* Half of the config/release pair. Usually called in response to
* a card ejection event. Checks to make sure no higher layers
* are still (or think they are) using the card via the link->open
* field.
*
* NOTE: Don't forget to increment the link->open variable in the
* device_open method, and decrement it in the device_close
* method.
*
* Arguments:
* arg a generic 32 bit variable. It's the value that
* we assigned to link->release.data in sta_attach().
*
* Returns:
* nothing
*
* Side effects:
* All resources should be released after this function
* executes and finds the device !open.
*
* Call context:
* Possibly in a timer context. Don't do anything that'll
* block.
----------------------------------------------------------------*/
void prism2sta_release(u_long arg)
{
dev_link_t *link = (dev_link_t *)arg;
DBFENTER;
/* First thing we should do is get the MSD back to the
* HWPRESENT state. I.e. everything quiescent.
*/
prism2sta_ifstate(link->priv, P80211ENUM_ifstate_disable);
if (link->open) {
/* TODO: I don't think we're even using this bit of code
* and I don't think it's hurting us at the moment.
*/
WLAN_LOG_DEBUG(1,
"prism2sta_cs: release postponed, '%s' still open\n",
link->dev->dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
DBFEXIT;
}
/*----------------------------------------------------------------
* prism2sta_event
*
* Handler for card services events.
*
* Arguments:
* event The event code
* priority hi/low - REMOVAL is the only hi
* args ptr to card services struct containing info about
* pcmcia status
*
* Returns:
* Zero on success, non-zero otherwise
*
* Side effects:
*
*
* Call context:
* Both interrupt and process thread, depends on the event.
----------------------------------------------------------------*/
static int
prism2sta_event (
event_t event,
int priority,
event_callback_args_t *args)
{
int result = 0;
dev_link_t *link = (dev_link_t *) args->client_data;
wlandevice_t *wlandev = (wlandevice_t*)link->priv;
hfa384x_t *hw = NULL;
DBFENTER;
if (wlandev) hw = wlandev->priv;
switch (event)
{
case CS_EVENT_CARD_INSERTION:
WLAN_LOG_DEBUG(5,"event is INSERTION\n");
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
prism2sta_config(link);
if (!(link->state & DEV_CONFIG)) {
wlandev->netdev->irq = 0;
WLAN_LOG_ERROR(
"%s: Initialization failed!\n", dev_info);
wlandev->msdstate = WLAN_MSD_HWFAIL;
break;
}
/* Fill in the rest of the hw struct */
hw->irq = wlandev->netdev->irq;
hw->iobase = wlandev->netdev->base_addr;
hw->link = link;
if (prism2_doreset) {
result = hfa384x_corereset(hw,
prism2_reset_holdtime,
prism2_reset_settletime, 0);
if ( result ) {
WLAN_LOG_ERROR(
"corereset() failed, result=%d.\n",
result);
wlandev->msdstate = WLAN_MSD_HWFAIL;
break;
}
}
#if 0
/*
* TODO: test_hostif() not implemented yet.
*/
result = hfa384x_test_hostif(hw);
if (result) {
WLAN_LOG_ERROR(
"test_hostif() failed, result=%d.\n", result);
wlandev->msdstate = WLAN_MSD_HWFAIL;
break;
}
#endif
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
case CS_EVENT_CARD_REMOVAL:
WLAN_LOG_DEBUG(5,"event is REMOVAL\n");
link->state &= ~DEV_PRESENT;
if (wlandev) {
p80211netdev_hwremoved(wlandev);
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
if (link->state & DEV_CONFIG)
{
link->release.expires = jiffies + (HZ/20);
add_timer(&link->release);
}
#endif
break;
case CS_EVENT_RESET_REQUEST:
WLAN_LOG_DEBUG(5,"event is RESET_REQUEST\n");
WLAN_LOG_NOTICE(
"prism2 card reset not supported "
"due to post-reset user mode configuration "
"requirements.\n");
WLAN_LOG_NOTICE(
" From user mode, use "
"'cardctl suspend;cardctl resume' "
"instead.\n");
break;
case CS_EVENT_RESET_PHYSICAL:
case CS_EVENT_CARD_RESET:
WLAN_LOG_WARNING("Rx'd CS_EVENT_RESET_xxx, should not "
"be possible since RESET_REQUEST was denied.\n");
break;
case CS_EVENT_PM_SUSPEND:
WLAN_LOG_DEBUG(5,"event is SUSPEND\n");
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
{
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
WLAN_LOG_DEBUG(5,"event is RESUME\n");
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
}
break;
}
DBFEXIT;
return 0; /* noone else does anthing with the return value */
}
#endif // <= 2.6.15
int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
{
int result = 0;
conf_reg_t reg;
UINT8 corsave;
DBFENTER;
WLAN_LOG_DEBUG(3, "Doing reset via CardServices().\n");
/* Collect COR */
reg.Function = 0;
reg.Action = CS_READ;
reg.Offset = CISREG_COR;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
result = pcmcia_access_configuration_register(hw->pdev, &reg);
#else
result = pcmcia_access_configuration_register(
hw->link->handle,
&reg);
#endif
if (result != CS_SUCCESS ) {
WLAN_LOG_ERROR(
":0: AccessConfigurationRegister(CS_READ) failed,"
"result=%d.\n", result);
result = -EIO;
}
corsave = reg.Value;
/* Write reset bit (BIT7) */
reg.Value |= BIT7;
reg.Action = CS_WRITE;
reg.Offset = CISREG_COR;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
result = pcmcia_access_configuration_register(hw->pdev, &reg);
#else
result = pcmcia_access_configuration_register(
hw->link->handle,
&reg);
#endif
if (result != CS_SUCCESS ) {
WLAN_LOG_ERROR(
":1: AccessConfigurationRegister(CS_WRITE) failed,"
"result=%d.\n", result);
result = -EIO;
}
/* Hold for holdtime */
mdelay(holdtime);
if (genesis) {
reg.Value = genesis;
reg.Action = CS_WRITE;
reg.Offset = CISREG_CCSR;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
result = pcmcia_access_configuration_register(hw->pdev, &reg);
#else
result = pcmcia_access_configuration_register(
hw->link->handle,
&reg);
#endif
if (result != CS_SUCCESS ) {
WLAN_LOG_ERROR(
":1: AccessConfigurationRegister(CS_WRITE) failed,"
"result=%d.\n", result);
result = -EIO;
}
}
/* Hold for holdtime */
mdelay(holdtime);
/* Clear reset bit */
reg.Value &= ~BIT7;
reg.Action = CS_WRITE;
reg.Offset = CISREG_COR;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
result = pcmcia_access_configuration_register(hw->pdev, &reg);
#else
result = pcmcia_access_configuration_register(
hw->link->handle,
&reg);
#endif
if (result != CS_SUCCESS ) {
WLAN_LOG_ERROR(
":2: AccessConfigurationRegister(CS_WRITE) failed,"
"result=%d.\n", result);
result = -EIO;
goto done;
}
/* Wait for settletime */
mdelay(settletime);
/* Set non-reset bits back what they were */
reg.Value = corsave;
reg.Action = CS_WRITE;
reg.Offset = CISREG_COR;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
result = pcmcia_access_configuration_register(hw->pdev, &reg);
#else
result = pcmcia_access_configuration_register(
hw->link->handle,
&reg);
#endif
if (result != CS_SUCCESS ) {
WLAN_LOG_ERROR(
":2: AccessConfigurationRegister(CS_WRITE) failed,"
"result=%d.\n", result);
result = -EIO;
goto done;
}
done:
DBFEXIT;
return result;
}
#ifdef MODULE
static int __init prism2cs_init(void)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
servinfo_t serv;
#endif
DBFENTER;
WLAN_LOG_NOTICE("%s Loaded\n", version);
WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
pcmcia_get_card_services_info(&serv);
if ( serv.Revision != CS_RELEASE_CODE )
{
printk(KERN_NOTICE"%s: CardServices release does not match!\n", dev_info);
return -1;
}
/* This call will result in a call to prism2sta_attach */
/* and eventually prism2sta_detach */
register_pccard_driver( &dev_info, &prism2sta_attach, &prism2sta_detach);
#else
pcmcia_register_driver(&prism2_cs_driver);
#endif
DBFEXIT;
return 0;
}
static void __exit prism2cs_cleanup(void)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
dev_link_t *link = dev_list;
dev_link_t *nlink;
DBFENTER;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
for (link=dev_list; link != NULL; link = nlink) {
nlink = link->next;
if ( link->state & DEV_CONFIG ) {
prism2sta_release((u_long)link);
}
prism2sta_detach(link); /* remember detach() frees link */
}
#endif
unregister_pccard_driver( &dev_info);
#else
pcmcia_unregister_driver(&prism2_cs_driver);
#endif
printk(KERN_NOTICE "%s Unloaded\n", version);
DBFEXIT;
return;
}
module_init(prism2cs_init);
module_exit(prism2cs_cleanup);
#endif // MODULE
#define WLAN_HOSTIF WLAN_PCI
#include "hfa384x.c"
#include "prism2mgmt.c"
#include "prism2mib.c"
#include "prism2sta.c"
#define PCI_SIZE 0x1000 /* Memory size - 4K bytes */
/* ISL3874A 11Mb/s WLAN controller */
#define PCIVENDOR_INTERSIL 0x1260UL
#define PCIDEVICE_ISL3874 0x3873UL /* [MSM] yeah I know...the ID says
3873. Trust me, it's a 3874. */
/* Samsung SWL-2210P 11Mb/s WLAN controller (uses ISL3874A) */
#define PCIVENDOR_SAMSUNG 0x167dUL
#define PCIDEVICE_SWL_2210P 0xa000UL
#define PCIVENDOR_NETGEAR 0x1385UL /* for MA311 */
/* PCI Class & Sub-Class code, Network-'Other controller' */
#define PCI_CLASS_NETWORK_OTHERS 0x280
/*----------------------------------------------------------------
* prism2sta_probe_pci
*
* Probe routine called when a PCI device w/ matching ID is found.
* The ISL3874 implementation uses the following map:
* BAR0: Prism2.x registers memory mapped, size=4k
* Here's the sequence:
* - Allocate the PCI resources.
* - Read the PCMCIA attribute memory to make sure we have a WLAN card
* - Reset the MAC
* - Initialize the netdev and wlan data
* - Initialize the MAC
*
* Arguments:
* pdev ptr to pci device structure containing info about
* pci configuration.
* id ptr to the device id entry that matched this device.
*
* Returns:
* zero - success
* negative - failed
*
* Side effects:
*
*
* Call context:
* process thread
*
----------------------------------------------------------------*/
static int __devinit
prism2sta_probe_pci(
struct pci_dev *pdev,
const struct pci_device_id *id)
{
int result;
phys_t phymem = 0;
void __iomem *mem = NULL;
wlandevice_t *wlandev = NULL;
hfa384x_t *hw = NULL;
DBFENTER;
/* Enable the pci device */
if (pci_enable_device(pdev)) {
WLAN_LOG_ERROR("%s: pci_enable_device() failed.\n", dev_info);
result = -EIO;
goto fail;
}
/* Figure out our resources */
phymem = pci_resource_start(pdev, 0);
if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
result = -EIO;
goto fail;
}
mem = ioremap(phymem, PCI_SIZE);
if ( mem == 0 ) {
WLAN_LOG_ERROR("%s: ioremap() failed.\n", dev_info);
result = -EIO;
goto fail;
}
/* Log the device */
WLAN_LOG_INFO("A Prism2.5 PCI device found, "
"phymem:0x%llx, irq:%d, mem:0x%p\n",
(unsigned long long)phymem, pdev->irq, mem);
if ((wlandev = create_wlan()) == NULL) {
WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
result = -EIO;
goto fail;
}
hw = wlandev->priv;
if ( wlan_setup(wlandev) != 0 ) {
WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
result = -EIO;
goto fail;
}
/* Setup netdevice's ability to report resources
* Note: the netdevice was allocated by wlan_setup()
*/
wlandev->netdev->irq = pdev->irq;
wlandev->netdev->mem_start = (unsigned long) mem;
wlandev->netdev->mem_end = wlandev->netdev->mem_start +
pci_resource_len(pdev, 0);
/* Initialize the hw data */
hfa384x_create(hw, wlandev->netdev->irq, 0, mem);
hw->wlandev = wlandev;
/* Register the wlandev, this gets us a name and registers the
* linux netdevice.
*/
SET_MODULE_OWNER(wlandev->netdev);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
SET_NETDEV_DEV(wlandev->netdev, &(pdev->dev));
#endif
if ( register_wlandev(wlandev) != 0 ) {
WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
result = -EIO;
goto fail;
}
#if 0
/* TODO: Move this and an irq test into an hfa384x_testif() routine.
*/
outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
if ( reg != PRISM2STA_MAGIC ) {
WLAN_LOG_ERROR("MAC register access test failed!\n");
result = -EIO;
goto fail;
}
#endif
/* Do a chip-level reset on the MAC */
if (prism2_doreset) {
result = hfa384x_corereset(hw,
prism2_reset_holdtime,
prism2_reset_settletime, 0);
if (result != 0) {
WLAN_LOG_ERROR(
"%s: hfa384x_corereset() failed.\n",
dev_info);
unregister_wlandev(wlandev);
hfa384x_destroy(hw);
result = -EIO;
goto fail;
}
}
pci_set_drvdata(pdev, wlandev);
/* Shouldn't actually hook up the IRQ until we
* _know_ things are alright. A test routine would help.
*/
request_irq(wlandev->netdev->irq, hfa384x_interrupt,
SA_SHIRQ, wlandev->name, wlandev);
wlandev->msdstate = WLAN_MSD_HWPRESENT;
result = 0;
goto done;
fail:
pci_set_drvdata(pdev, NULL);
if (wlandev) kfree(wlandev);
if (hw) kfree(hw);
if (mem) iounmap(mem);
pci_release_regions(pdev);
pci_disable_device(pdev);
done:
DBFEXIT;
return result;
}
static void __devexit prism2sta_remove_pci(struct pci_dev *pdev)
{
wlandevice_t *wlandev;
hfa384x_t *hw;
wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
hw = wlandev->priv;
p80211netdev_hwremoved(wlandev);
/* reset hardware */
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
if (pdev->irq)
free_irq(pdev->irq, wlandev);
unregister_wlandev(wlandev);
/* free local stuff */
if (hw) {
hfa384x_destroy(hw);
kfree(hw);
}
iounmap((void __iomem *)wlandev->netdev->mem_start);
wlan_unsetup(wlandev);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
kfree(wlandev);
}
static struct pci_device_id pci_id_tbl[] = {
{
PCIVENDOR_INTERSIL, PCIDEVICE_ISL3874,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller"
},
{
PCIVENDOR_INTERSIL, 0x3872,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Intersil Prism2.5 ISL3872 11Mb/s WLAN Controller"
},
{
PCIVENDOR_SAMSUNG, PCIDEVICE_SWL_2210P,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Samsung MagicLAN SWL-2210P 11Mb/s WLAN Controller"
},
{ /* for NetGear MA311 */
PCIVENDOR_NETGEAR, 0x3872,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Netgear MA311 WLAN Controller"
},
{
0, 0, 0, 0, 0, 0, 0
}
};
MODULE_DEVICE_TABLE(pci, pci_id_tbl);
/* Function declared here because of ptr reference below */
static int __devinit prism2sta_probe_pci(struct pci_dev *pdev,
const struct pci_device_id *id);
static void __devexit prism2sta_remove_pci(struct pci_dev *pdev);
static struct pci_driver prism2_pci_drv_id = {
.name = "prism2_pci",
.id_table = pci_id_tbl,
.probe = prism2sta_probe_pci,
.remove = prism2sta_remove_pci,
#ifdef CONFIG_PM
.suspend = prism2sta_suspend_pci,
.resume = prism2sta_resume_pci,
#endif
};
#ifdef MODULE
static int __init prism2pci_init(void)
{
WLAN_LOG_NOTICE("%s Loaded\n", version);
return pci_module_init(&prism2_pci_drv_id);
};
static void __exit prism2pci_cleanup(void)
{
pci_unregister_driver(&prism2_pci_drv_id);
};
module_init(prism2pci_init);
module_exit(prism2pci_cleanup);
#endif
int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
{
int result = 0;
unsigned long timeout;
UINT16 reg;
DBFENTER;
/* Assert reset and wait awhile
* (note: these delays are _really_ long, but they appear to be
* necessary.)
*/
hfa384x_setreg(hw, 0xc5, HFA384x_PCICOR);
timeout = jiffies + HZ/4;
while(time_before(jiffies, timeout)) udelay(5);
if (genesis) {
hfa384x_setreg(hw, genesis, HFA384x_PCIHCR);
timeout = jiffies + HZ/4;
while(time_before(jiffies, timeout)) udelay(5);
}
/* Clear the reset and wait some more
*/
hfa384x_setreg(hw, 0x45, HFA384x_PCICOR);
timeout = jiffies + HZ/2;
while(time_before(jiffies, timeout)) udelay(5);
/* Wait for f/w to complete initialization (CMD:BUSY == 0)
*/
timeout = jiffies + 2*HZ;
reg = hfa384x_getreg(hw, HFA384x_CMD);
while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) {
reg = hfa384x_getreg(hw, HFA384x_CMD);
udelay(10);
}
if (HFA384x_CMD_ISBUSY(reg)) {
WLAN_LOG_WARNING("corereset: Timed out waiting for cmd register.\n");
result=1;
}
DBFEXIT;
return result;
}
#define WLAN_HOSTIF WLAN_PLX
#include "hfa384x.c"
#include "prism2mgmt.c"
#include "prism2mib.c"
#include "prism2sta.c"
#define PLX_ATTR_SIZE 0x1000 /* Attribute memory size - 4K bytes */
#define COR_OFFSET 0x3e0 /* COR attribute offset of Prism2 PC card */
#define COR_VALUE 0x41 /* Enable PC card with irq in level trigger */
#define PLX_INTCSR 0x4c /* Interrupt Control and Status Register */
#define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */
#define PLX_MIN_ATTR_LEN 512 /* at least 2 x 256 is needed for CIS */
/* 3Com 3CRW777A (PLX) board ID */
#define PCIVENDOR_3COM 0x10B7
#define PCIDEVICE_AIRCONNECT 0x7770
/* Eumitcom PCI WL11000 PCI Adapter (PLX) board device+vendor ID */
#define PCIVENDOR_EUMITCOM 0x1638UL
#define PCIDEVICE_WL11000 0x1100UL
/* Global Sun Tech GL24110P PCI Adapter (PLX) board device+vendor ID */
#define PCIVENDOR_GLOBALSUN 0x16abUL
#define PCIDEVICE_GL24110P 0x1101UL
#define PCIDEVICE_GL24110P_ALT 0x1102UL
/* Netgear MA301 PCI Adapter (PLX) board device+vendor ID */
#define PCIVENDOR_NETGEAR 0x1385UL
#define PCIDEVICE_MA301 0x4100UL
/* US Robotics USR2410 PCI Adapter (PLX) board device+vendor ID */
#define PCIVENDOR_USROBOTICS 0x16ecUL
#define PCIDEVICE_USR2410 0x3685UL
/* Linksys WPC11 card with the WDT11 adapter (PLX) board device+vendor ID */
#define PCIVENDOR_Linksys 0x16abUL
#define PCIDEVICE_Wpc11Wdt11 0x1102UL
/* National Datacomm Corp SOHOware Netblaster II PCI */
#define PCIVENDOR_NDC 0x15e8UL
#define PCIDEVICE_NCP130_PLX 0x0130UL
#define PCIDEVICE_NCP130_ASIC 0x0131UL
/* NDC NCP130_PLX is also sold by Corega. Their name is CGWLPCIA11 */
#define PCIVENDOR_COREGA PCIVENDOR_NDC
#define PCIDEVICE_CGWLPCIA11 PCIDEVICE_NCP130_PLX
/* PCI Class & Sub-Class code, Network-'Other controller' */
#define PCI_CLASS_NETWORK_OTHERS 0x280
/*----------------------------------------------------------------
* prism2sta_probe_plx
*
* Probe routine called when a PCI device w/ matching ID is found.
* This PLX implementation uses the following map:
* BAR0: Unused
* BAR1: ????
* BAR2: PCMCIA attribute memory
* BAR3: PCMCIA i/o space
* Here's the sequence:
* - Allocate the PCI resources.
* - Read the PCMCIA attribute memory to make sure we have a WLAN card
* - Reset the MAC using the PCMCIA COR
* - Initialize the netdev and wlan data
* - Initialize the MAC
*
* Arguments:
* pdev ptr to pci device structure containing info about
* pci configuration.
* id ptr to the device id entry that matched this device.
*
* Returns:
* zero - success
* negative - failed
*
* Side effects:
*
*
* Call context:
* process thread
*
----------------------------------------------------------------*/
static int __devinit
prism2sta_probe_plx(
struct pci_dev *pdev,
const struct pci_device_id *id)
{
int result;
phys_t pccard_ioaddr;
phys_t pccard_attr_mem;
unsigned int pccard_attr_len;
void __iomem *attr_mem = NULL;
UINT32 plx_addr;
wlandevice_t *wlandev = NULL;
hfa384x_t *hw = NULL;
int reg;
u32 regic;
if (pci_enable_device(pdev))
return -EIO;
/* TMC7160 boards are special */
if ((pdev->vendor == PCIVENDOR_NDC) &&
(pdev->device == PCIDEVICE_NCP130_ASIC)) {
unsigned long delay;
pccard_attr_mem = 0;
pccard_ioaddr = pci_resource_start(pdev, 1);
outb(0x45, pccard_ioaddr);
delay = jiffies + 1*HZ;
while (time_before(jiffies, delay));
if (inb(pccard_ioaddr) != 0x45) {
WLAN_LOG_ERROR("Initialize the TMC7160 failed. (0x%x)\n", inb(pccard_ioaddr));
return -EIO;
}
pccard_ioaddr = pci_resource_start(pdev, 2);
prism2_doreset = 0;
WLAN_LOG_INFO("NDC NCP130 with TMC716(ASIC) PCI interface device found at io:0x%x, irq:%d\n", pccard_ioaddr, pdev->irq);
goto init;
}
/* Collect the resource requirements */
pccard_attr_mem = pci_resource_start(pdev, 2);
pccard_attr_len = pci_resource_len(pdev, 2);
if (pccard_attr_len < PLX_MIN_ATTR_LEN)
return -EIO;
pccard_ioaddr = pci_resource_start(pdev, 3);
/* bjoern: We need to tell the card to enable interrupts, in
* case the serial eprom didn't do this already. See the
* PLX9052 data book, p8-1 and 8-24 for reference.
* [MSM]: This bit of code came from the orinoco_cs driver.
*/
plx_addr = pci_resource_start(pdev, 1);
regic = 0;
regic = inl(plx_addr+PLX_INTCSR);
if(regic & PLX_INTCSR_INTEN) {
WLAN_LOG_DEBUG(1,
"%s: Local Interrupt already enabled\n", dev_info);
} else {
regic |= PLX_INTCSR_INTEN;
outl(regic, plx_addr+PLX_INTCSR);
regic = inl(plx_addr+PLX_INTCSR);
if(!(regic & PLX_INTCSR_INTEN)) {
WLAN_LOG_ERROR(
"%s: Couldn't enable Local Interrupts\n",
dev_info);
return -EIO;
}
}
/* These assignments are here in case of future mappings for
* io space and irq that might be similar to ioremap
*/
if (!request_mem_region(pccard_attr_mem, pci_resource_len(pdev, 2), "Prism2")) {
WLAN_LOG_ERROR("%s: Couldn't reserve PCI memory region\n", dev_info);
return -EIO;
}
attr_mem = ioremap(pccard_attr_mem, pccard_attr_len);
WLAN_LOG_INFO("A PLX PCI/PCMCIA interface device found, "
"phymem:0x%llx, phyio=0x%x, irq:%d, "
"mem: 0x%lx\n",
(unsigned long long)pccard_attr_mem, pccard_ioaddr, pdev->irq,
(unsigned long)attr_mem);
/* Verify whether PC card is present.
* [MSM] This needs improvement, the right thing to do is
* probably to walk the CIS looking for the vendor and product
* IDs. It would be nice if this could be tied in with the
* etc/pcmcia/wlan-ng.conf file. Any volunteers? ;-)
*/
if (
readb(attr_mem + 0) != 0x01 || readb(attr_mem + 2) != 0x03 ||
readb(attr_mem + 4) != 0x00 || readb(attr_mem + 6) != 0x00 ||
readb(attr_mem + 8) != 0xFF || readb(attr_mem + 10) != 0x17 ||
readb(attr_mem + 12) != 0x04 || readb(attr_mem + 14) != 0x67) {
WLAN_LOG_ERROR("Prism2 PC card CIS is invalid.\n");
return -EIO;
}
WLAN_LOG_INFO("A PCMCIA WLAN adapter was found.\n");
/* Write COR to enable PC card */
writeb(COR_VALUE, attr_mem + COR_OFFSET);
reg = readb(attr_mem + COR_OFFSET);
init:
/*
* Now do everything the same as a PCI device
* [MSM] TODO: We could probably factor this out of pcmcia/pci/plx
* and perhaps usb. Perhaps a task for another day.......
*/
if ((wlandev = create_wlan()) == NULL) {
WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
result = -EIO;
goto failed;
}
hw = wlandev->priv;
if ( wlan_setup(wlandev) != 0 ) {
WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
result = -EIO;
goto failed;
}
/* Setup netdevice's ability to report resources
* Note: the netdevice was allocated by wlan_setup()
*/
wlandev->netdev->irq = pdev->irq;
wlandev->netdev->base_addr = pccard_ioaddr;
wlandev->netdev->mem_start = (unsigned long)attr_mem;
wlandev->netdev->mem_end = (unsigned long)attr_mem + pci_resource_len(pdev, 0);
/* Initialize the hw data */
hfa384x_create(hw, wlandev->netdev->irq, pccard_ioaddr, attr_mem);
hw->wlandev = wlandev;
/* Register the wlandev, this gets us a name and registers the
* linux netdevice.
*/
SET_MODULE_OWNER(wlandev->netdev);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
SET_NETDEV_DEV(wlandev->netdev, &(pdev->dev));
#endif
if ( register_wlandev(wlandev) != 0 ) {
WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
result = -EIO;
goto failed;
}
#if 0
/* TODO: Move this and an irq test into an hfa384x_testif() routine.
*/
outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
if ( reg != PRISM2STA_MAGIC ) {
WLAN_LOG_ERROR("MAC register access test failed!\n");
result = -EIO;
goto failed;
}
#endif
/* Do a chip-level reset on the MAC */
if (prism2_doreset) {
result = hfa384x_corereset(hw,
prism2_reset_holdtime,
prism2_reset_settletime, 0);
if (result != 0) {
unregister_wlandev(wlandev);
hfa384x_destroy(hw);
WLAN_LOG_ERROR(
"%s: hfa384x_corereset() failed.\n",
dev_info);
result = -EIO;
goto failed;
}
}
pci_set_drvdata(pdev, wlandev);
/* Shouldn't actually hook up the IRQ until we
* _know_ things are alright. A test routine would help.
*/
request_irq(wlandev->netdev->irq, hfa384x_interrupt,
SA_SHIRQ, wlandev->name, wlandev);
wlandev->msdstate = WLAN_MSD_HWPRESENT;
result = 0;
goto done;
failed:
pci_set_drvdata(pdev, NULL);
if (wlandev) kfree(wlandev);
if (hw) kfree(hw);
if (attr_mem) iounmap(attr_mem);
pci_release_regions(pdev);
pci_disable_device(pdev);
done:
DBFEXIT;
return result;
}
static void __devexit prism2sta_remove_plx(struct pci_dev *pdev)
{
wlandevice_t *wlandev;
hfa384x_t *hw;
wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
hw = wlandev->priv;
p80211netdev_hwremoved(wlandev);
/* reset hardware */
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
if (pdev->irq)
free_irq(pdev->irq, wlandev);
unregister_wlandev(wlandev);
/* free local stuff */
if (hw) {
hfa384x_destroy(hw);
kfree(hw);
}
iounmap((void __iomem *)wlandev->netdev->mem_start);
wlan_unsetup(wlandev);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
kfree(wlandev);
}
static struct pci_device_id plx_id_tbl[] = {
{
PCIVENDOR_EUMITCOM, PCIDEVICE_WL11000,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Eumitcom WL11000 PCI(PLX) card"
},
{
PCIVENDOR_GLOBALSUN, PCIDEVICE_GL24110P,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
},
{
PCIVENDOR_GLOBALSUN, PCIDEVICE_GL24110P_ALT,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
},
{
PCIVENDOR_NETGEAR, PCIDEVICE_MA301,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
},
{
PCIVENDOR_USROBOTICS, PCIDEVICE_USR2410,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"US Robotics USR2410 PCI(PLX) card"
},
{
PCIVENDOR_Linksys, PCIDEVICE_Wpc11Wdt11,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"Linksys WPC11 with WDT11 PCI(PLX) adapter"
},
{
PCIVENDOR_NDC, PCIDEVICE_NCP130_PLX,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"NDC Netblaster II PCI(PLX)"
},
{
PCIVENDOR_NDC, PCIDEVICE_NCP130_ASIC,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"NDC Netblaster II PCI(TMC7160)"
},
{
PCIVENDOR_3COM, PCIDEVICE_AIRCONNECT,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
/* Driver data, we just put the name here */
(unsigned long)"3Com AirConnect PCI 802.11b 11Mb/s WLAN Controller"
},
{
0, 0, 0, 0, 0, 0, 0
}
};
MODULE_DEVICE_TABLE(pci, plx_id_tbl);
/* Function declared here because of ptr reference below */
static int __devinit prism2sta_probe_plx(struct pci_dev *pdev,
const struct pci_device_id *);
static void __devexit prism2sta_remove_plx(struct pci_dev *pdev);
static struct pci_driver prism2_plx_drv_id = {
.name = "prism2_plx",
.id_table = plx_id_tbl,
.probe = prism2sta_probe_plx,
.remove = prism2sta_remove_plx,
#ifdef CONFIG_PM
.suspend = prism2sta_suspend_pci,
.resume = prism2sta_resume_pci,
#endif
};
#ifdef MODULE
static int __init prism2plx_init(void)
{
WLAN_LOG_NOTICE("%s Loaded\n", version);
return pci_module_init(&prism2_plx_drv_id);
};
static void __exit prism2plx_cleanup(void)
{
pci_unregister_driver(&prism2_plx_drv_id);
};
module_init(prism2plx_init);
module_exit(prism2plx_cleanup);
#endif // MODULE
int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
{
int result = 0;
#define COR_OFFSET 0x3e0 /* COR attribute offset of Prism2 PC card */
#define COR_VALUE 0x41 /* Enable PC card with irq in level trigger */
#define HCR_OFFSET 0x3e2 /* HCR attribute offset of Prism2 PC card */
UINT8 corsave;
DBFENTER;
WLAN_LOG_DEBUG(3, "Doing reset via direct COR access.\n");
/* Collect COR */
corsave = readb(hw->membase + COR_OFFSET);
/* Write reset bit (BIT7) */
writeb(corsave | BIT7, hw->membase + COR_OFFSET);
/* Hold for holdtime */
mdelay(holdtime);
if (genesis) {
writeb(genesis, hw->membase + HCR_OFFSET);
/* Hold for holdtime */
mdelay(holdtime);
}
/* Clear reset bit */
writeb(corsave & ~BIT7, hw->membase + COR_OFFSET);
/* Wait for settletime */
mdelay(settletime);
/* Set non-reset bits back what they were */
writeb(corsave, hw->membase + COR_OFFSET);
DBFEXIT;
return result;
}
#define WLAN_HOSTIF WLAN_USB
#include "hfa384x_usb.c"
#include "prism2mgmt.c"
#include "prism2mib.c"
#include "prism2sta.c"
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
#error "prism2_usb requires at least a 2.4.x kernel!"
#endif
#define PRISM_USB_DEVICE(vid, pid, name) \
USB_DEVICE(vid, pid), \
.driver_info = (unsigned long) name
static struct usb_device_id usb_prism_tbl[] = {
{PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")},
{PRISM_USB_DEVICE(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11")},
{PRISM_USB_DEVICE(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x049f, 0x0033, "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
{PRISM_USB_DEVICE(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
{PRISM_USB_DEVICE(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
{PRISM_USB_DEVICE(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")},
{PRISM_USB_DEVICE(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
{PRISM_USB_DEVICE(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x0967, 0x0204, "Acer Warplink USB Adapter")},
{PRISM_USB_DEVICE(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")},
{PRISM_USB_DEVICE(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")},
{PRISM_USB_DEVICE(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")},
{PRISM_USB_DEVICE(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
{PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
{PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
// {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x50c2, 0x4013, "Averatec USB WLAN Adapter")},
{PRISM_USB_DEVICE(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter")},
{PRISM_USB_DEVICE(0x2821, 0x3300, "Hawking HighDB USB Adapter")},
{PRISM_USB_DEVICE(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")},
{PRISM_USB_DEVICE(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter")},
{PRISM_USB_DEVICE(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")},
{PRISM_USB_DEVICE(0x0bb2, 0x0302, "Ambit Microsystems Corp.")},
{PRISM_USB_DEVICE(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")},
{PRISM_USB_DEVICE(0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")},
{ /* terminator */ }
};
MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
/*----------------------------------------------------------------
* prism2sta_probe_usb
*
* Probe routine called by the USB subsystem.
*
* Arguments:
* dev ptr to the usb_device struct
* ifnum interface number being offered
*
* Returns:
* NULL - we're not claiming the device+interface
* non-NULL - we are claiming the device+interface and
* this is a ptr to the data we want back
* when disconnect is called.
*
* Side effects:
*
* Call context:
* I'm not sure, assume it's interrupt.
*
----------------------------------------------------------------*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
static void __devinit *prism2sta_probe_usb(
struct usb_device *dev,
unsigned int ifnum,
const struct usb_device_id *id)
#else
static int prism2sta_probe_usb(
struct usb_interface *interface,
const struct usb_device_id *id)
#endif
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
struct usb_interface *interface;
#else
struct usb_device *dev;
#endif
wlandevice_t *wlandev = NULL;
hfa384x_t *hw = NULL;
int result = 0;
DBFENTER;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
interface = &dev->actconfig->interface[ifnum];
#else
dev = interface_to_usbdev(interface);
#endif
if ((wlandev = create_wlan()) == NULL) {
WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
result = -EIO;
goto failed;
}
hw = wlandev->priv;
if ( wlan_setup(wlandev) != 0 ) {
WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
result = -EIO;
goto failed;
}
/* Initialize the hw data */
hfa384x_create(hw, dev);
hw->wlandev = wlandev;
/* Register the wlandev, this gets us a name and registers the
* linux netdevice.
*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
SET_NETDEV_DEV(wlandev->netdev, &(interface->dev));
#endif
if ( register_wlandev(wlandev) != 0 ) {
WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
result = -EIO;
goto failed;
}
/* Do a chip-level reset on the MAC */
if (prism2_doreset) {
result = hfa384x_corereset(hw,
prism2_reset_holdtime,
prism2_reset_settletime, 0);
if (result != 0) {
unregister_wlandev(wlandev);
hfa384x_destroy(hw);
result = -EIO;
WLAN_LOG_ERROR(
"%s: hfa384x_corereset() failed.\n",
dev_info);
goto failed;
}
}
#ifndef NEW_MODULE_CODE
usb_inc_dev_use(dev);
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
usb_get_dev(dev);
#endif
wlandev->msdstate = WLAN_MSD_HWPRESENT;
goto done;
failed:
if (wlandev) kfree(wlandev);
if (hw) kfree(hw);
wlandev = NULL;
done:
DBFEXIT;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
return wlandev;
#else
usb_set_intfdata(interface, wlandev);
return result;
#endif
}
/*----------------------------------------------------------------
* prism2sta_disconnect_usb
*
* Called when a device previously claimed by probe is removed
* from the USB.
*
* Arguments:
* dev ptr to the usb_device struct
* ptr ptr returned by probe() when the device
* was claimed.
*
* Returns:
* Nothing
*
* Side effects:
*
* Call context:
* process
----------------------------------------------------------------*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
static void __devexit
prism2sta_disconnect_usb(struct usb_device *dev, void *ptr)
#else
static void
prism2sta_disconnect_usb(struct usb_interface *interface)
#endif
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
wlandevice_t *wlandev;
#else
wlandevice_t *wlandev = (wlandevice_t*)ptr;
#endif
DBFENTER;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
wlandev = (wlandevice_t *) usb_get_intfdata(interface);
#endif
if ( wlandev != NULL ) {
LIST_HEAD(cleanlist);
struct list_head *entry;
struct list_head *temp;
unsigned long flags;
hfa384x_t *hw = wlandev->priv;
if (!hw)
goto exit;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
p80211netdev_hwremoved(wlandev);
list_splice_init(&hw->ctlxq.reapable, &cleanlist);
list_splice_init(&hw->ctlxq.completing, &cleanlist);
list_splice_init(&hw->ctlxq.pending, &cleanlist);
list_splice_init(&hw->ctlxq.active, &cleanlist);
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
/* There's no hardware to shutdown, but the driver
* might have some tasks or tasklets that must be
* stopped before we can tear everything down.
*/
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
del_singleshot_timer_sync(&hw->throttle);
del_singleshot_timer_sync(&hw->reqtimer);
del_singleshot_timer_sync(&hw->resptimer);
/* Unlink all the URBs. This "removes the wheels"
* from the entire CTLX handling mechanism.
*/
usb_kill_urb(&hw->rx_urb);
usb_kill_urb(&hw->tx_urb);
usb_kill_urb(&hw->ctlx_urb);
tasklet_kill(&hw->completion_bh);
tasklet_kill(&hw->reaper_bh);
flush_scheduled_work();
/* Now we complete any outstanding commands
* and tell everyone who is waiting for their
* responses that we have shut down.
*/
list_for_each(entry, &cleanlist) {
hfa384x_usbctlx_t *ctlx;
ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
complete(&ctlx->done);
}
/* Give any outstanding synchronous commands
* a chance to complete. All they need to do
* is "wake up", so that's easy.
* (I'd like a better way to do this, really.)
*/
msleep(100);
/* Now delete the CTLXs, because no-one else can now. */
list_for_each_safe(entry, temp, &cleanlist) {
hfa384x_usbctlx_t *ctlx;
ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
kfree(ctlx);
}
/* Unhook the wlandev */
unregister_wlandev(wlandev);
wlan_unsetup(wlandev);
#ifndef NEW_MODULE_CODE
usb_dec_dev_use(hw->usb);
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
usb_put_dev(hw->usb);
#endif
hfa384x_destroy(hw);
kfree(hw);
kfree(wlandev);
}
exit:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
usb_set_intfdata(interface, NULL);
#endif
DBFEXIT;
}
static struct usb_driver prism2_usb_driver = {
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,19)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
.owner = THIS_MODULE,
#endif
.name = "prism2_usb",
.probe = prism2sta_probe_usb,
.disconnect = prism2sta_disconnect_usb,
.id_table = usb_prism_tbl,
/* fops, minor? */
};
#ifdef MODULE
static int __init prism2usb_init(void)
{
DBFENTER;
WLAN_LOG_NOTICE("%s Loaded\n", version);
WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info);
/* This call will result in calls to prism2sta_probe_usb. */
return usb_register(&prism2_usb_driver);
DBFEXIT;
};
static void __exit prism2usb_cleanup(void)
{
DBFENTER;
usb_deregister(&prism2_usb_driver);
printk(KERN_NOTICE "%s Unloaded\n", version);
DBFEXIT;
};
module_init(prism2usb_init);
module_exit(prism2usb_cleanup);
#endif // module
/* src/prism2/driver/prism2mgmt.c
*
* Management request handler functions.
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* The functions in this file handle management requests sent from
* user mode.
*
* Most of these functions have two separate blocks of code that are
* conditional on whether this is a station or an AP. This is used
* to separate out the STA and AP responses to these management primitives.
* It's a choice (good, bad, indifferent?) to have the code in the same
* place so it's clear that the same primitive is implemented in both
* cases but has different behavior.
*
* --------------------------------------------------------------------
*/
/*================================================================*/
/* System Includes */
#define WLAN_DBVAR prism2_debug
#include "version.h"
#include <linux/version.h>
#include <linux/if_arp.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <linux/random.h>
#if (WLAN_HOSTIF == WLAN_USB)
#include <linux/usb.h>
#endif
#if (WLAN_HOSTIF == WLAN_PCMCIA)
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
#endif
#include "wlan_compat.h"
/*================================================================*/
/* Project Includes */
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211mgmt.h"
#include "p80211conv.h"
#include "p80211msg.h"
#include "p80211netdev.h"
#include "p80211metadef.h"
#include "p80211metastruct.h"
#include "hfa384x.h"
#include "prism2mgmt.h"
/*================================================================*/
/* Local Constants */
/*================================================================*/
/* Local Macros */
/* Converts 802.11 format rate specifications to prism2 */
#define p80211rate_to_p2bit(n) ((((n)&~BIT7) == 2) ? BIT0 : \
(((n)&~BIT7) == 4) ? BIT1 : \
(((n)&~BIT7) == 11) ? BIT2 : \
(((n)&~BIT7) == 22) ? BIT3 : 0)
/*================================================================*/
/* Local Types */
/*================================================================*/
/* Local Static Definitions */
/*================================================================*/
/* Local Function Declarations */
/*================================================================*/
/* Function Definitions */
/*----------------------------------------------------------------
* prism2mgmt_powermgmt
*
* Set the power management state of this station's MAC.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_powermgmt_t *msg = msgp;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/*
* Set CNFPMENABLED (on or off)
* Set CNFMULTICASTRX (if PM on, otherwise clear)
* Spout a notice stating that SleepDuration and
* HoldoverDuration and PMEPS also have an impact.
*/
/* Powermgmt is currently unsupported for STA */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
} else {
/*** ACCESS POINT ***/
/* Powermgmt is never supported for AP */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_scan
*
* Initiate a scan for BSSs.
*
* This function corresponds to MLME-scan.request and part of
* MLME-scan.confirm. As far as I can tell in the standard, there
* are no restrictions on when a scan.request may be issued. We have
* to handle in whatever state the driver/MAC happen to be.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_scan_t *msg = msgp;
UINT16 roamingmode, word;
int i, timeout;
int istmpenable = 0;
hfa384x_HostScanRequest_data_t scanreq;
DBFENTER;
if (hw->ap) {
WLAN_LOG_ERROR("Prism2 in AP mode cannot perform scans.\n");
result = 1;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
goto exit;
}
/* gatekeeper check */
if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
hw->ident_sta_fw.minor,
hw->ident_sta_fw.variant) <
HFA384x_FIRMWARE_VERSION(1,3,2)) {
WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n");
result = 1;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
goto exit;
}
memset(&scanreq, 0, sizeof(scanreq));
/* save current roaming mode */
result = hfa384x_drvr_getconfig16(hw,
HFA384x_RID_CNFROAMINGMODE, &roamingmode);
if ( result ) {
WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n",
result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* drop into mode 3 for the scan */
result = hfa384x_drvr_setconfig16(hw,
HFA384x_RID_CNFROAMINGMODE,
HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
if ( result ) {
WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n",
result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* active or passive? */
if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
hw->ident_sta_fw.minor,
hw->ident_sta_fw.variant) >
HFA384x_FIRMWARE_VERSION(1,5,0)) {
if (msg->scantype.data != P80211ENUM_scantype_active) {
word = host2hfa384x_16(msg->maxchanneltime.data);
} else {
word = 0;
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word);
if ( result ) {
WLAN_LOG_WARNING("Passive scan not supported with "
"current firmware. (<1.5.1)\n");
}
}
/* set up the txrate to be 2MBPS. Should be fastest basicrate... */
word = HFA384x_RATEBIT_2;
scanreq.txRate = host2hfa384x_16(word);
/* set up the channel list */
word = 0;
for (i = 0; i < msg->channellist.data.len; i++) {
UINT8 channel = msg->channellist.data.data[i];
if (channel > 14) continue;
/* channel 1 is BIT0 ... channel 14 is BIT13 */
word |= (1 << (channel-1));
}
scanreq.channelList = host2hfa384x_16(word);
/* set up the ssid, if present. */
scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len);
memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
/* Enable the MAC port if it's not already enabled */
result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
if ( result ) {
WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. "
"result=%d\n", result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
if (word == HFA384x_PORTSTATUS_DISABLED) {
UINT16 wordbuf[17];
result = hfa384x_drvr_setconfig16(hw,
HFA384x_RID_CNFROAMINGMODE,
HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
if ( result ) {
WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* Construct a bogus SSID and assign it to OwnSSID and
* DesiredSSID
*/
wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN);
get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
wordbuf, HFA384x_RID_CNFOWNSSID_LEN);
if ( result ) {
WLAN_LOG_ERROR("Failed to set OwnSSID.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN);
if ( result ) {
WLAN_LOG_ERROR("Failed to set DesiredSSID.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* bsstype */
result = hfa384x_drvr_setconfig16(hw,
HFA384x_RID_CNFPORTTYPE,
HFA384x_PORTTYPE_IBSS);
if ( result ) {
WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* ibss options */
result = hfa384x_drvr_setconfig16(hw,
HFA384x_RID_CREATEIBSS,
HFA384x_CREATEIBSS_JOINCREATEIBSS);
if ( result ) {
WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
result = hfa384x_drvr_enable(hw, 0);
if ( result ) {
WLAN_LOG_ERROR("drvr_enable(0) failed. "
"result=%d\n", result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
istmpenable = 1;
}
/* Figure out our timeout first Kus, then HZ */
timeout = msg->channellist.data.len * msg->maxchanneltime.data;
timeout = (timeout * HZ)/1000;
/* Issue the scan request */
hw->scanflag = 0;
WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq));
result = hfa384x_drvr_setconfig( hw,
HFA384x_RID_HOSTSCAN, &scanreq,
sizeof(hfa384x_HostScanRequest_data_t));
if ( result ) {
WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n",
result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* sleep until info frame arrives */
wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
if (hw->scanflag == -1)
hw->scanflag = 0;
msg->numbss.data = hw->scanflag;
hw->scanflag = 0;
/* Disable port if we temporarily enabled it. */
if (istmpenable) {
result = hfa384x_drvr_disable(hw, 0);
if ( result ) {
WLAN_LOG_ERROR("drvr_disable(0) failed. "
"result=%d\n", result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
}
/* restore original roaming mode */
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
roamingmode);
if ( result ) {
WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n",
result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
goto exit;
}
result = 0;
msg->resultcode.data = P80211ENUM_resultcode_success;
exit:
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_scan_results
*
* Retrieve the BSS description for one of the BSSs identified in
* a scan.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
p80211msg_dot11req_scan_results_t *req;
hfa384x_t *hw = wlandev->priv;
hfa384x_HScanResultSub_t *item = NULL;
int count;
DBFENTER;
req = (p80211msg_dot11req_scan_results_t *) msgp;
req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
if (hw->ap) {
result = 1;
req->resultcode.data = P80211ENUM_resultcode_not_supported;
goto exit;
}
if (! hw->scanresults) {
WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n");
result = 2;
req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
goto exit;
}
count = (hw->scanresults->framelen - 3) / 32;
if (count > 32) count = 32;
if (req->bssindex.data >= count) {
WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n",
req->bssindex.data, count);
result = 2;
req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
goto exit;
}
item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]);
/* signal and noise */
req->signal.status = P80211ENUM_msgitem_status_data_ok;
req->noise.status = P80211ENUM_msgitem_status_data_ok;
req->signal.data = hfa384x2host_16(item->sl);
req->noise.data = hfa384x2host_16(item->anl);
/* BSSID */
req->bssid.status = P80211ENUM_msgitem_status_data_ok;
req->bssid.data.len = WLAN_BSSID_LEN;
memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);
/* SSID */
req->ssid.status = P80211ENUM_msgitem_status_data_ok;
req->ssid.data.len = hfa384x2host_16(item->ssid.len);
memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
/* supported rates */
for (count = 0; count < 10 ; count++)
if (item->supprates[count] == 0)
break;
#define REQBASICRATE(N) \
if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \
req->basicrate ## N .data = item->supprates[(N)-1]; \
req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \
}
REQBASICRATE(1);
REQBASICRATE(2);
REQBASICRATE(3);
REQBASICRATE(4);
REQBASICRATE(5);
REQBASICRATE(6);
REQBASICRATE(7);
REQBASICRATE(8);
#define REQSUPPRATE(N) \
if (count >= N) { \
req->supprate ## N .data = item->supprates[(N)-1]; \
req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \
}
REQSUPPRATE(1);
REQSUPPRATE(2);
REQSUPPRATE(3);
REQSUPPRATE(4);
REQSUPPRATE(5);
REQSUPPRATE(6);
REQSUPPRATE(7);
REQSUPPRATE(8);
/* beacon period */
req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
req->beaconperiod.data = hfa384x2host_16(item->bcnint);
/* timestamps */
req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
req->timestamp.data = jiffies;
req->localtime.status = P80211ENUM_msgitem_status_data_ok;
req->localtime.data = jiffies;
/* atim window */
req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
req->ibssatimwindow.data = hfa384x2host_16(item->atim);
/* Channel */
req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
req->dschannel.data = hfa384x2host_16(item->chid);
/* capinfo bits */
count = hfa384x2host_16(item->capinfo);
/* privacy flag */
req->privacy.status = P80211ENUM_msgitem_status_data_ok;
req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);
/* cfpollable */
req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);
/* cfpollreq */
req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
/* bsstype */
req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
P80211ENUM_bsstype_infrastructure :
P80211ENUM_bsstype_independent;
// item->proberesp_rate
/*
req->fhdwelltime
req->fhhopset
req->fhhoppattern
req->fhhopindex
req->cfpdurremaining
*/
result = 0;
req->resultcode.data = P80211ENUM_resultcode_success;
exit:
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_join
*
* Join a BSS whose BSS description was previously obtained with
* a scan.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_join(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_join_t *msg = msgp;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/* TODO: Implement after scan */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
} else {
/*** ACCESS POINT ***/
/* Never supported by APs */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_p2_join
*
* Join a specific BSS
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_join_t *msg = msgp;
UINT16 reg;
p80211pstrd_t *pstr;
UINT8 bytebuf[256];
hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
hfa384x_JoinRequest_data_t joinreq;
DBFENTER;
if (!hw->ap) {
wlandev->macmode = WLAN_MACMODE_NONE;
/*** STATION ***/
/* Set the PortType */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
/* ess port */
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1);
if ( result ) {
WLAN_LOG_ERROR("Failed to set Port Type\n");
goto failed;
}
/* Set the auth type */
if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
} else {
reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
if ( result ) {
WLAN_LOG_ERROR("Failed to set Authentication\n");
goto failed;
}
/* Turn off all roaming */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, 3);
if ( result ) {
WLAN_LOG_ERROR("Failed to Turn off Roaming\n");
goto failed;
}
/* Basic rates */
reg = 0;
if ( msg->basicrate1.status == P80211ENUM_msgitem_status_data_ok ) {
reg = p80211rate_to_p2bit(msg->basicrate1.data);
}
if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->basicrate2.data);
}
if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->basicrate3.data);
}
if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->basicrate4.data);
}
if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->basicrate5.data);
}
if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->basicrate6.data);
}
if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->basicrate7.data);
}
if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->basicrate8.data);
}
if( reg == 0)
reg = 0x03;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, reg);
if ( result ) {
WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", reg);
goto failed;
}
/* Operational rates (supprates and txratecontrol) */
reg = 0;
if ( msg->operationalrate1.status == P80211ENUM_msgitem_status_data_ok ) {
reg = p80211rate_to_p2bit(msg->operationalrate1.data);
}
if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->operationalrate2.data);
}
if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->operationalrate3.data);
}
if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->operationalrate4.data);
}
if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->operationalrate5.data);
}
if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->operationalrate6.data);
}
if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->operationalrate7.data);
}
if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
reg |= p80211rate_to_p2bit(msg->operationalrate8.data);
}
if( reg == 0)
reg = 0x0f;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, reg);
if ( result ) {
WLAN_LOG_ERROR("Failed to set supprates=%d.\n", reg);
goto failed;
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg);
if ( result ) {
WLAN_LOG_ERROR("Failed to set txrates=%d.\n", reg);
goto failed;
}
/* Set the ssid */
memset(bytebuf, 0, 256);
pstr = (p80211pstrd_t*)&(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
result = hfa384x_drvr_setconfig(
hw, HFA384x_RID_CNFDESIREDSSID,
bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
if ( result ) {
WLAN_LOG_ERROR("Failed to set SSID\n");
goto failed;
}
/* Enable the Port */
result = hfa384x_cmd_enable(hw, 0);
if ( result ) {
WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
goto failed;
}
/* Fill in the join request */
joinreq.channel = msg->channel.data;
memcpy( joinreq.bssid, ((unsigned char *) &msg->bssid.data) + 1, WLAN_BSSID_LEN);
hw->joinreq = joinreq;
hw->join_ap = 1;
/* Send the join request */
result = hfa384x_drvr_setconfig( hw,
HFA384x_RID_JOINREQUEST,
&joinreq, HFA384x_RID_JOINREQUEST_LEN);
if(result != 0) {
WLAN_LOG_ERROR("Join request failed, result=%d.\n", result);
goto failed;
}
} else {
/*** ACCESS POINT ***/
/* Never supported by APs */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
}
goto done;
failed:
WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
done:
result = 0;
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_authenticate
*
* Station should be begin an authentication exchange.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_authenticate_t *msg = msgp;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/* TODO: Decide how we're going to handle this one w/ Prism2 */
/* It could be entertaining since Prism2 doesn't have */
/* an explicit way to control this */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
} else {
/*** ACCESS POINT ***/
/* Never supported by APs */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_deauthenticate
*
* Send a deauthenticate notification.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_deauthenticate_t *msg = msgp;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/* TODO: Decide how we're going to handle this one w/ Prism2 */
/* It could be entertaining since Prism2 doesn't have */
/* an explicit way to control this */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
} else {
/*** ACCESS POINT ***/
hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data);
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_associate
*
* Associate with an ESS.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
int result = 0;
p80211msg_dot11req_associate_t *msg = msgp;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
#if 0
/* Set the TxRates */
reg = 0x000f;
hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg);
#endif
/* Set the PortType */
/* ess port */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1);
/* Enable the Port */
hfa384x_drvr_enable(hw, 0);
/* Set the resultcode */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
} else {
/*** ACCESS POINT ***/
/* Never supported on AP */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_reassociate
*
* Renew association because of a BSS change.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_reassociate_t *msg = msgp;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/* TODO: Not supported yet...not sure how we're going to do it */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
} else {
/*** ACCESS POINT ***/
/* Never supported on AP */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_disassociate
*
* Send a disassociation notification.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_disassociate_t *msg = msgp;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/* TODO: Not supported yet...not sure how to do it */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
} else {
/*** ACCESS POINT ***/
hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data);
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_reset
*
* Reset the MAC and MSD. The p80211 layer has it's own handling
* that should be done before and after this function.
* Procedure:
* - disable system interrupts ??
* - disable MAC interrupts
* - restore system interrupts
* - issue the MAC initialize command
* - clear any MSD level state (including timers, queued events,
* etc.). Note that if we're removing timer'd/queue events, we may
* need to have remained in the system interrupt disabled state.
* We should be left in the same state that we're in following
* driver initialization.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer, MAY BE NULL! for a driver local
* call.
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread, commonly wlanctl, but might be rmmod/pci_close.
----------------------------------------------------------------*/
int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_reset_t *msg = msgp;
DBFENTER;
/*
* This is supported on both AP and STA and it's not allowed
* to fail.
*/
if ( msgp ) {
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
WLAN_LOG_INFO("dot11req_reset: the macaddress and "
"setdefaultmib arguments are currently unsupported.\n");
}
/*
* If we got this far, the MSD must be in the MSDRUNNING state
* therefore, we must stop and then restart the hw/MAC combo.
*/
hfa384x_drvr_stop(hw);
result = hfa384x_drvr_start(hw);
if (result != 0) {
WLAN_LOG_ERROR("dot11req_reset: Initialize command failed,"
" bad things will happen from here.\n");
return 0;
}
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_start
*
* Start a BSS. Any station can do this for IBSS, only AP for ESS.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_dot11req_start_t *msg = msgp;
p80211pstrd_t *pstr;
UINT8 bytebuf[80];
hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
hfa384x_PCFInfo_data_t *pcfinfo = (hfa384x_PCFInfo_data_t*)bytebuf;
UINT16 word;
DBFENTER;
wlandev->macmode = WLAN_MACMODE_NONE;
/* Set the SSID */
memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
if (!hw->ap) {
/*** ADHOC IBSS ***/
/* see if current f/w is less than 8c3 */
if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
hw->ident_sta_fw.minor,
hw->ident_sta_fw.variant) <
HFA384x_FIRMWARE_VERSION(0,8,3)) {
/* Ad-Hoc not quite supported on Prism2 */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
goto done;
}
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/*** STATION ***/
/* Set the REQUIRED config items */
/* SSID */
pstr = (p80211pstrd_t*)&(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
if ( result ) {
WLAN_LOG_ERROR("Failed to set CnfOwnSSID\n");
goto failed;
}
result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
if ( result ) {
WLAN_LOG_ERROR("Failed to set CnfDesiredSSID\n");
goto failed;
}
/* bsstype - we use the default in the ap firmware */
/* IBSS port */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0);
/* beacon period */
word = msg->beaconperiod.data;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
goto failed;
}
/* dschannel */
word = msg->dschannel.data;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
goto failed;
}
/* Basic rates */
word = p80211rate_to_p2bit(msg->basicrate1.data);
if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate2.data);
}
if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate3.data);
}
if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate4.data);
}
if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate5.data);
}
if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate6.data);
}
if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate7.data);
}
if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate8.data);
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
goto failed;
}
/* Operational rates (supprates and txratecontrol) */
word = p80211rate_to_p2bit(msg->operationalrate1.data);
if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate2.data);
}
if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate3.data);
}
if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate4.data);
}
if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate5.data);
}
if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate6.data);
}
if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate7.data);
}
if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate8.data);
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
goto failed;
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
goto failed;
}
/* Set the macmode so the frame setup code knows what to do */
if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
wlandev->macmode = WLAN_MACMODE_IBSS_STA;
/* lets extend the data length a bit */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
}
/* Enable the Port */
result = hfa384x_drvr_enable(hw, 0);
if ( result ) {
WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
goto failed;
}
msg->resultcode.data = P80211ENUM_resultcode_success;
goto done;
}
/*** ACCESS POINT ***/
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* Validate the command, if BSStype=infra is the tertiary loaded? */
if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
WLAN_LOG_ERROR("AP driver cannot create IBSS.\n");
goto failed;
} else if ( hw->cap_sup_sta.id != 5) {
WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n");
goto failed;
}
/* Set the REQUIRED config items */
/* SSID */
pstr = (p80211pstrd_t*)&(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
if ( result ) {
WLAN_LOG_ERROR("Failed to set SSID, result=0x%04x\n", result);
goto failed;
}
/* bsstype - we use the default in the ap firmware */
/* beacon period */
word = msg->beaconperiod.data;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
goto failed;
}
/* dschannel */
word = msg->dschannel.data;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
goto failed;
}
/* Basic rates */
word = p80211rate_to_p2bit(msg->basicrate1.data);
if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate2.data);
}
if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate3.data);
}
if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate4.data);
}
if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate5.data);
}
if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate6.data);
}
if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate7.data);
}
if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->basicrate8.data);
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
goto failed;
}
/* Operational rates (supprates and txratecontrol) */
word = p80211rate_to_p2bit(msg->operationalrate1.data);
if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate2.data);
}
if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate3.data);
}
if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate4.data);
}
if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate5.data);
}
if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate6.data);
}
if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate7.data);
}
if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
word |= p80211rate_to_p2bit(msg->operationalrate8.data);
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
goto failed;
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL0, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
goto failed;
}
/* ibssatimwindow */
if (msg->ibssatimwindow.status == P80211ENUM_msgitem_status_data_ok) {
WLAN_LOG_INFO("prism2mgmt_start: atimwindow not used in "
"Infrastructure mode, ignored.\n");
}
/* DTIM period */
word = msg->dtimperiod.data;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNDTIMPER, word);
if ( result ) {
WLAN_LOG_ERROR("Failed to set dtim period=%d.\n", word);
goto failed;
}
/* probedelay */
if (msg->probedelay.status == P80211ENUM_msgitem_status_data_ok) {
WLAN_LOG_INFO("prism2mgmt_start: probedelay not "
"supported in prism2, ignored.\n");
}
/* cfpollable, cfpollreq, cfpperiod, cfpmaxduration */
if (msg->cfpollable.data == P80211ENUM_truth_true &&
msg->cfpollreq.data == P80211ENUM_truth_true ) {
WLAN_LOG_ERROR("cfpollable=cfpollreq=true is illegal.\n");
result = -1;
goto failed;
}
/* read the PCFInfo and update */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO,
pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN);
if ( result ) {
WLAN_LOG_INFO("prism2mgmt_start: read(pcfinfo) failed, "
"assume it's "
"not supported, pcf settings ignored.\n");
goto pcf_skip;
}
if ((msg->cfpollable.data == P80211ENUM_truth_false &&
msg->cfpollreq.data == P80211ENUM_truth_false) ) {
pcfinfo->MediumOccupancyLimit = 0;
pcfinfo->CFPPeriod = 0;
pcfinfo->CFPMaxDuration = 0;
pcfinfo->CFPFlags &= host2hfa384x_16((UINT16)~BIT0);
if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok ||
msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok ) {
WLAN_LOG_WARNING(
"Setting cfpperiod or cfpmaxduration when "
"cfpollable and cfreq are false is pointless.\n");
}
}
if ((msg->cfpollable.data == P80211ENUM_truth_true ||
msg->cfpollreq.data == P80211ENUM_truth_true) ) {
if ( msg->cfpollable.data == P80211ENUM_truth_true) {
pcfinfo->CFPFlags |= host2hfa384x_16((UINT16)BIT0);
}
if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok) {
pcfinfo->CFPPeriod = msg->cfpperiod.data;
pcfinfo->CFPPeriod = host2hfa384x_16(pcfinfo->CFPPeriod);
}
if ( msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok) {
pcfinfo->CFPMaxDuration = msg->cfpmaxduration.data;
pcfinfo->CFPMaxDuration = host2hfa384x_16(pcfinfo->CFPMaxDuration);
pcfinfo->MediumOccupancyLimit = pcfinfo->CFPMaxDuration;
}
}
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO,
pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN);
if ( result ) {
WLAN_LOG_ERROR("write(pcfinfo) failed.\n");
goto failed;
}
pcf_skip:
/* Set the macmode so the frame setup code knows what to do */
if ( msg->bsstype.data == P80211ENUM_bsstype_infrastructure ) {
wlandev->macmode = WLAN_MACMODE_ESS_AP;
/* lets extend the data length a bit */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
}
/* Set the BSSID to the same as our MAC */
memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN);
/* Enable the Port */
result = hfa384x_drvr_enable(hw, 0);
if ( result ) {
WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
goto failed;
}
msg->resultcode.data = P80211ENUM_resultcode_success;
goto done;
failed:
WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
done:
result = 0;
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_enable
*
* Start a BSS. Any station can do this for IBSS, only AP for ESS.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_enable_t *msg = msgp;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/* Ad-Hoc not quite supported on Prism2 */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
goto done;
}
/*** ACCESS POINT ***/
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* Is the tertiary loaded? */
if ( hw->cap_sup_sta.id != 5) {
WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n");
goto failed;
}
/* Set the macmode so the frame setup code knows what to do */
wlandev->macmode = WLAN_MACMODE_ESS_AP;
/* Set the BSSID to the same as our MAC */
memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN);
/* Enable the Port */
result = hfa384x_drvr_enable(hw, 0);
if ( result ) {
WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
goto failed;
}
msg->resultcode.data = P80211ENUM_resultcode_success;
goto done;
failed:
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
done:
result = 0;
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_readpda
*
* Collect the PDA data and put it in the message.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_readpda_t *msg = msgp;
int result;
DBFENTER;
/* We only support collecting the PDA when in the FWLOAD
* state.
*/
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
WLAN_LOG_ERROR(
"PDA may only be read "
"in the fwload state.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
} else {
/* Call drvr_readpda(), it handles the auxport enable
* and validating the returned PDA.
*/
result = hfa384x_drvr_readpda(
hw,
msg->pda.data,
HFA384x_PDA_LEN_MAX);
if (result) {
WLAN_LOG_ERROR(
"hfa384x_drvr_readpda() failed, "
"result=%d\n",
result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status =
P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
}
msg->pda.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
}
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_readcis
*
* Collect the CIS data and put it in the message.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp)
{
int result;
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_readcis_t *msg = msgp;
DBFENTER;
memset(msg->cis.data, 0, sizeof(msg->cis.data));
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CIS,
msg->cis.data, HFA384x_RID_CIS_LEN);
if ( result ) {
WLAN_LOG_INFO("prism2mgmt_readcis: read(cis) failed.\n");
msg->cis.status = P80211ENUM_msgitem_status_no_value;
msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
}
else {
msg->cis.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
}
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_auxport_state
*
* Enables/Disables the card's auxiliary port. Should be called
* before and after a sequence of auxport_read()/auxport_write()
* calls.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp)
{
p80211msg_p2req_auxport_state_t *msg = msgp;
#if (WLAN_HOSTIF != WLAN_USB)
hfa384x_t *hw = wlandev->priv;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
if (msg->enable.data == P80211ENUM_truth_true) {
if ( hfa384x_cmd_aux_enable(hw, 0) ) {
msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
} else {
msg->resultcode.data = P80211ENUM_resultcode_success;
}
} else {
hfa384x_cmd_aux_disable(hw);
msg->resultcode.data = P80211ENUM_resultcode_success;
}
#else /* !USB */
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
#endif /* WLAN_HOSTIF != WLAN_USB */
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_auxport_read
*
* Copies data from the card using the auxport. The auxport must
* have previously been enabled. Note: this is not the way to
* do downloads, see the [ram|flash]dl functions.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp)
{
#if (WLAN_HOSTIF != WLAN_USB)
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_auxport_read_t *msg = msgp;
UINT32 addr;
UINT32 len;
UINT8* buf;
UINT32 maxlen = sizeof(msg->data.data);
DBFENTER;
if ( hw->auxen ) {
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
if ( len <= maxlen ) { /* max read/write size */
hfa384x_copy_from_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len);
msg->resultcode.data = P80211ENUM_resultcode_success;
} else {
WLAN_LOG_DEBUG(1,"Attempt to read > maxlen from auxport.\n");
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
} else {
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
msg->data.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
#else
DBFENTER;
WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n");
DBFEXIT;
return 0;
#endif
}
/*----------------------------------------------------------------
* prism2mgmt_auxport_write
*
* Copies data to the card using the auxport. The auxport must
* have previously been enabled. Note: this is not the way to
* do downloads, see the [ram|flash]dl functions.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp)
{
#if (WLAN_HOSTIF != WLAN_USB)
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_auxport_write_t *msg = msgp;
UINT32 addr;
UINT32 len;
UINT8* buf;
UINT32 maxlen = sizeof(msg->data.data);
DBFENTER;
if ( hw->auxen ) {
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
if ( len <= maxlen ) { /* max read/write size */
hfa384x_copy_to_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len);
} else {
WLAN_LOG_DEBUG(1,"Attempt to write > maxlen from auxport.\n");
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
} else {
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
msg->data.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
#else
DBFENTER;
WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n");
DBFEXIT;
return 0;
#endif
}
/*----------------------------------------------------------------
* prism2mgmt_low_level
*
* Puts the card into the desired test mode.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_low_level_t *msg = msgp;
hfa384x_metacmd_t cmd;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* call some routine to execute the test command */
cmd.cmd = (UINT16) msg->command.data;
cmd.parm0 = (UINT16) msg->param0.data;
cmd.parm1 = (UINT16) msg->param1.data;
cmd.parm2 = (UINT16) msg->param2.data;
hfa384x_drvr_low_level(hw,&cmd);
msg->resp0.data = (UINT32) cmd.result.resp0;
msg->resp1.data = (UINT32) cmd.result.resp1;
msg->resp2.data = (UINT32) cmd.result.resp2;
msg->resultcode.data = P80211ENUM_resultcode_success;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_test_command
*
* Puts the card into the desired test mode.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_test_command_t *msg = msgp;
hfa384x_metacmd_t cmd;
DBFENTER;
cmd.cmd = ((UINT16) msg->testcode.data) << 8 | 0x38;
cmd.parm0 = (UINT16) msg->testparam.data;
cmd.parm1 = 0;
cmd.parm2 = 0;
/* call some routine to execute the test command */
hfa384x_drvr_low_level(hw,&cmd);
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
msg->status.status = P80211ENUM_msgitem_status_data_ok;
msg->status.data = cmd.result.status;
msg->resp0.status = P80211ENUM_msgitem_status_data_ok;
msg->resp0.data = cmd.result.resp0;
msg->resp1.status = P80211ENUM_msgitem_status_data_ok;
msg->resp1.data = cmd.result.resp1;
msg->resp2.status = P80211ENUM_msgitem_status_data_ok;
msg->resp2.data = cmd.result.resp2;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_mmi_read
*
* Read from one of the MMI registers.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_mmi_read_t *msg = msgp;
UINT32 resp = 0;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* call some routine to execute the test command */
hfa384x_drvr_mmi_read(hw, msg->addr.data, &resp);
/* I'm not sure if this is "architecturally" correct, but it
is expedient. */
msg->value.status = P80211ENUM_msgitem_status_data_ok;
msg->value.data = resp;
msg->resultcode.data = P80211ENUM_resultcode_success;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_mmi_write
*
* Write a data value to one of the MMI registers.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_mmi_write_t *msg = msgp;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* call some routine to execute the test command */
hfa384x_drvr_mmi_write(hw, msg->addr.data, msg->data.data);
msg->resultcode.data = P80211ENUM_resultcode_success;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_ramdl_state
*
* Establishes the beginning/end of a card RAM download session.
*
* It is expected that the ramdl_write() function will be called
* one or more times between the 'enable' and 'disable' calls to
* this function.
*
* Note: This function should not be called when a mac comm port
* is active.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_ramdl_state_t *msg = msgp;
DBFENTER;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
WLAN_LOG_ERROR(
"ramdl_state(): may only be called "
"in the fwload state.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
}
/*
** Note: Interrupts are locked out if this is an AP and are NOT
** locked out if this is a station.
*/
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
if ( msg->enable.data == P80211ENUM_truth_true ) {
if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) {
msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
} else {
msg->resultcode.data = P80211ENUM_resultcode_success;
}
} else {
hfa384x_drvr_ramdl_disable(hw);
msg->resultcode.data = P80211ENUM_resultcode_success;
}
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_ramdl_write
*
* Writes a buffer to the card RAM using the download state. This
* is for writing code to card RAM. To just read or write raw data
* use the aux functions.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_ramdl_write_t *msg = msgp;
UINT32 addr;
UINT32 len;
UINT8 *buf;
DBFENTER;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
WLAN_LOG_ERROR(
"ramdl_write(): may only be called "
"in the fwload state.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
}
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* first validate the length */
if ( msg->len.data > sizeof(msg->data.data) ) {
msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters;
return 0;
}
/* call the hfa384x function to do the write */
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) {
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
msg->resultcode.data = P80211ENUM_resultcode_success;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_flashdl_state
*
* Establishes the beginning/end of a card Flash download session.
*
* It is expected that the flashdl_write() function will be called
* one or more times between the 'enable' and 'disable' calls to
* this function.
*
* Note: This function should not be called when a mac comm port
* is active.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_flashdl_state_t *msg = msgp;
DBFENTER;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
WLAN_LOG_ERROR(
"flashdl_state(): may only be called "
"in the fwload state.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
}
/*
** Note: Interrupts are locked out if this is an AP and are NOT
** locked out if this is a station.
*/
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
if ( msg->enable.data == P80211ENUM_truth_true ) {
if ( hfa384x_drvr_flashdl_enable(hw) ) {
msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
} else {
msg->resultcode.data = P80211ENUM_resultcode_success;
}
} else {
hfa384x_drvr_flashdl_disable(hw);
msg->resultcode.data = P80211ENUM_resultcode_success;
/* NOTE: At this point, the MAC is in the post-reset
* state and the driver is in the fwload state.
* We need to get the MAC back into the fwload
* state. To do this, we set the nsdstate to HWPRESENT
* and then call the ifstate function to redo everything
* that got us into the fwload state.
*/
wlandev->msdstate = WLAN_MSD_HWPRESENT;
result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
if (result != P80211ENUM_resultcode_success) {
WLAN_LOG_ERROR("prism2sta_ifstate(fwload) failed,"
"P80211ENUM_resultcode=%d\n", result);
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
result = -1;
}
}
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_flashdl_write
*
*
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_flashdl_write_t *msg = msgp;
UINT32 addr;
UINT32 len;
UINT8 *buf;
DBFENTER;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
WLAN_LOG_ERROR(
"flashdl_write(): may only be called "
"in the fwload state.\n");
msg->resultcode.data =
P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
}
/*
** Note: Interrupts are locked out if this is an AP and are NOT
** locked out if this is a station.
*/
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* first validate the length */
if ( msg->len.data > sizeof(msg->data.data) ) {
msg->resultcode.status =
P80211ENUM_resultcode_invalid_parameters;
return 0;
}
/* call the hfa384x function to do the write */
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) {
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
msg->resultcode.data = P80211ENUM_resultcode_success;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_dump_state
*
* Dumps the driver's and hardware's current state via the kernel
* log at KERN_NOTICE level.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp)
{
p80211msg_p2req_dump_state_t *msg = msgp;
int result = 0;
#if (WLAN_HOSTIF != WLAN_USB)
hfa384x_t *hw = wlandev->priv;
UINT16 auxbuf[15];
DBFENTER;
WLAN_LOG_NOTICE("prism2 driver and hardware state:\n");
if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
WLAN_LOG_ERROR("aux_enable failed, result=%d\n", result);
goto failed;
}
hfa384x_copy_from_aux(hw,
0x01e2,
HFA384x_AUX_CTL_EXTDS,
auxbuf,
sizeof(auxbuf));
hfa384x_cmd_aux_disable(hw);
WLAN_LOG_NOTICE(" cmac: FreeBlocks=%d\n", auxbuf[5]);
WLAN_LOG_NOTICE(" cmac: IntEn=0x%02x EvStat=0x%02x\n",
hfa384x_getreg(hw, HFA384x_INTEN),
hfa384x_getreg(hw, HFA384x_EVSTAT));
#ifdef USE_FID_STACK
WLAN_LOG_NOTICE(" drvr: txfid_top=%d stacksize=%d\n",
hw->txfid_top,HFA384x_DRVR_FIDSTACKLEN_MAX);
#else
WLAN_LOG_NOTICE(" drvr: txfid_head=%d txfid_tail=%d txfid_N=%d\n",
hw->txfid_head, hw->txfid_tail, hw->txfid_N);
#endif
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
#else /* (WLAN_HOSTIF == WLAN_USB) */
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
goto failed;
#endif /* (WLAN_HOSTIF != WLAN_USB) */
failed:
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_channel_info
*
* Issues a ChannelInfoRequest.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp)
{
p80211msg_p2req_channel_info_t *msg=msgp;
hfa384x_t *hw = wlandev->priv;
int result, i, n=0;
UINT16 channel_mask=0;
hfa384x_ChannelInfoRequest_data_t chinforeq;
// unsigned long now;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/* Not supported in STA f/w */
P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported);
goto done;
}
/*** ACCESS POINT ***/
#define CHINFO_TIMEOUT 2
P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success);
/* setting default value for channellist = all channels */
if (!msg->channellist.data) {
P80211_SET_INT(msg->channellist, 0x00007FFE);
}
/* setting default value for channeldwelltime = 100 ms */
if (!msg->channeldwelltime.data) {
P80211_SET_INT(msg->channeldwelltime, 100);
}
channel_mask = (UINT16) (msg->channellist.data >> 1);
for (i=0, n=0; i < 14; i++) {
if (channel_mask & (1<<i)) {
n++;
}
}
P80211_SET_INT(msg->numchinfo, n);
chinforeq.channelList = host2hfa384x_16(channel_mask);
chinforeq.channelDwellTime = host2hfa384x_16(msg->channeldwelltime.data);
atomic_set(&hw->channel_info.done, 1);
result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CHANNELINFOREQUEST,
&chinforeq, HFA384x_RID_CHANNELINFOREQUEST_LEN);
if ( result ) {
WLAN_LOG_ERROR("setconfig(CHANNELINFOREQUEST) failed. result=%d\n",
result);
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
goto done;
}
/*
now = jiffies;
while (atomic_read(&hw->channel_info.done) != 1) {
if ((jiffies - now) > CHINFO_TIMEOUT*HZ) {
WLAN_LOG_NOTICE("ChannelInfo results not received in %d seconds, aborting.\n",
CHINFO_TIMEOUT);
msg->resultcode.data = P80211ENUM_resultcode_timeout;
goto done;
}
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ/4);
current->state = TASK_RUNNING;
}
*/
done:
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_channel_info_results
*
* Returns required ChannelInfo result.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
p80211msg_p2req_channel_info_results_t *msg=msgp;
int result=0;
int channel;
DBFENTER;
if (!hw->ap) {
/*** STATION ***/
/* Not supported in STA f/w */
P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported);
goto done;
}
/*** ACCESS POINT ***/
switch (atomic_read(&hw->channel_info.done)) {
case 0: msg->resultcode.status = P80211ENUM_msgitem_status_no_value;
goto done;
case 1: msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata;
goto done;
}
P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success);
channel=msg->channel.data-1;
if (channel < 0 || ! (hw->channel_info.results.scanchannels & 1<<channel) ) {
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
goto done;
}
WLAN_LOG_DEBUG(2, "chinfo_results: channel %d, avg/peak level=%d/%d dB, active=%d\n",
channel+1,
hw->channel_info.results.result[channel].anl,
hw->channel_info.results.result[channel].pnl,
hw->channel_info.results.result[channel].active
);
P80211_SET_INT(msg->avgnoiselevel, hw->channel_info.results.result[channel].anl);
P80211_SET_INT(msg->peaknoiselevel, hw->channel_info.results.result[channel].pnl);
P80211_SET_INT(msg->bssactive, hw->channel_info.results.result[channel].active &
HFA384x_CHINFORESULT_BSSACTIVE
? P80211ENUM_truth_true
: P80211ENUM_truth_false) ;
P80211_SET_INT(msg->pcfactive, hw->channel_info.results.result[channel].active &
HFA384x_CHINFORESULT_PCFACTIVE
? P80211ENUM_truth_true
: P80211ENUM_truth_false) ;
done:
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_autojoin
*
* Associate with an ESS.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
{
hfa384x_t *hw = wlandev->priv;
int result = 0;
UINT16 reg;
UINT16 port_type;
p80211msg_lnxreq_autojoin_t *msg = msgp;
p80211pstrd_t *pstr;
UINT8 bytebuf[256];
hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
DBFENTER;
wlandev->macmode = WLAN_MACMODE_NONE;
/* Set the SSID */
memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
if (hw->ap) {
/*** ACCESS POINT ***/
/* Never supported on AP */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
goto done;
}
/* Disable the Port */
hfa384x_drvr_disable(hw, 0);
/*** STATION ***/
/* Set the TxRates */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
/* Set the auth type */
if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
} else {
reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
}
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
/* Set the ssid */
memset(bytebuf, 0, 256);
pstr = (p80211pstrd_t*)&(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
result = hfa384x_drvr_setconfig(
hw, HFA384x_RID_CNFDESIREDSSID,
bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
#if 0
/* we can use the new-fangled auto-unknown mode if the firmware
is 1.3.3 or newer */
if (HFA384x_FIRMARE_VERSION(hw->ident_sta_fw.major,
hw->ident_sta_fw.minor,
hw->ident_sta_fw.variant) >=
HFA384x_FIRMWARE_VERSION(1,3,3)) {
/* Set up the IBSS options */
reg = HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS;
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, reg);
/* Set the PortType */
port_type = HFA384x_PORTTYPE_IBSS;
} else {
port_type = HFA384x_PORTTYPE_BSS;
}
#else
port_type = HFA384x_PORTTYPE_BSS;
#endif
/* Set the PortType */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
/* Enable the Port */
hfa384x_drvr_enable(hw, 0);
/* Set the resultcode */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
done:
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2mgmt_wlansniff
*
* Start or stop sniffing.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
{
int result = 0;
p80211msg_lnxreq_wlansniff_t *msg = msgp;
hfa384x_t *hw = wlandev->priv;
UINT16 word;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
switch (msg->enable.data)
{
case P80211ENUM_truth_false:
/* Confirm that we're in monitor mode */
if ( wlandev->netdev->type == ARPHRD_ETHER ) {
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
result = 0;
goto exit;
}
/* Disable monitor mode */
result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to disable monitor mode, result=%d\n",
result);
goto failed;
}
/* Disable port 0 */
result = hfa384x_drvr_disable(hw, 0);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to disable port 0 after sniffing, result=%d\n",
result);
goto failed;
}
/* Clear the driver state */
wlandev->netdev->type = ARPHRD_ETHER;
/* Restore the wepflags */
result = hfa384x_drvr_setconfig16(hw,
HFA384x_RID_CNFWEPFLAGS,
hw->presniff_wepflags);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to restore wepflags=0x%04x, result=%d\n",
hw->presniff_wepflags,
result);
goto failed;
}
/* Set the port to its prior type and enable (if necessary) */
if (hw->presniff_port_type != 0 ) {
word = hw->presniff_port_type;
result = hfa384x_drvr_setconfig16(hw,
HFA384x_RID_CNFPORTTYPE, word);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to restore porttype, result=%d\n",
result);
goto failed;
}
/* Enable the port */
result = hfa384x_drvr_enable(hw, 0);
if ( result ) {
WLAN_LOG_DEBUG(1, "failed to enable port to presniff setting, result=%d\n", result);
goto failed;
}
} else {
result = hfa384x_drvr_disable(hw, 0);
}
WLAN_LOG_INFO("monitor mode disabled\n");
msg->resultcode.data = P80211ENUM_resultcode_success;
result = 0;
goto exit;
break;
case P80211ENUM_truth_true:
/* Disable the port (if enabled), only check Port 0 */
if ( hw->port_enabled[0]) {
if (wlandev->netdev->type == ARPHRD_ETHER) {
/* Save macport 0 state */
result = hfa384x_drvr_getconfig16(hw,
HFA384x_RID_CNFPORTTYPE,
&(hw->presniff_port_type));
if ( result ) {
WLAN_LOG_DEBUG(1,"failed to read porttype, result=%d\n", result);
goto failed;
}
/* Save the wepflags state */
result = hfa384x_drvr_getconfig16(hw,
HFA384x_RID_CNFWEPFLAGS,
&(hw->presniff_wepflags));
if ( result ) {
WLAN_LOG_DEBUG(1,"failed to read wepflags, result=%d\n", result);
goto failed;
}
hfa384x_drvr_stop(hw);
result = hfa384x_drvr_start(hw);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to restart the card for sniffing, result=%d\n",
result);
goto failed;
}
} else {
/* Disable the port */
result = hfa384x_drvr_disable(hw, 0);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to enable port for sniffing, result=%d\n",
result);
goto failed;
}
}
} else {
hw->presniff_port_type = 0;
}
/* Set the channel we wish to sniff */
word = msg->channel.data;
result = hfa384x_drvr_setconfig16(hw,
HFA384x_RID_CNFOWNCHANNEL, word);
hw->sniff_channel=word;
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to set channel %d, result=%d\n",
word,
result);
goto failed;
}
/* Now if we're already sniffing, we can skip the rest */
if (wlandev->netdev->type != ARPHRD_ETHER) {
/* Set the port type to pIbss */
word = HFA384x_PORTTYPE_PSUEDOIBSS;
result = hfa384x_drvr_setconfig16(hw,
HFA384x_RID_CNFPORTTYPE, word);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to set porttype %d, result=%d\n",
word,
result);
goto failed;
}
if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) {
/* Set the wepflags for no decryption */
word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word);
}
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to set wepflags=0x%04x, result=%d\n",
word,
result);
goto failed;
}
}
/* Do we want to strip the FCS in monitor mode? */
if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) && (msg->stripfcs.data == P80211ENUM_truth_true)) {
hw->sniff_fcs = 0;
} else {
hw->sniff_fcs = 1;
}
/* Do we want to truncate the packets? */
if (msg->packet_trunc.status == P80211ENUM_msgitem_status_data_ok) {
hw->sniff_truncate = msg->packet_trunc.data;
} else {
hw->sniff_truncate = 0;
}
/* Enable the port */
result = hfa384x_drvr_enable(hw, 0);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to enable port for sniffing, result=%d\n",
result);
goto failed;
}
/* Enable monitor mode */
result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
if ( result ) {
WLAN_LOG_DEBUG(1,
"failed to enable monitor mode, result=%d\n",
result);
goto failed;
}
if (wlandev->netdev->type == ARPHRD_ETHER) {
WLAN_LOG_INFO("monitor mode enabled\n");
}
/* Set the driver state */
/* Do we want the prism2 header? */
if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) {
hw->sniffhdr = 0;
wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
} else if ((msg->wlanheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->wlanheader.data == P80211ENUM_truth_true)) {
hw->sniffhdr = 1;
wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
} else {
wlandev->netdev->type = ARPHRD_IEEE80211;
}
msg->resultcode.data = P80211ENUM_resultcode_success;
result = 0;
goto exit;
break;
default:
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
result = 0;
goto exit;
break;
}
failed:
msg->resultcode.data = P80211ENUM_resultcode_refused;
result = 0;
exit:
DBFEXIT;
return result;
}
/* prism2mgmt.h
*
* Declares the mgmt command handler functions
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file contains the constants and data structures for interaction
* with the hfa384x Wireless LAN (WLAN) Media Access Contoller (MAC).
* The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset.
*
* [Implementation and usage notes]
*
* [References]
* CW10 Programmer's Manual v1.5
* IEEE 802.11 D10.0
*
* --------------------------------------------------------------------
*/
#ifndef _PRISM2MGMT_H
#define _PRISM2MGMT_H
/*=============================================================*/
/*------ Constants --------------------------------------------*/
/*=============================================================*/
/*------ Macros -----------------------------------------------*/
/*=============================================================*/
/*------ Types and their related constants --------------------*/
/*=============================================================*/
/*------ Static variable externs ------------------------------*/
#if (WLAN_HOSTIF != WLAN_USB)
extern int prism2_bap_timeout;
extern int prism2_irq_evread_max;
#endif
extern int prism2_debug;
extern int prism2_reset_holdtime;
extern int prism2_reset_settletime;
/*=============================================================*/
/*--- Function Declarations -----------------------------------*/
/*=============================================================*/
UINT32
prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate);
void
prism2sta_ev_dtim(wlandevice_t *wlandev);
void
prism2sta_ev_infdrop(wlandevice_t *wlandev);
void
prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
void
prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status);
void
prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status);
void
prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
void
prism2sta_ev_alloc(wlandevice_t *wlandev);
int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_join(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_start(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_mm_state(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp);
/*---------------------------------------------------------------
* conversion functions going between wlan message data types and
* Prism2 data types
---------------------------------------------------------------*/
/* byte area conversion functions*/
void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr);
void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len);
/* byte string conversion functions*/
void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
/* integer conversion functions */
void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint);
void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint);
/* enumerated integer conversion functions */
void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid);
void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid);
/* functions to convert a bit area to/from an Operational Rate Set */
void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr);
void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr);
/* functions to convert Group Addresses */
void prism2mgmt_get_grpaddr(UINT32 did,
p80211pstrd_t *pstr, hfa384x_t *priv );
int prism2mgmt_set_grpaddr(UINT32 did,
UINT8 *prism2buf, p80211pstrd_t *pstr, hfa384x_t *priv );
int prism2mgmt_get_grpaddr_index( UINT32 did );
void prism2sta_processing_defer(struct work_struct *data);
void prism2sta_commsqual_defer(struct work_struct *data);
void prism2sta_commsqual_timer(unsigned long data);
/*=============================================================*/
/*--- Inline Function Definitions (if supported) --------------*/
/*=============================================================*/
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
/* src/prism2/driver/prism2sta.c
*
* Implements the station functionality for prism2
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* This file implements the module and linux pcmcia routines for the
* prism2 driver.
*
* --------------------------------------------------------------------
*/
/*================================================================*/
/* System Includes */
#define WLAN_DBVAR prism2_debug
#include "version.h"
#include <linux/version.h>
#include <linux/module.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25))
#include <linux/moduleparam.h>
#endif
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include <linux/tqueue.h>
#else
#include <linux/workqueue.h>
#endif
#include <asm/io.h>
#include <linux/delay.h>
#include <asm/byteorder.h>
#include <linux/if_arp.h>
#if (WLAN_HOSTIF == WLAN_PCMCIA)
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
#endif
#include "wlan_compat.h"
#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))
#include <linux/ioport.h>
#include <linux/pci.h>
#endif
/*================================================================*/
/* Project Includes */
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211mgmt.h"
#include "p80211conv.h"
#include "p80211msg.h"
#include "p80211netdev.h"
#include "p80211req.h"
#include "p80211metadef.h"
#include "p80211metastruct.h"
#include "hfa384x.h"
#include "prism2mgmt.h"
/*================================================================*/
/* Local Constants */
/*================================================================*/
/* Local Macros */
/*================================================================*/
/* Local Types */
/*================================================================*/
/* Local Static Definitions */
#if (WLAN_HOSTIF == WLAN_PCMCIA)
#define DRIVER_SUFFIX "_cs"
#elif (WLAN_HOSTIF == WLAN_PLX)
#define DRIVER_SUFFIX "_plx"
typedef char* dev_info_t;
#elif (WLAN_HOSTIF == WLAN_PCI)
#define DRIVER_SUFFIX "_pci"
typedef char* dev_info_t;
#elif (WLAN_HOSTIF == WLAN_USB)
#define DRIVER_SUFFIX "_usb"
typedef char* dev_info_t;
#else
#error "HOSTIF unsupported or undefined!"
#endif
static char *version = "prism2" DRIVER_SUFFIX ".o: " WLAN_RELEASE;
static dev_info_t dev_info = "prism2" DRIVER_SUFFIX;
#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)
#ifdef CONFIG_PM
static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state);
static int prism2sta_resume_pci(struct pci_dev *pdev);
#endif
#endif
#if (WLAN_HOSTIF == WLAN_PCI)
#endif /* WLAN_PCI */
static wlandevice_t *create_wlan(void);
/*----------------------------------------------------------------*/
/* --Module Parameters */
int prism2_reset_holdtime=30; /* Reset hold time in ms */
int prism2_reset_settletime=100; /* Reset settle time in ms */
#if (WLAN_HOSTIF == WLAN_USB)
static int prism2_doreset=0; /* Do a reset at init? */
#else
static int prism2_doreset=1; /* Do a reset at init? */
int prism2_bap_timeout=1000; /* BAP timeout */
int prism2_irq_evread_max=20; /* Maximum number of
* ev_reads (loops)
* in irq handler
*/
#endif
#ifdef WLAN_INCLUDE_DEBUG
int prism2_debug=0;
module_param( prism2_debug, int, 0644);
MODULE_PARM_DESC(prism2_debug, "prism2 debugging");
#endif
module_param( prism2_doreset, int, 0644);
MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization");
module_param( prism2_reset_holdtime, int, 0644);
MODULE_PARM_DESC( prism2_reset_holdtime, "reset hold time in ms");
module_param( prism2_reset_settletime, int, 0644);
MODULE_PARM_DESC( prism2_reset_settletime, "reset settle time in ms");
#if (WLAN_HOSTIF != WLAN_USB)
module_param( prism2_bap_timeout, int, 0644);
MODULE_PARM_DESC(prism2_bap_timeout, "BufferAccessPath Timeout in 10*n us");
module_param( prism2_irq_evread_max, int, 0644);
MODULE_PARM_DESC( prism2_irq_evread_max, "Maximim number of event reads in interrupt handler");
#endif
MODULE_LICENSE("Dual MPL/GPL");
/*================================================================*/
/* Local Function Declarations */
static int prism2sta_open(wlandevice_t *wlandev);
static int prism2sta_close(wlandevice_t *wlandev);
static void prism2sta_reset(wlandevice_t *wlandev );
static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);
static int prism2sta_getcardinfo(wlandevice_t *wlandev);
static int prism2sta_globalsetup(wlandevice_t *wlandev);
static int prism2sta_setmulticast(wlandevice_t *wlandev,
netdevice_t *dev);
static void prism2sta_inf_handover(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_tallies(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_hostscanresults(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_scanresults(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_chinforesults(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_linkstatus(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_assocstatus(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_authreq(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_authreq_defer(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
static void prism2sta_inf_psusercnt(
wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
#ifdef CONFIG_PROC_FS
static int
prism2sta_proc_read(
char *page,
char **start,
off_t offset,
int count,
int *eof,
void *data);
#endif
/*================================================================*/
/* Function Definitions */
/*----------------------------------------------------------------
* dmpmem
*
* Debug utility function to dump memory to the kernel debug log.
*
* Arguments:
* buf ptr data we want dumped
* len length of data
*
* Returns:
* nothing
* Side effects:
*
* Call context:
* process thread
* interrupt
----------------------------------------------------------------*/
inline void dmpmem(void *buf, int n)
{
int c;
for ( c= 0; c < n; c++) {
if ( (c % 16) == 0 ) printk(KERN_DEBUG"dmp[%d]: ", c);
printk("%02x ", ((UINT8*)buf)[c]);
if ( (c % 16) == 15 ) printk("\n");
}
if ( (c % 16) != 0 ) printk("\n");
}
/*----------------------------------------------------------------
* prism2sta_open
*
* WLAN device open method. Called from p80211netdev when kernel
* device open (start) method is called in response to the
* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
* from clear to set.
*
* Arguments:
* wlandev wlan device structure
*
* Returns:
* 0 success
* >0 f/w reported error
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
static int prism2sta_open(wlandevice_t *wlandev)
{
DBFENTER;
#ifdef ANCIENT_MODULE_CODE
MOD_INC_USE_COUNT;
#endif
/* We don't currently have to do anything else.
* The setup of the MAC should be subsequently completed via
* the mlme commands.
* Higher layers know we're ready from dev->start==1 and
* dev->tbusy==0. Our rx path knows to pass up received/
* frames because of dev->flags&IFF_UP is true.
*/
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2sta_close
*
* WLAN device close method. Called from p80211netdev when kernel
* device close method is called in response to the
* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
* from set to clear.
*
* Arguments:
* wlandev wlan device structure
*
* Returns:
* 0 success
* >0 f/w reported error
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
static int prism2sta_close(wlandevice_t *wlandev)
{
DBFENTER;
#ifdef ANCIENT_MODULE_CODE
MOD_DEC_USE_COUNT;
#endif
/* We don't currently have to do anything else.
* Higher layers know we're not ready from dev->start==0 and
* dev->tbusy==1. Our rx path knows to not pass up received
* frames because of dev->flags&IFF_UP is false.
*/
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2sta_reset
*
* Not currently implented.
*
* Arguments:
* wlandev wlan device structure
* none
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
static void prism2sta_reset(wlandevice_t *wlandev )
{
DBFENTER;
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_txframe
*
* Takes a frame from p80211 and queues it for transmission.
*
* Arguments:
* wlandev wlan device structure
* pb packet buffer struct. Contains an 802.11
* data frame.
* p80211_hdr points to the 802.11 header for the packet.
* Returns:
* 0 Success and more buffs available
* 1 Success but no more buffs
* 2 Allocation failure
* 4 Buffer full or queue busy
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
p80211_hdr_t *p80211_hdr,
p80211_metawep_t *p80211_wep)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
int result;
DBFENTER;
/* If necessary, set the 802.11 WEP bit */
if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) {
p80211_hdr->a3.fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
}
result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep);
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2sta_mlmerequest
*
* wlan command message handler. All we do here is pass the message
* over to the prism2sta_mgmt_handler.
*
* Arguments:
* wlandev wlan device structure
* msg wlan command message
* Returns:
* 0 success
* <0 successful acceptance of message, but we're
* waiting for an async process to finish before
* we're done with the msg. When the asynch
* process is done, we'll call the p80211
* function p80211req_confirm() .
* >0 An error occurred while we were handling
* the message.
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
int result = 0;
DBFENTER;
switch( msg->msgcode )
{
case DIDmsg_dot11req_mibget :
WLAN_LOG_DEBUG(2,"Received mibget request\n");
result = prism2mgmt_mibset_mibget(wlandev, msg);
break;
case DIDmsg_dot11req_mibset :
WLAN_LOG_DEBUG(2,"Received mibset request\n");
result = prism2mgmt_mibset_mibget(wlandev, msg);
break;
case DIDmsg_dot11req_powermgmt :
WLAN_LOG_DEBUG(2,"Received powermgmt request\n");
result = prism2mgmt_powermgmt(wlandev, msg);
break;
case DIDmsg_dot11req_scan :
WLAN_LOG_DEBUG(2,"Received scan request\n");
result = prism2mgmt_scan(wlandev, msg);
break;
case DIDmsg_dot11req_scan_results :
WLAN_LOG_DEBUG(2,"Received scan_results request\n");
result = prism2mgmt_scan_results(wlandev, msg);
break;
case DIDmsg_dot11req_join :
WLAN_LOG_DEBUG(2,"Received join request\n");
result = prism2mgmt_join(wlandev, msg);
break;
case DIDmsg_dot11req_authenticate :
WLAN_LOG_DEBUG(2,"Received authenticate request\n");
result = prism2mgmt_authenticate(wlandev, msg);
break;
case DIDmsg_dot11req_deauthenticate :
WLAN_LOG_DEBUG(2,"Received mlme deauthenticate request\n");
result = prism2mgmt_deauthenticate(wlandev, msg);
break;
case DIDmsg_dot11req_associate :
WLAN_LOG_DEBUG(2,"Received mlme associate request\n");
result = prism2mgmt_associate(wlandev, msg);
break;
case DIDmsg_dot11req_reassociate :
WLAN_LOG_DEBUG(2,"Received mlme reassociate request\n");
result = prism2mgmt_reassociate(wlandev, msg);
break;
case DIDmsg_dot11req_disassociate :
WLAN_LOG_DEBUG(2,"Received mlme disassociate request\n");
result = prism2mgmt_disassociate(wlandev, msg);
break;
case DIDmsg_dot11req_reset :
WLAN_LOG_DEBUG(2,"Received mlme reset request\n");
result = prism2mgmt_reset(wlandev, msg);
break;
case DIDmsg_dot11req_start :
WLAN_LOG_DEBUG(2,"Received mlme start request\n");
result = prism2mgmt_start(wlandev, msg);
break;
/*
* Prism2 specific messages
*/
case DIDmsg_p2req_join :
WLAN_LOG_DEBUG(2,"Received p2 join request\n");
result = prism2mgmt_p2_join(wlandev, msg);
break;
case DIDmsg_p2req_readpda :
WLAN_LOG_DEBUG(2,"Received mlme readpda request\n");
result = prism2mgmt_readpda(wlandev, msg);
break;
case DIDmsg_p2req_readcis :
WLAN_LOG_DEBUG(2,"Received mlme readcis request\n");
result = prism2mgmt_readcis(wlandev, msg);
break;
case DIDmsg_p2req_auxport_state :
WLAN_LOG_DEBUG(2,"Received mlme auxport_state request\n");
result = prism2mgmt_auxport_state(wlandev, msg);
break;
case DIDmsg_p2req_auxport_read :
WLAN_LOG_DEBUG(2,"Received mlme auxport_read request\n");
result = prism2mgmt_auxport_read(wlandev, msg);
break;
case DIDmsg_p2req_auxport_write :
WLAN_LOG_DEBUG(2,"Received mlme auxport_write request\n");
result = prism2mgmt_auxport_write(wlandev, msg);
break;
case DIDmsg_p2req_low_level :
WLAN_LOG_DEBUG(2,"Received mlme low_level request\n");
result = prism2mgmt_low_level(wlandev, msg);
break;
case DIDmsg_p2req_test_command :
WLAN_LOG_DEBUG(2,"Received mlme test_command request\n");
result = prism2mgmt_test_command(wlandev, msg);
break;
case DIDmsg_p2req_mmi_read :
WLAN_LOG_DEBUG(2,"Received mlme mmi_read request\n");
result = prism2mgmt_mmi_read(wlandev, msg);
break;
case DIDmsg_p2req_mmi_write :
WLAN_LOG_DEBUG(2,"Received mlme mmi_write request\n");
result = prism2mgmt_mmi_write(wlandev, msg);
break;
case DIDmsg_p2req_ramdl_state :
WLAN_LOG_DEBUG(2,"Received mlme ramdl_state request\n");
result = prism2mgmt_ramdl_state(wlandev, msg);
break;
case DIDmsg_p2req_ramdl_write :
WLAN_LOG_DEBUG(2,"Received mlme ramdl_write request\n");
result = prism2mgmt_ramdl_write(wlandev, msg);
break;
case DIDmsg_p2req_flashdl_state :
WLAN_LOG_DEBUG(2,"Received mlme flashdl_state request\n");
result = prism2mgmt_flashdl_state(wlandev, msg);
break;
case DIDmsg_p2req_flashdl_write :
WLAN_LOG_DEBUG(2,"Received mlme flashdl_write request\n");
result = prism2mgmt_flashdl_write(wlandev, msg);
break;
case DIDmsg_p2req_dump_state :
WLAN_LOG_DEBUG(2,"Received mlme dump_state request\n");
result = prism2mgmt_dump_state(wlandev, msg);
break;
case DIDmsg_p2req_channel_info :
WLAN_LOG_DEBUG(2,"Received mlme channel_info request\n");
result = prism2mgmt_channel_info(wlandev, msg);
break;
case DIDmsg_p2req_channel_info_results :
WLAN_LOG_DEBUG(2,"Received mlme channel_info_results request\n");
result = prism2mgmt_channel_info_results(wlandev, msg);
break;
/*
* Linux specific messages
*/
case DIDmsg_lnxreq_hostwep :
break; // ignore me.
case DIDmsg_lnxreq_ifstate :
{
p80211msg_lnxreq_ifstate_t *ifstatemsg;
WLAN_LOG_DEBUG(2,"Received mlme ifstate request\n");
ifstatemsg = (p80211msg_lnxreq_ifstate_t*)msg;
result = prism2sta_ifstate(wlandev, ifstatemsg->ifstate.data);
ifstatemsg->resultcode.status =
P80211ENUM_msgitem_status_data_ok;
ifstatemsg->resultcode.data = result;
result = 0;
}
break;
case DIDmsg_lnxreq_wlansniff :
WLAN_LOG_DEBUG(2,"Received mlme wlansniff request\n");
result = prism2mgmt_wlansniff(wlandev, msg);
break;
case DIDmsg_lnxreq_autojoin :
WLAN_LOG_DEBUG(2,"Received mlme autojoin request\n");
result = prism2mgmt_autojoin(wlandev, msg);
break;
case DIDmsg_p2req_enable :
WLAN_LOG_DEBUG(2,"Received mlme enable request\n");
result = prism2mgmt_enable(wlandev, msg);
break;
case DIDmsg_lnxreq_commsquality: {
p80211msg_lnxreq_commsquality_t *qualmsg;
WLAN_LOG_DEBUG(2,"Received commsquality request\n");
if (hw->ap)
break;
qualmsg = (p80211msg_lnxreq_commsquality_t*) msg;
qualmsg->link.status = P80211ENUM_msgitem_status_data_ok;
qualmsg->level.status = P80211ENUM_msgitem_status_data_ok;
qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok;
qualmsg->link.data = hfa384x2host_16(hw->qual.CQ_currBSS);
qualmsg->level.data = hfa384x2host_16(hw->qual.ASL_currBSS);
qualmsg->noise.data = hfa384x2host_16(hw->qual.ANL_currFC);
break;
}
default:
WLAN_LOG_WARNING("Unknown mgmt request message 0x%08x", msg->msgcode);
break;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2sta_ifstate
*
* Interface state. This is the primary WLAN interface enable/disable
* handler. Following the driver/load/deviceprobe sequence, this
* function must be called with a state of "enable" before any other
* commands will be accepted.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* A p80211 message resultcode value.
*
* Side effects:
*
* Call context:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
UINT32 prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
UINT32 result;
DBFENTER;
result = P80211ENUM_resultcode_implementation_failure;
WLAN_LOG_DEBUG(2, "Current MSD state(%d), requesting(%d)\n",
wlandev->msdstate, ifstate);
switch (ifstate)
{
case P80211ENUM_ifstate_fwload:
switch (wlandev->msdstate) {
case WLAN_MSD_HWPRESENT:
wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING;
/*
* Initialize the device+driver sufficiently
* for firmware loading.
*/
#if (WLAN_HOSTIF != WLAN_USB)
result=hfa384x_cmd_initialize(hw);
#else
if ((result=hfa384x_drvr_start(hw))) {
WLAN_LOG_ERROR(
"hfa384x_drvr_start() failed,"
"result=%d\n", (int)result);
result =
P80211ENUM_resultcode_implementation_failure;
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
}
#endif
wlandev->msdstate = WLAN_MSD_FWLOAD;
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_FWLOAD:
hfa384x_cmd_initialize(hw);
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_RUNNING:
WLAN_LOG_WARNING(
"Cannot enter fwload state from enable state,"
"you must disable first.\n");
result = P80211ENUM_resultcode_invalid_parameters;
break;
case WLAN_MSD_HWFAIL:
default:
/* probe() had a problem or the msdstate contains
* an unrecognized value, there's nothing we can do.
*/
result = P80211ENUM_resultcode_implementation_failure;
break;
}
break;
case P80211ENUM_ifstate_enable:
switch (wlandev->msdstate) {
case WLAN_MSD_HWPRESENT:
case WLAN_MSD_FWLOAD:
wlandev->msdstate = WLAN_MSD_RUNNING_PENDING;
/* Initialize the device+driver for full
* operation. Note that this might me an FWLOAD to
* to RUNNING transition so we must not do a chip
* or board level reset. Note that on failure,
* the MSD state is set to HWPRESENT because we
* can't make any assumptions about the state
* of the hardware or a previous firmware load.
*/
if ((result=hfa384x_drvr_start(hw))) {
WLAN_LOG_ERROR(
"hfa384x_drvr_start() failed,"
"result=%d\n", (int)result);
result =
P80211ENUM_resultcode_implementation_failure;
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
}
if ((result=prism2sta_getcardinfo(wlandev))) {
WLAN_LOG_ERROR(
"prism2sta_getcardinfo() failed,"
"result=%d\n", (int)result);
result =
P80211ENUM_resultcode_implementation_failure;
hfa384x_drvr_stop(hw);
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
}
if ((result=prism2sta_globalsetup(wlandev))) {
WLAN_LOG_ERROR(
"prism2sta_globalsetup() failed,"
"result=%d\n", (int)result);
result =
P80211ENUM_resultcode_implementation_failure;
hfa384x_drvr_stop(hw);
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
}
wlandev->msdstate = WLAN_MSD_RUNNING;
hw->join_ap = 0;
hw->join_retries = 60;
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_RUNNING:
/* Do nothing, we're already in this state.*/
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_HWFAIL:
default:
/* probe() had a problem or the msdstate contains
* an unrecognized value, there's nothing we can do.
*/
result = P80211ENUM_resultcode_implementation_failure;
break;
}
break;
case P80211ENUM_ifstate_disable:
switch (wlandev->msdstate) {
case WLAN_MSD_HWPRESENT:
/* Do nothing, we're already in this state.*/
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_FWLOAD:
case WLAN_MSD_RUNNING:
wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING;
/*
* TODO: Shut down the MAC completely. Here a chip
* or board level reset is probably called for.
* After a "disable" _all_ results are lost, even
* those from a fwload.
*/
if (!wlandev->hwremoved)
netif_carrier_off(wlandev->netdev);
hfa384x_drvr_stop(hw);
wlandev->macmode = WLAN_MACMODE_NONE;
wlandev->msdstate = WLAN_MSD_HWPRESENT;
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_HWFAIL:
default:
/* probe() had a problem or the msdstate contains
* an unrecognized value, there's nothing we can do.
*/
result = P80211ENUM_resultcode_implementation_failure;
break;
}
break;
default:
result = P80211ENUM_resultcode_invalid_parameters;
break;
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2sta_getcardinfo
*
* Collect the NICID, firmware version and any other identifiers
* we'd like to have in host-side data structures.
*
* Arguments:
* wlandev wlan device structure
*
* Returns:
* 0 success
* >0 f/w reported error
* <0 driver reported error
*
* Side effects:
*
* Call context:
* Either.
----------------------------------------------------------------*/
static int prism2sta_getcardinfo(wlandevice_t *wlandev)
{
int result = 0;
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
UINT16 temp;
UINT8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
DBFENTER;
/* Collect version and compatibility info */
/* Some are critical, some are not */
/* NIC identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY,
&hw->ident_nic, sizeof(hfa384x_compident_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve NICIDENTITY\n");
goto failed;
}
/* get all the nic id fields in host byte order */
hw->ident_nic.id = hfa384x2host_16(hw->ident_nic.id);
hw->ident_nic.variant = hfa384x2host_16(hw->ident_nic.variant);
hw->ident_nic.major = hfa384x2host_16(hw->ident_nic.major);
hw->ident_nic.minor = hfa384x2host_16(hw->ident_nic.minor);
WLAN_LOG_INFO( "ident: nic h/w: id=0x%02x %d.%d.%d\n",
hw->ident_nic.id, hw->ident_nic.major,
hw->ident_nic.minor, hw->ident_nic.variant);
/* Primary f/w identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY,
&hw->ident_pri_fw, sizeof(hfa384x_compident_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve PRIIDENTITY\n");
goto failed;
}
/* get all the private fw id fields in host byte order */
hw->ident_pri_fw.id = hfa384x2host_16(hw->ident_pri_fw.id);
hw->ident_pri_fw.variant = hfa384x2host_16(hw->ident_pri_fw.variant);
hw->ident_pri_fw.major = hfa384x2host_16(hw->ident_pri_fw.major);
hw->ident_pri_fw.minor = hfa384x2host_16(hw->ident_pri_fw.minor);
WLAN_LOG_INFO( "ident: pri f/w: id=0x%02x %d.%d.%d\n",
hw->ident_pri_fw.id, hw->ident_pri_fw.major,
hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
/* Station (Secondary?) f/w identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY,
&hw->ident_sta_fw, sizeof(hfa384x_compident_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve STAIDENTITY\n");
goto failed;
}
if (hw->ident_nic.id < 0x8000) {
WLAN_LOG_ERROR("FATAL: Card is not an Intersil Prism2/2.5/3\n");
result = -1;
goto failed;
}
/* get all the station fw id fields in host byte order */
hw->ident_sta_fw.id = hfa384x2host_16(hw->ident_sta_fw.id);
hw->ident_sta_fw.variant = hfa384x2host_16(hw->ident_sta_fw.variant);
hw->ident_sta_fw.major = hfa384x2host_16(hw->ident_sta_fw.major);
hw->ident_sta_fw.minor = hfa384x2host_16(hw->ident_sta_fw.minor);
/* strip out the 'special' variant bits */
hw->mm_mods = hw->ident_sta_fw.variant & (BIT14 | BIT15);
hw->ident_sta_fw.variant &= ~((UINT16)(BIT14 | BIT15));
if ( hw->ident_sta_fw.id == 0x1f ) {
hw->ap = 0;
WLAN_LOG_INFO(
"ident: sta f/w: id=0x%02x %d.%d.%d\n",
hw->ident_sta_fw.id, hw->ident_sta_fw.major,
hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
} else {
hw->ap = 1;
WLAN_LOG_INFO(
"ident: ap f/w: id=0x%02x %d.%d.%d\n",
hw->ident_sta_fw.id, hw->ident_sta_fw.major,
hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
}
/* Compatibility range, Modem supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE,
&hw->cap_sup_mfi, sizeof(hfa384x_caplevel_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve MFISUPRANGE\n");
goto failed;
}
/* get all the Compatibility range, modem interface supplier
fields in byte order */
hw->cap_sup_mfi.role = hfa384x2host_16(hw->cap_sup_mfi.role);
hw->cap_sup_mfi.id = hfa384x2host_16(hw->cap_sup_mfi.id);
hw->cap_sup_mfi.variant = hfa384x2host_16(hw->cap_sup_mfi.variant);
hw->cap_sup_mfi.bottom = hfa384x2host_16(hw->cap_sup_mfi.bottom);
hw->cap_sup_mfi.top = hfa384x2host_16(hw->cap_sup_mfi.top);
WLAN_LOG_INFO(
"MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
hw->cap_sup_mfi.top);
/* Compatibility range, Controller supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE,
&hw->cap_sup_cfi, sizeof(hfa384x_caplevel_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve CFISUPRANGE\n");
goto failed;
}
/* get all the Compatibility range, controller interface supplier
fields in byte order */
hw->cap_sup_cfi.role = hfa384x2host_16(hw->cap_sup_cfi.role);
hw->cap_sup_cfi.id = hfa384x2host_16(hw->cap_sup_cfi.id);
hw->cap_sup_cfi.variant = hfa384x2host_16(hw->cap_sup_cfi.variant);
hw->cap_sup_cfi.bottom = hfa384x2host_16(hw->cap_sup_cfi.bottom);
hw->cap_sup_cfi.top = hfa384x2host_16(hw->cap_sup_cfi.top);
WLAN_LOG_INFO(
"CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
hw->cap_sup_cfi.top);
/* Compatibility range, Primary f/w supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE,
&hw->cap_sup_pri, sizeof(hfa384x_caplevel_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve PRISUPRANGE\n");
goto failed;
}
/* get all the Compatibility range, primary firmware supplier
fields in byte order */
hw->cap_sup_pri.role = hfa384x2host_16(hw->cap_sup_pri.role);
hw->cap_sup_pri.id = hfa384x2host_16(hw->cap_sup_pri.id);
hw->cap_sup_pri.variant = hfa384x2host_16(hw->cap_sup_pri.variant);
hw->cap_sup_pri.bottom = hfa384x2host_16(hw->cap_sup_pri.bottom);
hw->cap_sup_pri.top = hfa384x2host_16(hw->cap_sup_pri.top);
WLAN_LOG_INFO(
"PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
hw->cap_sup_pri.role, hw->cap_sup_pri.id,
hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
hw->cap_sup_pri.top);
/* Compatibility range, Station f/w supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE,
&hw->cap_sup_sta, sizeof(hfa384x_caplevel_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve STASUPRANGE\n");
goto failed;
}
/* get all the Compatibility range, station firmware supplier
fields in byte order */
hw->cap_sup_sta.role = hfa384x2host_16(hw->cap_sup_sta.role);
hw->cap_sup_sta.id = hfa384x2host_16(hw->cap_sup_sta.id);
hw->cap_sup_sta.variant = hfa384x2host_16(hw->cap_sup_sta.variant);
hw->cap_sup_sta.bottom = hfa384x2host_16(hw->cap_sup_sta.bottom);
hw->cap_sup_sta.top = hfa384x2host_16(hw->cap_sup_sta.top);
if ( hw->cap_sup_sta.id == 0x04 ) {
WLAN_LOG_INFO(
"STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
hw->cap_sup_sta.role, hw->cap_sup_sta.id,
hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
hw->cap_sup_sta.top);
} else {
WLAN_LOG_INFO(
"AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
hw->cap_sup_sta.role, hw->cap_sup_sta.id,
hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
hw->cap_sup_sta.top);
}
/* Compatibility range, primary f/w actor, CFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES,
&hw->cap_act_pri_cfi, sizeof(hfa384x_caplevel_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve PRI_CFIACTRANGES\n");
goto failed;
}
/* get all the Compatibility range, primary f/w actor, CFI supplier
fields in byte order */
hw->cap_act_pri_cfi.role = hfa384x2host_16(hw->cap_act_pri_cfi.role);
hw->cap_act_pri_cfi.id = hfa384x2host_16(hw->cap_act_pri_cfi.id);
hw->cap_act_pri_cfi.variant = hfa384x2host_16(hw->cap_act_pri_cfi.variant);
hw->cap_act_pri_cfi.bottom = hfa384x2host_16(hw->cap_act_pri_cfi.bottom);
hw->cap_act_pri_cfi.top = hfa384x2host_16(hw->cap_act_pri_cfi.top);
WLAN_LOG_INFO(
"PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
hw->cap_act_pri_cfi.top);
/* Compatibility range, sta f/w actor, CFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES,
&hw->cap_act_sta_cfi, sizeof(hfa384x_caplevel_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve STA_CFIACTRANGES\n");
goto failed;
}
/* get all the Compatibility range, station f/w actor, CFI supplier
fields in byte order */
hw->cap_act_sta_cfi.role = hfa384x2host_16(hw->cap_act_sta_cfi.role);
hw->cap_act_sta_cfi.id = hfa384x2host_16(hw->cap_act_sta_cfi.id);
hw->cap_act_sta_cfi.variant = hfa384x2host_16(hw->cap_act_sta_cfi.variant);
hw->cap_act_sta_cfi.bottom = hfa384x2host_16(hw->cap_act_sta_cfi.bottom);
hw->cap_act_sta_cfi.top = hfa384x2host_16(hw->cap_act_sta_cfi.top);
WLAN_LOG_INFO(
"STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
hw->cap_act_sta_cfi.top);
/* Compatibility range, sta f/w actor, MFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES,
&hw->cap_act_sta_mfi, sizeof(hfa384x_caplevel_t));
if ( result ) {
WLAN_LOG_ERROR("Failed to retrieve STA_MFIACTRANGES\n");
goto failed;
}
/* get all the Compatibility range, station f/w actor, MFI supplier
fields in byte order */
hw->cap_act_sta_mfi.role = hfa384x2host_16(hw->cap_act_sta_mfi.role);
hw->cap_act_sta_mfi.id = hfa384x2host_16(hw->cap_act_sta_mfi.id);
hw->cap_act_sta_mfi.variant = hfa384x2host_16(hw->cap_act_sta_mfi.variant);
hw->cap_act_sta_mfi.bottom = hfa384x2host_16(hw->cap_act_sta_mfi.bottom);
hw->cap_act_sta_mfi.top = hfa384x2host_16(hw->cap_act_sta_mfi.top);
WLAN_LOG_INFO(
"STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
hw->cap_act_sta_mfi.top);
/* Serial Number */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER,
snum, HFA384x_RID_NICSERIALNUMBER_LEN);
if ( !result ) {
wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN,
pstr, sizeof(pstr));
WLAN_LOG_INFO("Prism2 card SN: %s\n", pstr);
} else {
WLAN_LOG_ERROR("Failed to retrieve Prism2 Card SN\n");
goto failed;
}
/* Collect the MAC address */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR,
wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
if ( result != 0 ) {
WLAN_LOG_ERROR("Failed to retrieve mac address\n");
goto failed;
}
/* short preamble is always implemented */
wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE;
/* find out if hardware wep is implemented */
hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp);
if (temp)
wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP;
/* get the dBm Scaling constant */
hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp);
hw->dbmadjust = temp;
/* Only enable scan by default on newer firmware */
if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
hw->ident_sta_fw.minor,
hw->ident_sta_fw.variant) <
HFA384x_FIRMWARE_VERSION(1,5,5)) {
wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN;
}
/* TODO: Set any internally managed config items */
goto done;
failed:
WLAN_LOG_ERROR("Failed, result=%d\n", result);
done:
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2sta_globalsetup
*
* Set any global RIDs that we want to set at device activation.
*
* Arguments:
* wlandev wlan device structure
*
* Returns:
* 0 success
* >0 f/w reported error
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
static int prism2sta_globalsetup(wlandevice_t *wlandev)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
/* Set the maximum frame size */
return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
WLAN_DATA_MAXLEN);
}
static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
{
int result = 0;
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
UINT16 promisc;
DBFENTER;
/* If we're not ready, what's the point? */
if ( hw->state != HFA384x_STATE_RUNNING )
goto exit;
/* If we're an AP, do nothing here */
if (hw->ap)
goto exit;
if ( (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 )
promisc = P80211ENUM_truth_true;
else
promisc = P80211ENUM_truth_false;
result = hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, promisc);
/* XXX TODO: configure the multicast list */
// CLEAR_HW_MULTICAST_LIST
// struct dev_mc_list element = dev->mc_list;
// while (element != null) {
// HW_ADD_MULTICAST_ADDR(element->dmi_addr, dmi_addrlen)
// element = element->next;
// }
exit:
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* prism2sta_inf_handover
*
* Handles the receipt of a Handover info frame. Should only be present
* in APs only.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
{
DBFENTER;
WLAN_LOG_DEBUG(2,"received infoframe:HANDOVER (unhandled)\n");
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_inf_tallies
*
* Handles the receipt of a CommTallies info frame.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static void prism2sta_inf_tallies(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
UINT16 *src16;
UINT32 *dst;
UINT32 *src32;
int i;
int cnt;
DBFENTER;
/*
** Determine if these are 16-bit or 32-bit tallies, based on the
** record length of the info record.
*/
cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(UINT32);
if (inf->framelen > 22) {
dst = (UINT32 *) &hw->tallies;
src32 = (UINT32 *) &inf->info.commtallies32;
for (i = 0; i < cnt; i++, dst++, src32++)
*dst += hfa384x2host_32(*src32);
} else {
dst = (UINT32 *) &hw->tallies;
src16 = (UINT16 *) &inf->info.commtallies16;
for (i = 0; i < cnt; i++, dst++, src16++)
*dst += hfa384x2host_16(*src16);
}
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_inf_scanresults
*
* Handles the receipt of a Scan Results info frame.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
int nbss;
hfa384x_ScanResult_t *sr = &(inf->info.scanresult);
int i;
hfa384x_JoinRequest_data_t joinreq;
int result;
DBFENTER;
/* Get the number of results, first in bytes, then in results */
nbss = (inf->framelen * sizeof(UINT16)) -
sizeof(inf->infotype) -
sizeof(inf->info.scanresult.scanreason);
nbss /= sizeof(hfa384x_ScanResultSub_t);
/* Print em */
WLAN_LOG_DEBUG(1,"rx scanresults, reason=%d, nbss=%d:\n",
inf->info.scanresult.scanreason, nbss);
for ( i = 0; i < nbss; i++) {
WLAN_LOG_DEBUG(1, "chid=%d anl=%d sl=%d bcnint=%d\n",
sr->result[i].chid,
sr->result[i].anl,
sr->result[i].sl,
sr->result[i].bcnint);
WLAN_LOG_DEBUG(1, " capinfo=0x%04x proberesp_rate=%d\n",
sr->result[i].capinfo,
sr->result[i].proberesp_rate);
}
/* issue a join request */
joinreq.channel = sr->result[0].chid;
memcpy( joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
result = hfa384x_drvr_setconfig( hw,
HFA384x_RID_JOINREQUEST,
&joinreq, HFA384x_RID_JOINREQUEST_LEN);
if (result) {
WLAN_LOG_ERROR("setconfig(joinreq) failed, result=%d\n", result);
}
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_inf_hostscanresults
*
* Handles the receipt of a Scan Results info frame.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
int nbss;
DBFENTER;
nbss = (inf->framelen - 3) / 32;
WLAN_LOG_DEBUG(1, "Received %d hostscan results\n", nbss);
if (nbss > 32)
nbss = 32;
if (hw->scanresults)
kfree(hw->scanresults);
hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC);
memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t));
if (nbss == 0)
nbss = -1;
/* Notify/wake the sleeping caller. */
hw->scanflag = nbss;
wake_up_interruptible(&hw->cmdq);
DBFEXIT;
};
/*----------------------------------------------------------------
* prism2sta_inf_chinforesults
*
* Handles the receipt of a Channel Info Results info frame.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
unsigned int i, n;
DBFENTER;
hw->channel_info.results.scanchannels =
hfa384x2host_16(inf->info.chinforesult.scanchannels);
#if 0
memcpy(&inf->info.chinforesult, &hw->channel_info.results, sizeof(hfa384x_ChInfoResult_t));
#endif
for (i=0, n=0; i<HFA384x_CHINFORESULT_MAX; i++) {
if (hw->channel_info.results.scanchannels & (1<<i)) {
int channel=hfa384x2host_16(inf->info.chinforesult.result[n].chid)-1;
hfa384x_ChInfoResultSub_t *chinforesult=&hw->channel_info.results.result[channel];
chinforesult->chid = channel;
chinforesult->anl = hfa384x2host_16(inf->info.chinforesult.result[n].anl);
chinforesult->pnl = hfa384x2host_16(inf->info.chinforesult.result[n].pnl);
chinforesult->active = hfa384x2host_16(inf->info.chinforesult.result[n].active);
WLAN_LOG_DEBUG(2, "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
channel+1,
chinforesult->active &
HFA384x_CHINFORESULT_BSSACTIVE ? "signal" : "noise",
chinforesult->anl, chinforesult->pnl,
chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0
);
n++;
}
}
atomic_set(&hw->channel_info.done, 2);
hw->channel_info.count = n;
DBFEXIT;
return;
}
void prism2sta_processing_defer(struct work_struct *data)
{
hfa384x_t *hw = container_of(data, struct hfa384x, link_bh);
wlandevice_t *wlandev = hw->wlandev;
hfa384x_bytestr32_t ssid;
int result;
DBFENTER;
/* First let's process the auth frames */
{
struct sk_buff *skb;
hfa384x_InfFrame_t *inf;
while ( (skb = skb_dequeue(&hw->authq)) ) {
inf = (hfa384x_InfFrame_t *) skb->data;
prism2sta_inf_authreq_defer(wlandev, inf);
}
}
/* Now let's handle the linkstatus stuff */
if (hw->link_status == hw->link_status_new)
goto failed;
hw->link_status = hw->link_status_new;
switch(hw->link_status) {
case HFA384x_LINK_NOTCONNECTED:
/* I'm currently assuming that this is the initial link
* state. It should only be possible immediately
* following an Enable command.
* Response:
* Block Transmits, Ignore receives of data frames
*/
netif_carrier_off(wlandev->netdev);
WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n");
break;
case HFA384x_LINK_CONNECTED:
/* This one indicates a successful scan/join/auth/assoc.
* When we have the full MLME complement, this event will
* signify successful completion of both mlme_authenticate
* and mlme_associate. State management will get a little
* ugly here.
* Response:
* Indicate authentication and/or association
* Enable Transmits, Receives and pass up data frames
*/
netif_carrier_on(wlandev->netdev);
/* If we are joining a specific AP, set our state and reset retries */
if(hw->join_ap == 1)
hw->join_ap = 2;
hw->join_retries = 60;
/* Don't call this in monitor mode */
if ( wlandev->netdev->type == ARPHRD_ETHER ) {
UINT16 portstatus;
WLAN_LOG_INFO("linkstatus=CONNECTED\n");
/* For non-usb devices, we can use the sync versions */
/* Collect the BSSID, and set state to allow tx */
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTBSSID,
wlandev->bssid, WLAN_BSSID_LEN);
if ( result ) {
WLAN_LOG_DEBUG(1,
"getconfig(0x%02x) failed, result = %d\n",
HFA384x_RID_CURRENTBSSID, result);
goto failed;
}
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTSSID,
&ssid, sizeof(ssid));
if ( result ) {
WLAN_LOG_DEBUG(1,
"getconfig(0x%02x) failed, result = %d\n",
HFA384x_RID_CURRENTSSID, result);
goto failed;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
(p80211pstrd_t *) &wlandev->ssid);
/* Collect the port status */
result = hfa384x_drvr_getconfig16(hw,
HFA384x_RID_PORTSTATUS, &portstatus);
if ( result ) {
WLAN_LOG_DEBUG(1,
"getconfig(0x%02x) failed, result = %d\n",
HFA384x_RID_PORTSTATUS, result);
goto failed;
}
wlandev->macmode =
(portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
/* Get the ball rolling on the comms quality stuff */
prism2sta_commsqual_defer(&hw->commsqual_bh);
}
break;
case HFA384x_LINK_DISCONNECTED:
/* This one indicates that our association is gone. We've
* lost connection with the AP and/or been disassociated.
* This indicates that the MAC has completely cleared it's
* associated state. We * should send a deauth indication
* (implying disassoc) up * to the MLME.
* Response:
* Indicate Deauthentication
* Block Transmits, Ignore receives of data frames
*/
if(hw->join_ap == 2)
{
hfa384x_JoinRequest_data_t joinreq;
joinreq = hw->joinreq;
/* Send the join request */
hfa384x_drvr_setconfig( hw,
HFA384x_RID_JOINREQUEST,
&joinreq, HFA384x_RID_JOINREQUEST_LEN);
WLAN_LOG_INFO("linkstatus=DISCONNECTED (re-submitting join)\n");
} else {
if (wlandev->netdev->type == ARPHRD_ETHER)
WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n");
}
wlandev->macmode = WLAN_MACMODE_NONE;
netif_carrier_off(wlandev->netdev);
break;
case HFA384x_LINK_AP_CHANGE:
/* This one indicates that the MAC has decided to and
* successfully completed a change to another AP. We
* should probably implement a reassociation indication
* in response to this one. I'm thinking that the the
* p80211 layer needs to be notified in case of
* buffering/queueing issues. User mode also needs to be
* notified so that any BSS dependent elements can be
* updated.
* associated state. We * should send a deauth indication
* (implying disassoc) up * to the MLME.
* Response:
* Indicate Reassociation
* Enable Transmits, Receives and pass up data frames
*/
WLAN_LOG_INFO("linkstatus=AP_CHANGE\n");
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTBSSID,
wlandev->bssid, WLAN_BSSID_LEN);
if ( result ) {
WLAN_LOG_DEBUG(1,
"getconfig(0x%02x) failed, result = %d\n",
HFA384x_RID_CURRENTBSSID, result);
goto failed;
}
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTSSID,
&ssid, sizeof(ssid));
if ( result ) {
WLAN_LOG_DEBUG(1,
"getconfig(0x%02x) failed, result = %d\n",
HFA384x_RID_CURRENTSSID, result);
goto failed;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
(p80211pstrd_t *) &wlandev->ssid);
hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev);
break;
case HFA384x_LINK_AP_OUTOFRANGE:
/* This one indicates that the MAC has decided that the
* AP is out of range, but hasn't found a better candidate
* so the MAC maintains its "associated" state in case
* we get back in range. We should block transmits and
* receives in this state. Do we need an indication here?
* Probably not since a polling user-mode element would
* get this status from from p2PortStatus(FD40). What about
* p80211?
* Response:
* Block Transmits, Ignore receives of data frames
*/
WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n");
netif_carrier_off(wlandev->netdev);
break;
case HFA384x_LINK_AP_INRANGE:
/* This one indicates that the MAC has decided that the
* AP is back in range. We continue working with our
* existing association.
* Response:
* Enable Transmits, Receives and pass up data frames
*/
WLAN_LOG_INFO("linkstatus=AP_INRANGE\n");
hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev);
break;
case HFA384x_LINK_ASSOCFAIL:
/* This one is actually a peer to CONNECTED. We've
* requested a join for a given SSID and optionally BSSID.
* We can use this one to indicate authentication and
* association failures. The trick is going to be
* 1) identifying the failure, and 2) state management.
* Response:
* Disable Transmits, Ignore receives of data frames
*/
if(hw->join_ap && --hw->join_retries > 0)
{
hfa384x_JoinRequest_data_t joinreq;
joinreq = hw->joinreq;
/* Send the join request */
hfa384x_drvr_setconfig( hw,
HFA384x_RID_JOINREQUEST,
&joinreq, HFA384x_RID_JOINREQUEST_LEN);
WLAN_LOG_INFO("linkstatus=ASSOCFAIL (re-submitting join)\n");
} else {
WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n");
}
netif_carrier_off(wlandev->netdev);
break;
default:
/* This is bad, IO port problems? */
WLAN_LOG_WARNING(
"unknown linkstatus=0x%02x\n", hw->link_status);
goto failed;
break;
}
wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
#ifdef WIRELESS_EXT
p80211wext_event_associated(wlandev, wlandev->linkstatus);
#endif
failed:
DBFEXIT;
}
/*----------------------------------------------------------------
* prism2sta_inf_linkstatus
*
* Handles the receipt of a Link Status info frame.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
DBFENTER;
hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus);
schedule_work(&hw->link_bh);
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_inf_assocstatus
*
* Handles the receipt of an Association Status info frame. Should
* be present in APs only.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
hfa384x_AssocStatus_t rec;
int i;
DBFENTER;
memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
rec.assocstatus = hfa384x2host_16(rec.assocstatus);
rec.reason = hfa384x2host_16(rec.reason);
/*
** Find the address in the list of authenticated stations. If it wasn't
** found, then this address has not been previously authenticated and
** something weird has happened if this is anything other than an
** "authentication failed" message. If the address was found, then
** set the "associated" flag for that station, based on whether the
** station is associating or losing its association. Something weird
** has also happened if we find the address in the list of authenticated
** stations but we are getting an "authentication failed" message.
*/
for (i = 0; i < hw->authlist.cnt; i++)
if (memcmp(rec.sta_addr, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
break;
if (i >= hw->authlist.cnt) {
if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL)
WLAN_LOG_WARNING("assocstatus info frame received for non-authenticated station.\n");
} else {
hw->authlist.assoc[i] =
(rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL)
WLAN_LOG_WARNING("authfail assocstatus info frame received for authenticated station.\n");
}
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_inf_authreq
*
* Handles the receipt of an Authentication Request info frame. Should
* be present in APs only.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
*
----------------------------------------------------------------*/
static void prism2sta_inf_authreq(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
struct sk_buff *skb;
DBFENTER;
skb = dev_alloc_skb(sizeof(*inf));
if (skb) {
skb_put(skb, sizeof(*inf));
memcpy(skb->data, inf, sizeof(*inf));
skb_queue_tail(&hw->authq, skb);
schedule_work(&hw->link_bh);
}
DBFEXIT;
}
static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
hfa384x_authenticateStation_data_t rec;
int i, added, result, cnt;
UINT8 *addr;
DBFENTER;
/*
** Build the AuthenticateStation record. Initialize it for denying
** authentication.
*/
memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN);
rec.status = P80211ENUM_status_unspec_failure;
/*
** Authenticate based on the access mode.
*/
switch (hw->accessmode) {
case WLAN_ACCESS_NONE:
/*
** Deny all new authentications. However, if a station
** is ALREADY authenticated, then accept it.
*/
for (i = 0; i < hw->authlist.cnt; i++)
if (memcmp(rec.address, hw->authlist.addr[i],
WLAN_ADDR_LEN) == 0) {
rec.status = P80211ENUM_status_successful;
break;
}
break;
case WLAN_ACCESS_ALL:
/*
** Allow all authentications.
*/
rec.status = P80211ENUM_status_successful;
break;
case WLAN_ACCESS_ALLOW:
/*
** Only allow the authentication if the MAC address
** is in the list of allowed addresses.
**
** Since this is the interrupt handler, we may be here
** while the access list is in the middle of being
** updated. Choose the list which is currently okay.
** See "prism2mib_priv_accessallow()" for details.
*/
if (hw->allow.modify == 0) {
cnt = hw->allow.cnt;
addr = hw->allow.addr[0];
} else {
cnt = hw->allow.cnt1;
addr = hw->allow.addr1[0];
}
for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
rec.status = P80211ENUM_status_successful;
break;
}
break;
case WLAN_ACCESS_DENY:
/*
** Allow the authentication UNLESS the MAC address is
** in the list of denied addresses.
**
** Since this is the interrupt handler, we may be here
** while the access list is in the middle of being
** updated. Choose the list which is currently okay.
** See "prism2mib_priv_accessdeny()" for details.
*/
if (hw->deny.modify == 0) {
cnt = hw->deny.cnt;
addr = hw->deny.addr[0];
} else {
cnt = hw->deny.cnt1;
addr = hw->deny.addr1[0];
}
rec.status = P80211ENUM_status_successful;
for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
rec.status = P80211ENUM_status_unspec_failure;
break;
}
break;
}
/*
** If the authentication is okay, then add the MAC address to the list
** of authenticated stations. Don't add the address if it is already in
** the list. (802.11b does not seem to disallow a station from issuing
** an authentication request when the station is already authenticated.
** Does this sort of thing ever happen? We might as well do the check
** just in case.)
*/
added = 0;
if (rec.status == P80211ENUM_status_successful) {
for (i = 0; i < hw->authlist.cnt; i++)
if (memcmp(rec.address, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
break;
if (i >= hw->authlist.cnt) {
if (hw->authlist.cnt >= WLAN_AUTH_MAX) {
rec.status = P80211ENUM_status_ap_full;
} else {
memcpy(hw->authlist.addr[hw->authlist.cnt],
rec.address, WLAN_ADDR_LEN);
hw->authlist.cnt++;
added = 1;
}
}
}
/*
** Send back the results of the authentication. If this doesn't work,
** then make sure to remove the address from the authenticated list if
** it was added.
*/
rec.status = host2hfa384x_16(rec.status);
rec.algorithm = inf->info.authreq.algorithm;
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA,
&rec, sizeof(rec));
if (result) {
if (added) hw->authlist.cnt--;
WLAN_LOG_ERROR("setconfig(authenticatestation) failed, result=%d\n", result);
}
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_inf_psusercnt
*
* Handles the receipt of a PowerSaveUserCount info frame. Should
* be present in APs only.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to info frame (contents in hfa384x order)
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
DBFENTER;
hw->psusercount = hfa384x2host_16(inf->info.psusercnt.usercnt);
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_ev_dtim
*
* Handles the DTIM early warning event.
*
* Arguments:
* wlandev wlan device structure
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
void prism2sta_ev_dtim(wlandevice_t *wlandev)
{
#if 0
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
#endif
DBFENTER;
WLAN_LOG_DEBUG(3, "DTIM event, currently unhandled.\n");
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_ev_infdrop
*
* Handles the InfDrop event.
*
* Arguments:
* wlandev wlan device structure
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
void prism2sta_ev_infdrop(wlandevice_t *wlandev)
{
#if 0
hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
#endif
DBFENTER;
WLAN_LOG_DEBUG(3, "Info frame dropped due to card mem low.\n");
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_ev_info
*
* Handles the Info event.
*
* Arguments:
* wlandev wlan device structure
* inf ptr to a generic info frame
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
{
DBFENTER;
inf->infotype = hfa384x2host_16(inf->infotype);
/* Dispatch */
switch ( inf->infotype ) {
case HFA384x_IT_HANDOVERADDR:
prism2sta_inf_handover(wlandev, inf);
break;
case HFA384x_IT_COMMTALLIES:
prism2sta_inf_tallies(wlandev, inf);
break;
case HFA384x_IT_HOSTSCANRESULTS:
prism2sta_inf_hostscanresults(wlandev, inf);
break;
case HFA384x_IT_SCANRESULTS:
prism2sta_inf_scanresults(wlandev, inf);
break;
case HFA384x_IT_CHINFORESULTS:
prism2sta_inf_chinforesults(wlandev, inf);
break;
case HFA384x_IT_LINKSTATUS:
prism2sta_inf_linkstatus(wlandev, inf);
break;
case HFA384x_IT_ASSOCSTATUS:
prism2sta_inf_assocstatus(wlandev, inf);
break;
case HFA384x_IT_AUTHREQ:
prism2sta_inf_authreq(wlandev, inf);
break;
case HFA384x_IT_PSUSERCNT:
prism2sta_inf_psusercnt(wlandev, inf);
break;
case HFA384x_IT_KEYIDCHANGED:
WLAN_LOG_WARNING("Unhandled IT_KEYIDCHANGED\n");
break;
case HFA384x_IT_ASSOCREQ:
WLAN_LOG_WARNING("Unhandled IT_ASSOCREQ\n");
break;
case HFA384x_IT_MICFAILURE:
WLAN_LOG_WARNING("Unhandled IT_MICFAILURE\n");
break;
default:
WLAN_LOG_WARNING(
"Unknown info type=0x%02x\n", inf->infotype);
break;
}
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_ev_txexc
*
* Handles the TxExc event. A Transmit Exception event indicates
* that the MAC's TX process was unsuccessful - so the packet did
* not get transmitted.
*
* Arguments:
* wlandev wlan device structure
* status tx frame status word
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
void prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status)
{
DBFENTER;
WLAN_LOG_DEBUG(3, "TxExc status=0x%x.\n", status);
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_ev_tx
*
* Handles the Tx event.
*
* Arguments:
* wlandev wlan device structure
* status tx frame status word
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
void prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status)
{
DBFENTER;
WLAN_LOG_DEBUG(4, "Tx Complete, status=0x%04x\n", status);
/* update linux network stats */
wlandev->linux_stats.tx_packets++;
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_ev_rx
*
* Handles the Rx event.
*
* Arguments:
* wlandev wlan device structure
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
{
DBFENTER;
p80211netdev_rx(wlandev, skb);
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* prism2sta_ev_alloc
*
* Handles the Alloc event.
*
* Arguments:
* wlandev wlan device structure
*
* Returns:
* nothing
*
* Side effects:
*
* Call context:
* interrupt
----------------------------------------------------------------*/
void prism2sta_ev_alloc(wlandevice_t *wlandev)
{
DBFENTER;
p80211netdev_wake_queue(wlandev);
DBFEXIT;
return;
}
#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)
#ifdef CONFIG_PM
static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state)
{
wlandevice_t *wlandev;
wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
/* reset hardware */
if (wlandev) {
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
p80211_suspend(wlandev);
}
// call a netif_device_detach(wlandev->netdev) ?
return 0;
}
static int prism2sta_resume_pci (struct pci_dev *pdev)
{
wlandevice_t *wlandev;
wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
if (wlandev) {
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
p80211_resume(wlandev);
}
return 0;
}
#endif
#endif
/*----------------------------------------------------------------
* create_wlan
*
* Called at module init time. This creates the wlandevice_t structure
* and initializes it with relevant bits.
*
* Arguments:
* none
*
* Returns:
* the created wlandevice_t structure.
*
* Side effects:
* also allocates the priv/hw structures.
*
* Call context:
* process thread
*
----------------------------------------------------------------*/
static wlandevice_t *create_wlan(void)
{
wlandevice_t *wlandev = NULL;
hfa384x_t *hw = NULL;
/* Alloc our structures */
wlandev = kmalloc(sizeof(wlandevice_t), GFP_KERNEL);
hw = kmalloc(sizeof(hfa384x_t), GFP_KERNEL);
if (!wlandev || !hw) {
WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
if (wlandev) kfree(wlandev);
if (hw) kfree(hw);
return NULL;
}
/* Clear all the structs */
memset(wlandev, 0, sizeof(wlandevice_t));
memset(hw, 0, sizeof(hfa384x_t));
/* Initialize the network device object. */
wlandev->nsdname = dev_info;
wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING;
wlandev->priv = hw;
wlandev->open = prism2sta_open;
wlandev->close = prism2sta_close;
wlandev->reset = prism2sta_reset;
#ifdef CONFIG_PROC_FS
wlandev->nsd_proc_read = prism2sta_proc_read;
#endif
wlandev->txframe = prism2sta_txframe;
wlandev->mlmerequest = prism2sta_mlmerequest;
wlandev->set_multicast_list = prism2sta_setmulticast;
wlandev->tx_timeout = hfa384x_tx_timeout;
wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT |
P80211_NSDCAP_AUTOJOIN;
/* Initialize the device private data stucture. */
hw->dot11_desired_bss_type = 1;
return wlandev;
}
#ifdef CONFIG_PROC_FS
static int
prism2sta_proc_read(
char *page,
char **start,
off_t offset,
int count,
int *eof,
void *data)
{
char *p = page;
wlandevice_t *wlandev = (wlandevice_t *) data;
hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
UINT16 hwtype = 0;
DBFENTER;
if (offset != 0) {
*eof = 1;
goto exit;
}
// XXX 0x0001 for prism2.5/3, 0x0000 for prism2.
hwtype = BIT0;
#if (WLAN_HOSTIF != WLAN_USB)
if (hw->isram16)
hwtype |= BIT1;
#endif
#if (WLAN_HOSTIF == WLAN_PCI)
hwtype |= BIT2;
#endif
#define PRISM2_CVS_ID "$Id: prism2sta.c 1826 2007-03-19 15:37:00Z pizza $"
p += sprintf(p, "# %s version %s (%s) '%s'\n\n",
dev_info,
WLAN_RELEASE, WLAN_BUILD_DATE, PRISM2_CVS_ID);
p += sprintf(p, "# nic h/w: id=0x%02x %d.%d.%d\n",
hw->ident_nic.id, hw->ident_nic.major,
hw->ident_nic.minor, hw->ident_nic.variant);
p += sprintf(p, "# pri f/w: id=0x%02x %d.%d.%d\n",
hw->ident_pri_fw.id, hw->ident_pri_fw.major,
hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
if (hw->ident_sta_fw.id == 0x1f) {
p += sprintf(p, "# sta f/w: id=0x%02x %d.%d.%d\n",
hw->ident_sta_fw.id, hw->ident_sta_fw.major,
hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
} else {
p += sprintf(p, "# ap f/w: id=0x%02x %d.%d.%d\n",
hw->ident_sta_fw.id, hw->ident_sta_fw.major,
hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
}
#if (WLAN_HOSTIF != WLAN_USB)
p += sprintf(p, "# initial nic hw type, needed for SSF ramdl\n");
p += sprintf(p, "initnichw=%04x\n", hwtype);
#endif
exit:
DBFEXIT;
return (p - page);
}
#endif
void prism2sta_commsqual_defer(struct work_struct *data)
{
hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
wlandevice_t *wlandev = hw->wlandev;
hfa384x_bytestr32_t ssid;
int result = 0;
DBFENTER;
if (hw->wlandev->hwremoved)
goto done;
/* we don't care if we're in AP mode */
if ((wlandev->macmode == WLAN_MACMODE_NONE) ||
(wlandev->macmode == WLAN_MACMODE_ESS_AP)) {
goto done;
}
/* It only makes sense to poll these in non-IBSS */
if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) {
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY,
&hw->qual,
HFA384x_RID_DBMCOMMSQUALITY_LEN);
if (result) {
WLAN_LOG_ERROR("error fetching commsqual\n");
goto done;
}
// qual.CQ_currBSS; // link
// ASL_currBSS; // level
// qual.ANL_currFC; // noise
WLAN_LOG_DEBUG(3, "commsqual %d %d %d\n",
hfa384x2host_16(hw->qual.CQ_currBSS),
hfa384x2host_16(hw->qual.ASL_currBSS),
hfa384x2host_16(hw->qual.ANL_currFC));
}
/* Lastly, we need to make sure the BSSID didn't change on us */
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTBSSID,
wlandev->bssid, WLAN_BSSID_LEN);
if ( result ) {
WLAN_LOG_DEBUG(1,
"getconfig(0x%02x) failed, result = %d\n",
HFA384x_RID_CURRENTBSSID, result);
goto done;
}
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTSSID,
&ssid, sizeof(ssid));
if ( result ) {
WLAN_LOG_DEBUG(1,
"getconfig(0x%02x) failed, result = %d\n",
HFA384x_RID_CURRENTSSID, result);
goto done;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
(p80211pstrd_t *) &wlandev->ssid);
/* Reschedule timer */
mod_timer(&hw->commsqual_timer, jiffies + HZ);
done:
DBFEXIT;
}
void prism2sta_commsqual_timer(unsigned long data)
{
hfa384x_t *hw = (hfa384x_t *) data;
DBFENTER;
schedule_work(&hw->commsqual_bh);
DBFEXIT;
}
/* src/include/wlan/version.h
*
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*/
#ifndef _WLAN_VERSION_H
#define _WLAN_VERSION_H
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#endif
/* WLAN_HOSTIF (generally set on the command line, not detected) */
#define WLAN_NONE 0
#define WLAN_PCMCIA 1
#define WLAN_ISA 2
#define WLAN_PCI 3
#define WLAN_USB 4
#define WLAN_PLX 5
#define WLAN_SLAVE 6
#define WLAN_RELEASE "0.2.8"
#define WLAN_RELEASE_CODE 0x000208
#define WLAN_BUILD_DATE "Thu Oct 2 11:04:42 PDT 2008"
#endif
/* wlan_compat.h
*
* Types and macros to aid in portability
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*/
#ifndef _WLAN_COMPAT_H
#define _WLAN_COMPAT_H
/*=============================================================*/
/*------ Establish Platform Identity --------------------------*/
/*=============================================================*/
/* Key macros: */
/* WLAN_CPU_FAMILY */
#define WLAN_Ix86 1
#define WLAN_PPC 2
#define WLAN_Ix96 3
#define WLAN_ARM 4
#define WLAN_ALPHA 5
#define WLAN_MIPS 6
#define WLAN_HPPA 7
#define WLAN_SPARC 8
#define WLAN_SH 9
#define WLAN_x86_64 10
/* WLAN_SYSARCH */
#define WLAN_PCAT 1
#define WLAN_MBX 2
#define WLAN_RPX 3
#define WLAN_LWARCH 4
#define WLAN_PMAC 5
#define WLAN_SKIFF 6
#define WLAN_BITSY 7
#define WLAN_ALPHAARCH 7
#define WLAN_MIPSARCH 9
#define WLAN_HPPAARCH 10
#define WLAN_SPARCARCH 11
#define WLAN_SHARCH 12
/* Note: the PLX HOSTIF above refers to some vendors implementations for */
/* PCI. It's a PLX chip that is a PCI to PCMCIA adapter, but it */
/* isn't a real PCMCIA host interface adapter providing all the */
/* card&socket services. */
#if (defined(CONFIG_PPC) || defined(CONFIG_8xx) || defined(__powerpc__))
#ifndef __ppc__
#define __ppc__
#endif
#endif
#if defined(__KERNEL__)
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#if defined(__x86_64__)
#define WLAN_CPU_FAMILY WLAN_x86_64
#define WLAN_SYSARCH WLAN_PCAT
#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
#define WLAN_CPU_FAMILY WLAN_Ix86
#define WLAN_SYSARCH WLAN_PCAT
#elif defined(__ppc__)
#define WLAN_CPU_FAMILY WLAN_PPC
#if defined(CONFIG_MBX)
#define WLAN_SYSARCH WLAN_MBX
#elif defined(CONFIG_RPXLITE)
#define WLAN_SYSARCH WLAN_RPX
#elif defined(CONFIG_RPXCLASSIC)
#define WLAN_SYSARCH WLAN_RPX
#else
#define WLAN_SYSARCH WLAN_PMAC
#endif
#elif defined(__arm__)
#define WLAN_CPU_FAMILY WLAN_ARM
#define WLAN_SYSARCH WLAN_SKIFF
#elif defined(__alpha__)
#define WLAN_CPU_FAMILY WLAN_ALPHA
#define WLAN_SYSARCH WLAN_ALPHAARCH
#elif defined(__mips__)
#define WLAN_CPU_FAMILY WLAN_MIPS
#define WLAN_SYSARCH WLAN_MIPSARCH
#elif defined(__hppa__)
#define WLAN_CPU_FAMILY WLAN_HPPA
#define WLAN_SYSARCH WLAN_HPPAARCH
#elif defined(__sparc__)
#define WLAN_CPU_FAMILY WLAN_SPARC
#define WLAN_SYSARCH WLAN_SPARC
#elif defined(__sh__)
#define WLAN_CPU_FAMILY WLAN_SH
#define WLAN_SYSARCH WLAN_SHARCH
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#endif
#else
#error "No CPU identified!"
#endif
#endif /* __KERNEL__ */
/*
Some big endian machines implicitly do all I/O in little endian mode.
In particular:
Linux/PPC on PowerMacs (PCI)
Arm/Intel Xscale (PCI)
This may also affect PLX boards and other BE &| PPC platforms;
as new ones are discovered, add them below.
*/
#if defined(WLAN_HOSTIF)
#if ((WLAN_HOSTIF == WLAN_PCI) || (WLAN_HOSTIF == WLAN_PLX))
#if ((WLAN_SYSARCH == WLAN_SKIFF) || (WLAN_SYSARCH == WLAN_PMAC) || (WLAN_SYSARCH == WLAN_SPARC))
#define REVERSE_ENDIAN
#endif
#endif
#endif
/*=============================================================*/
/*------ Bit settings -----------------------------------------*/
/*=============================================================*/
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
#define BIT4 0x00000010
#define BIT5 0x00000020
#define BIT6 0x00000040
#define BIT7 0x00000080
#define BIT8 0x00000100
#define BIT9 0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
#include <linux/types.h>
typedef u_int8_t UINT8;
typedef u_int16_t UINT16;
typedef u_int32_t UINT32;
typedef int8_t INT8;
typedef int16_t INT16;
typedef int32_t INT32;
typedef unsigned int UINT;
typedef signed int INT;
typedef u_int64_t UINT64;
typedef int64_t INT64;
#define UINT8_MAX (0xffUL)
#define UINT16_MAX (0xffffUL)
#define UINT32_MAX (0xffffffffUL)
#define INT8_MAX (0x7fL)
#define INT16_MAX (0x7fffL)
#define INT32_MAX (0x7fffffffL)
/*=============================================================*/
/*------ Compiler Portability Macros --------------------------*/
/*=============================================================*/
#define __WLAN_ATTRIB_PACK__ __attribute__ ((packed))
/*=============================================================*/
/*------ OS Portability Macros --------------------------------*/
/*=============================================================*/
#ifndef WLAN_DBVAR
#define WLAN_DBVAR wlan_debug
#endif
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
# if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8))
# include <linux/hardirq.h>
# else
# include <asm/hardirq.h>
# endif
#elif defined(__KERNEL__)
# define PREEMPT_MASK (0x000000FFUL)
# define preempt_count() (0UL)
#endif
#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __FUNCTION__ , ##args);
#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __FUNCTION__ , ##args);
#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __FUNCTION__ , ##args);
#define WLAN_LOG_INFO(args... ) printk(KERN_INFO args)
#if defined(WLAN_INCLUDE_DEBUG)
#define WLAN_ASSERT(c) if ((!(c)) && WLAN_DBVAR >= 1) { \
WLAN_LOG_DEBUG(1, "Assertion failure!\n"); }
#define WLAN_HEX_DUMP( l, x, p, n) if( WLAN_DBVAR >= (l) ){ \
int __i__; \
printk(KERN_DEBUG x ":"); \
for( __i__=0; __i__ < (n); __i__++) \
printk( " %02x", ((UINT8*)(p))[__i__]); \
printk("\n"); }
#define DBFENTER { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"---->\n"); } }
#define DBFEXIT { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"<----\n"); } }
#define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x , __FUNCTION__, (preempt_count() & PREEMPT_MASK), ##args );
#else
#define WLAN_ASSERT(c)
#define WLAN_HEX_DUMP( l, s, p, n)
#define DBFENTER
#define DBFEXIT
#define WLAN_LOG_DEBUG(l, s, args...)
#endif
#ifdef CONFIG_SMP
#define __SMP__ 1
#endif
#if defined(__KERNEL__)
#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)))
#define URB_ONLY_CALLBACK
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
#define PT_REGS , struct pt_regs *regs
#else
#define PT_REGS
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
# define del_singleshot_timer_sync(a) del_timer_sync(a)
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17))
#define CONFIG_NETLINK 1
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
#define kfree_s(a, b) kfree((a))
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18))
#ifndef init_waitqueue_head
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,0,16))
#define init_waitqueue_head(p) (*(p) = NULL)
#else
#define init_waitqueue_head(p) init_waitqueue(p)
#endif
typedef struct wait_queue *wait_queue_head_t;
typedef struct wait_queue wait_queue_t;
#define set_current_state(b) { current->state = (b); mb(); }
#define init_waitqueue_entry(a, b) { (a)->task = current; }
#endif
#endif
#ifndef wait_event_interruptible_timeout
// retval == 0; signal met; we're good.
// retval < 0; interrupted by signal.
// retval > 0; timed out.
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) // fixme?
#define __wait_event_interruptible_timeout(wq, condition, ret) \
do { \
wait_queue_t __wait; \
init_waitqueue_entry(&__wait, current); \
\
add_wait_queue(&wq, &__wait); \
for (;;) { \
set_current_state(TASK_INTERRUPTIBLE); \
if (condition) \
break; \
if (!signal_pending(current)) { \
ret = schedule_timeout(ret) ; \
if (!ret) \
break; \
continue; \
} \
ret = -ERESTARTSYS; \
break; \
} \
set_current_state(TASK_RUNNING); \
remove_wait_queue(&wq, &__wait); \
} while (0)
#else // 2.2
#define __wait_event_interruptible_timeout(wq, condition, ret) \
do { \
struct wait_queue __wait; \
\
__wait.task = current; \
add_wait_queue(&wq, &__wait); \
for (;;) { \
current->state = TASK_INTERRUPTIBLE; \
if (condition) \
break; \
if (!signal_pending(current)) { \
ret = schedule_timeout(ret); \
if (!ret) \
break; \
continue; \
} \
ret = -ERESTARTSYS; \
break; \
} \
current->state = TASK_RUNNING; \
remove_wait_queue(&wq, &__wait); \
} while (0)
#endif // version >= 2.4
#define wait_event_interruptible_timeout(wq, condition, timeout) \
({ \
long __ret = timeout; \
if (!(condition)) \
__wait_event_interruptible_timeout(wq, condition, __ret); \
__ret; \
})
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
#ifdef _LINUX_LIST_H
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
#endif // LIST_H
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,90))
#define spin_lock(l) do { } while (0)
#define spin_unlock(l) do { } while (0)
#define spin_lock_irqsave(l,f) do { save_flags(f); cli(); } while (0)
#define spin_unlock_irqrestore(l,f) do { restore_flags(f); } while (0)
#define spin_lock_init(s) do { } while (0)
#define spin_trylock(l) (1)
typedef int spinlock_t;
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) // XXX ???
#define spin_lock_bh spin_lock
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
#ifdef CONFIG_SMP
#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0)
#else
#define spin_is_locked(l) (0)
#endif
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28))
#define __user
#define __iomem
#endif
#ifdef _LINUX_PROC_FS_H
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,25))
extern inline struct proc_dir_entry *
create_proc_read_entry(const char *name, mode_t mode,
struct proc_dir_entry *base,
read_proc_t *read_proc, void *data)
{
struct proc_dir_entry *res = create_proc_entry(name, mode, base);
if (res) {
res->read_proc = read_proc;
res->data = data;
}
return res;
}
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29))
#ifndef proc_mkdir
#define proc_mkdir(name, root) create_proc_entry(name, S_IFDIR, root)
#endif
#endif
#endif /* _LINUX_PROC_FS_H */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#ifndef INIT_TQUEUE
#define PREPARE_TQUEUE(_tq, _routine, _data) \
do { \
(_tq)->routine = _routine; \
(_tq)->data = _data; \
} while (0)
#define INIT_TQUEUE(_tq, _routine, _data) \
do { \
INIT_LIST_HEAD(&(_tq)->list); \
(_tq)->sync = 0; \
PREPARE_TQUEUE((_tq), (_routine), (_data)); \
} while (0)
#endif
#ifndef container_of
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif
#ifndef INIT_WORK
#define work_struct tq_struct
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
#define schedule_work(a) queue_task(a, &tq_scheduler)
#else
#define schedule_work(a) schedule_task(a)
#endif
#define flush_scheduled_work flush_scheduled_tasks
#define INIT_WORK2(_wq, _routine) INIT_TQUEUE(_wq, (void (*)(void *))_routine, _wq)
#endif
#else // >= 2.5 kernel
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#define INIT_WORK2(_wq, _routine) INIT_WORK(_wq, (void (*)(void *))_routine, _wq)
#else
#define INIT_WORK2(_wq, _routine) INIT_WORK(_wq, _routine)
#endif
#endif // >= 2.5 kernel
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38))
typedef struct device netdevice_t;
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4))
typedef struct net_device netdevice_t;
#else
#undef netdevice_t
typedef struct net_device netdevice_t;
#endif
#ifdef WIRELESS_EXT
#if (WIRELESS_EXT < 13)
struct iw_request_info
{
__u16 cmd; /* Wireless Extension command */
__u16 flags; /* More to come ;-) */
};
#endif
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18))
#define MODULE_PARM(a,b) extern int __bogus_decl
#define MODULE_AUTHOR(a) extern int __bogus_decl
#define MODULE_DESCRIPTION(a) extern int __bogus_decl
#define MODULE_SUPPORTED_DEVICE(a) extern int __bogus_decl
#undef GET_USE_COUNT
#define GET_USE_COUNT(m) mod_use_count_
#endif
#ifndef MODULE_OWNER
#define MODULE_OWNER(a) extern int __bogus_decl
#define ANCIENT_MODULE_CODE
#endif
#ifndef MODULE_LICENSE
#define MODULE_LICENSE(m) extern int __bogus_decl
#endif
/* TODO: Do we care about this? */
#ifndef MODULE_DEVICE_TABLE
#define MODULE_DEVICE_TABLE(foo,bar)
#endif
#define wlan_minutes2ticks(a) ((a)*(wlan_ticks_per_sec * 60))
#define wlan_seconds2ticks(a) ((a)*(wlan_ticks_per_sec))
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47))
#define NEW_MODULE_CODE
#ifdef ANCIENT_MODULE_CODE
#undef ANCIENT_MODULE_CODE
#endif
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25))
#define module_param(name, type, perm) \
static inline void *__check_existence_##name(void) { return &name; } \
MODULE_PARM(name, _MODULE_PARM_STRING_ ## type)
#define _MODULE_PARM_STRING_byte "b"
#define _MODULE_PARM_STRING_short "h"
#define _MODULE_PARM_STRING_ushort "h"
#define _MODULE_PARM_STRING_int "i"
#define _MODULE_PARM_STRING_uint "i"
#define _MODULE_PARM_STRING_long "l"
#define _MODULE_PARM_STRING_ulong "l"
#define _MODULE_PARM_STRING_bool "i"
#endif
/* linux < 2.5.69 */
#ifndef IRQ_NONE
typedef void irqreturn_t;
#define IRQ_NONE
#define IRQ_HANDLED
#define IRQ_RETVAL(x)
#endif
#ifndef in_atomic
#define in_atomic() 0
#endif
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
#define URB_ASYNC_UNLINK 0
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
#define URB_ASYNC_UNLINK USB_ASYNC_UNLINK
#define usb_fill_bulk_urb FILL_BULK_URB
#define usb_kill_urb usb_unlink_urb
#else
#define USB_QUEUE_BULK 0
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11))
typedef u32 pm_message_t;
#endif
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9))
#define hotplug_path "/etc/hotplug/wlan.agent"
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
#define free_netdev(x) kfree(x)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
#define eth_hdr(x) (x)->mac.ethernet
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
#define del_timer_sync(a) del_timer(a)
#endif
#ifndef might_sleep
#define might_sleep(a) do { } while (0)
#endif
/* Apparently 2.4.2 ethtool is quite different, maybe newer too? */
#if (defined(SIOETHTOOL) && !defined(ETHTOOL_GDRVINFO))
#undef SIOETHTOOL
#endif
// pcmcia-cs stuff
#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) && \
!defined(pcmcia_access_configuration_register))
#define pcmcia_access_configuration_register(handle, reg) \
CardServices(AccessConfigurationRegister, handle, reg)
#define pcmcia_register_client(handle, reg) \
CardServices(RegisterClient, handle, reg)
#define pcmcia_deregister_client(handle) \
CardServices(DeregisterClient, handle)
#define pcmcia_get_first_tuple(handle, tuple) \
CardServices(GetFirstTuple, handle, tuple)
#define pcmcia_get_next_tuple(handle, tuple) \
CardServices(GetNextTuple, handle, tuple)
#define pcmcia_get_tuple_data(handle, tuple) \
CardServices(GetTupleData, handle, tuple)
#define pcmcia_parse_tuple(handle, tuple, parse) \
CardServices(ParseTuple, handle, tuple, parse)
#define pcmcia_get_configuration_info(handle, config) \
CardServices(GetConfigurationInfo, handle, config)
#define pcmcia_request_io(handle, req) \
CardServices(RequestIO, handle, req)
#define pcmcia_request_irq(handle, req) \
CardServices(RequestIRQ, handle, req)
#define pcmcia_request_configuration(handle, req) \
CardServices(RequestConfiguration, handle, req)
#define pcmcia_release_configuration(handle) \
CardServices(ReleaseConfiguration, handle)
#define pcmcia_release_io(handle, req) \
CardServices(ReleaseIO, handle, req)
#define pcmcia_release_irq(handle, req) \
CardServices(ReleaseIRQ, handle, req)
#define pcmcia_release_window(win) \
CardServices(ReleaseWindow, win)
#define pcmcia_get_card_services_info(info) \
CardServices(GetCardServicesInfo, info)
#define pcmcia_report_error(handle, err) \
CardServices(ReportError, handle, err)
#endif
#endif /* __KERNEL__ */
/*=============================================================*/
/*------ Hardware Portability Macros --------------------------*/
/*=============================================================*/
#define ieee2host16(n) __le16_to_cpu(n)
#define ieee2host32(n) __le32_to_cpu(n)
#define host2ieee16(n) __cpu_to_le16(n)
#define host2ieee32(n) __cpu_to_le32(n)
#if (WLAN_CPU_FAMILY != WLAN_MIPS)
typedef UINT32 phys_t;
#endif
#if (WLAN_CPU_FAMILY == WLAN_PPC)
#define wlan_inw(a) in_be16((unsigned short *)((a)+_IO_BASE))
#define wlan_inw_le16_to_cpu(a) inw((a))
#define wlan_outw(v,a) out_be16((unsigned short *)((a)+_IO_BASE), (v))
#define wlan_outw_cpu_to_le16(v,a) outw((v),(a))
#else
#define wlan_inw(a) inw((a))
#define wlan_inw_le16_to_cpu(a) __cpu_to_le16(inw((a)))
#define wlan_outw(v,a) outw((v),(a))
#define wlan_outw_cpu_to_le16(v,a) outw(__cpu_to_le16((v)),(a))
#endif
/*=============================================================*/
/*--- General Macros ------------------------------------------*/
/*=============================================================*/
#define wlan_max(a, b) (((a) > (b)) ? (a) : (b))
#define wlan_min(a, b) (((a) < (b)) ? (a) : (b))
#define wlan_isprint(c) (((c) > (0x19)) && ((c) < (0x7f)))
#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a)))
/* Create a string of printable chars from something that might not be */
/* It's recommended that the str be 4*len + 1 bytes long */
#define wlan_mkprintstr(buf, buflen, str, strlen) \
{ \
int i = 0; \
int j = 0; \
memset(str, 0, (strlen)); \
for (i = 0; i < (buflen); i++) { \
if ( wlan_isprint((buf)[i]) ) { \
(str)[j] = (buf)[i]; \
j++; \
} else { \
(str)[j] = '\\'; \
(str)[j+1] = 'x'; \
(str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \
(str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \
j += 4; \
} \
} \
}
/*=============================================================*/
/*--- Variables -----------------------------------------------*/
/*=============================================================*/
#ifdef WLAN_INCLUDE_DEBUG
extern int wlan_debug;
#endif
extern int wlan_ethconv; /* What's the default ethconv? */
/*=============================================================*/
/*--- Functions -----------------------------------------------*/
/*=============================================================*/
#endif /* _WLAN_COMPAT_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment