aboutsummaryrefslogtreecommitdiffstats
path: root/package/wlcompat
diff options
context:
space:
mode:
Diffstat (limited to 'package/wlcompat')
-rw-r--r--package/wlcompat/Makefile77
-rw-r--r--package/wlcompat/src/Makefile19
-rw-r--r--package/wlcompat/src/include/bcmnvram.h148
-rw-r--r--package/wlcompat/src/include/bcmutils.h157
-rw-r--r--package/wlcompat/src/include/cy_conf.h69
-rw-r--r--package/wlcompat/src/include/epivers.h69
-rw-r--r--package/wlcompat/src/include/proto/802.11.h852
-rw-r--r--package/wlcompat/src/include/proto/ethernet.h179
-rw-r--r--package/wlcompat/src/include/shutils.h200
-rw-r--r--package/wlcompat/src/include/typedefs.h293
-rw-r--r--package/wlcompat/src/include/utils.h131
-rw-r--r--package/wlcompat/src/include/wlcompat.h36
-rw-r--r--package/wlcompat/src/include/wlioctl.h1094
-rw-r--r--package/wlcompat/src/include/wlutils.h59
-rw-r--r--package/wlcompat/src/wlcompat.c1056
15 files changed, 4439 insertions, 0 deletions
diff --git a/package/wlcompat/Makefile b/package/wlcompat/Makefile
new file mode 100644
index 0000000000..fc66c90f50
--- /dev/null
+++ b/package/wlcompat/Makefile
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id$
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=kmod-wlcompat
+PKG_RELEASE:=4
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/kmod-wlcompat/Default
+ SECTION:=kernel
+ CATEGORY:=Kernel drivers
+ DEPENDS:=kmod-brcm-wl
+ TITLE:=Broadcom wl wrapper module
+ DESCRIPTION:=\
+ This package contains a wrapper module, that provides Wireless Extension \\\
+ support for the proprietary Broadcom wl module.
+ VERSION:=$(LINUX_VERSION)+$(BOARD)-$(PKG_RELEASE)
+endef
+
+define Package/kmod-wlcompat
+ $(call Package/kmod-wlcompat/Default)
+ DEFAULT:=y
+endef
+
+define Package/kmod-wlcompat-debug
+ $(call Package/kmod-wlcompat/Default)
+ TITLE+= (debug)
+ DESCRIPTION+=\\\
+ \\\
+ This is a debugging version.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ ARCH="$(LINUX_KARCH)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="-DDEBUG -I$(LINUX_DIR)/arch/mips/bcm947xx/include -I$(PKG_BUILD_DIR)/include" \
+ modules
+ mv $(PKG_BUILD_DIR)/wlcompat.o $(PKG_BUILD_DIR)/wlcompat-debug.o
+ $(MAKE) -C "$(LINUX_DIR)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ ARCH="$(LINUX_KARCH)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="-I$(LINUX_DIR)/arch/mips/bcm947xx/include -I$(PKG_BUILD_DIR)/include" \
+ modules
+endef
+
+define Package/kmod-wlcompat/install
+ install -d -m0755 $(1)/lib/modules/$(LINUX_VERSION)
+ $(CP) $(PKG_BUILD_DIR)/wlcompat.o $(1)/lib/modules/$(LINUX_VERSION)/
+ install -d -m0755 $(1)/etc/modules.d
+ echo "wlcompat" > $(1)/etc/modules.d/30-wlcompat
+endef
+
+define Package/kmod-wlcompat-debug/install
+ install -d -m0755 $(1)/lib/modules/$(LINUX_VERSION)
+ $(CP) $(PKG_BUILD_DIR)/wlcompat-debug.o $(1)/lib/modules/$(LINUX_VERSION)/
+endef
+
+$(eval $(call BuildPackage,kmod-wlcompat))
+$(eval $(call BuildPackage,kmod-wlcompat-debug))
diff --git a/package/wlcompat/src/Makefile b/package/wlcompat/src/Makefile
new file mode 100644
index 0000000000..4290d9a33a
--- /dev/null
+++ b/package/wlcompat/src/Makefile
@@ -0,0 +1,19 @@
+# $Id$
+#
+# Makefile for diag driver
+#
+# Copyright (C) 2005 Felix Fietkau <nbd@openwrt.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+
+obj-m := wlcompat.o
+
+ifeq ($(MAKING_MODULES),1)
+export-objs := wlcompat.o
+
+-include $(TOPDIR)/Rules.make
+endif
diff --git a/package/wlcompat/src/include/bcmnvram.h b/package/wlcompat/src/include/bcmnvram.h
new file mode 100644
index 0000000000..3c452634e8
--- /dev/null
+++ b/package/wlcompat/src/include/bcmnvram.h
@@ -0,0 +1,148 @@
+/*
+ * NVRAM variable manipulation
+ *
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _bcmnvram_h_
+#define _bcmnvram_h_
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+#include <typedefs.h>
+
+struct nvram_header {
+ uint32 magic;
+ uint32 len;
+ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:27 init, mem. test 28, 29-31 reserved */
+ uint32 config_refresh; /* 0:15 config, 16:31 refresh */
+ uint32 config_ncdl; /* ncdl values for memc */
+};
+
+struct nvram_tuple {
+ char *name;
+ char *value;
+ struct nvram_tuple *next;
+};
+
+/*
+ * Initialize NVRAM access. May be unnecessary or undefined on certain
+ * platforms.
+ */
+extern int nvram_init(void *sbh);
+
+/*
+ * Disable NVRAM access. May be unnecessary or undefined on certain
+ * platforms.
+ */
+extern void nvram_exit(void);
+
+/*
+ * Get the value of an NVRAM variable. The pointer returned may be
+ * invalid after a set.
+ * @param name name of variable to get
+ * @return value of variable or NULL if undefined
+ */
+extern char * nvram_get(const char *name);
+
+/*
+ * Get the value of an NVRAM variable.
+ * @param name name of variable to get
+ * @return value of variable or NUL if undefined
+ */
+#define nvram_safe_get(name) (nvram_get(name) ? : "")
+
+#define nvram_safe_unset(name) ({ \
+ if(nvram_get(name)) \
+ nvram_unset(name); \
+})
+
+#define nvram_safe_set(name, value) ({ \
+ if(!nvram_get(name) || strcmp(nvram_get(name), value)) \
+ nvram_set(name, value); \
+})
+
+/*
+ * Match an NVRAM variable.
+ * @param name name of variable to match
+ * @param match value to compare against value of variable
+ * @return TRUE if variable is defined and its value is string equal
+ * to match or FALSE otherwise
+ */
+static INLINE int
+nvram_match(char *name, char *match) {
+ const char *value = nvram_get(name);
+ return (value && !strcmp(value, match));
+}
+
+/*
+ * Inversely match an NVRAM variable.
+ * @param name name of variable to match
+ * @param match value to compare against value of variable
+ * @return TRUE if variable is defined and its value is not string
+ * equal to invmatch or FALSE otherwise
+ */
+static INLINE int
+nvram_invmatch(char *name, char *invmatch) {
+ const char *value = nvram_get(name);
+ return (value && strcmp(value, invmatch));
+}
+
+/*
+ * Set the value of an NVRAM variable. The name and value strings are
+ * copied into private storage. Pointers to previously set values
+ * may become invalid. The new value may be immediately
+ * retrieved but will not be permanently stored until a commit.
+ * @param name name of variable to set
+ * @param value value of variable
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_set(const char *name, const char *value);
+
+/*
+ * Unset an NVRAM variable. Pointers to previously set values
+ * remain valid until a set.
+ * @param name name of variable to unset
+ * @return 0 on success and errno on failure
+ * NOTE: use nvram_commit to commit this change to flash.
+ */
+extern int nvram_unset(const char *name);
+
+/*
+ * Commit NVRAM variables to permanent storage. All pointers to values
+ * may be invalid after a commit.
+ * NVRAM values are undefined after a commit.
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_commit(void);
+
+/*
+ * Get all NVRAM variables (format name=value\0 ... \0\0).
+ * @param buf buffer to store variables
+ * @param count size of buffer in bytes
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_getall(char *buf, int count);
+
+extern int file2nvram(char *filename, char *varname);
+extern int nvram2file(char *varname, char *filename);
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
+#define NVRAM_VERSION 1
+#define NVRAM_HEADER_SIZE 20
+#define NVRAM_SPACE 0x8000
+#define FLASH_BASE 0xbfc00000 /* Extif core */
+#define FLASH_MIN 0x00100000 /* Minimum flash size */
+#define FLASH_MAX 0x00400000 /* Maximum flash size with extif */
+
+#endif /* _bcmnvram_h_ */
diff --git a/package/wlcompat/src/include/bcmutils.h b/package/wlcompat/src/include/bcmutils.h
new file mode 100644
index 0000000000..05ad41d9d8
--- /dev/null
+++ b/package/wlcompat/src/include/bcmutils.h
@@ -0,0 +1,157 @@
+/*
+ * Misc useful os-independent macros and functions.
+ *
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ * $Id$
+ */
+
+#ifndef _bcmutils_h_
+#define _bcmutils_h_
+
+#ifndef MIN
+#define MIN(a, b) (((a)<(b))?(a):(b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) (((a)>(b))?(a):(b))
+#endif
+
+#define CEIL(x, y) (((x) + ((y)-1)) / (y))
+#define ROUNDUP(x, y) ((((ulong)(x)+((y)-1))/(y))*(y))
+#define ISALIGNED(a, x) (((uint)(a) & ((x)-1)) == 0)
+#define ISPOWEROF2(x) ((((x)-1)&(x))==0)
+#define OFFSETOF(type, member) ((uint) &((type *)0)->member)
+#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
+
+/* bit map related macros */
+#ifndef setbit
+#define NBBY 8 /* 8 bits per byte */
+#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+#endif
+
+#define NBITS(type) (sizeof (type) * 8)
+
+#define _BCM_U 0x01 /* upper */
+#define _BCM_L 0x02 /* lower */
+#define _BCM_D 0x04 /* digit */
+#define _BCM_C 0x08 /* cntrl */
+#define _BCM_P 0x10 /* punct */
+#define _BCM_S 0x20 /* white space (space/lf/tab) */
+#define _BCM_X 0x40 /* hex digit */
+#define _BCM_SP 0x80 /* hard space (0x20) */
+
+extern unsigned char bcm_ctype[];
+#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
+
+#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
+#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
+#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
+#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
+#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
+#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
+#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
+#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
+#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
+#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
+#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
+
+/*
+ * Spin at most 'us' microseconds while 'exp' is true.
+ * Caller should explicitly test 'exp' when this completes
+ * and take appropriate error action if 'exp' is still true.
+ */
+#define SPINWAIT(exp, us) { \
+ uint countdown = (us) + 9; \
+ while ((exp) && (countdown >= 10)) {\
+ OSL_DELAY(10); \
+ countdown -= 10; \
+ } \
+}
+
+/* generic osl packet queue */
+struct pktq {
+ void *head; /* first packet to dequeue */
+ void *tail; /* last packet to dequeue */
+ uint len; /* number of queued packets */
+ uint maxlen; /* maximum number of queued packets */
+ bool priority; /* enqueue by packet priority */
+};
+#define DEFAULT_QLEN 128
+
+#define pktq_len(q) ((q)->len)
+#define pktq_avail(q) ((q)->maxlen - (q)->len)
+#define pktq_head(q) ((q)->head)
+#define pktq_full(q) ((q)->len >= (q)->maxlen)
+
+/* crc defines */
+#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
+#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
+#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
+#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
+
+/* tag_ID/length/value_buffer tuple */
+typedef struct bcm_tlv {
+ uint8 id;
+ uint8 len;
+ uint8 data[1];
+} bcm_tlv_t;
+
+/* Check that bcm_tlv_t fits into the given buflen */
+#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (buflen) >= 2 + (elt)->len)
+
+/* buffer length for ethernet address from bcm_ether_ntoa() */
+#define ETHER_ADDR_STR_LEN 18
+
+/*
+* load 32-bit value from unaligned byte array
+*/
+#ifdef IL_BIGENDIAN
+#define load32_ua(a) ((((uint8 *)(a))[0] << 24) + (((uint8 *)(a))[1] << 16) + \
+ (((uint8 *)(a))[2] << 8) + ((uint8 *)(a))[3])
+#else
+#define load32_ua(a) ((((uint8 *)(a))[3] << 24) + (((uint8 *)(a))[2] << 16) + \
+ (((uint8 *)(a))[1] << 8) + ((uint8 *)(a))[0])
+#endif
+
+/* externs */
+extern uint bcm_atoi(char *s);
+extern uchar bcm_toupper(uchar c);
+extern ulong bcm_strtoul(char *cp, char **endp, uint base);
+extern void deadbeef(char *p, uint len);
+extern void prhex(char *msg, uchar *buf, uint len);
+extern void prpkt(char *msg, void *drv, void *p0);
+extern uint pktcopy(void *drv, void *p, uint offset, int len, uchar *buf);
+extern uint pkttotlen(void *drv, void *);
+extern uchar *bcm_ether_ntoa(char *ea, char *buf);
+extern int bcm_ether_atoe(char *p, char *ea);
+extern void bcm_mdelay(uint ms);
+extern char *getvar(char *vars, char *name);
+extern int getintvar(char *vars, char *name);
+extern char *bcmstrstr(char *haystack, char *needle);
+
+extern uint8 crc8(uint8 *p, uint nbytes, uint8 crc);
+extern uint16 crc16(uint8 *p, uint nbytes, uint16 crc);
+extern uint32 crc32(uint8 *p, uint nbytes, uint32 crc);
+extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
+extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
+extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key);
+extern void pktq_init(struct pktq *q, uint maxlen, bool priority);
+extern bool pktenq(struct pktq *q, void *p, bool lifo);
+extern void *pktdeq(struct pktq *q);
+
+#define bcmlog(fmt, a1, a2)
+#define bcmdumplog(buf, size) *buf = '\0'
+#define bcmdumplogent(buf, idx) -1
+
+#endif /* _bcmutils_h_ */
diff --git a/package/wlcompat/src/include/cy_conf.h b/package/wlcompat/src/include/cy_conf.h
new file mode 100644
index 0000000000..dbe387b83b
--- /dev/null
+++ b/package/wlcompat/src/include/cy_conf.h
@@ -0,0 +1,69 @@
+
+#define DNSMASQ_SUPPORT 1
+#define CONFIG_DNSMASQ y
+#define UDHCPD_SUPPORT 1
+#define CONFIG_UDHCPD y
+#define UDHCPC_SUPPORT 1
+#define CONFIG_UDHCPC y
+#define PPPOE_SUPPORT 1
+#define CONFIG_PPPOE y
+#define PPTP_SUPPORT 1
+#define CONFIG_PPTP y
+#define L2TP_SUPPORT 1
+#define CONFIG_L2TP y
+#define PPPD_SUPPORT 1
+#define CONFIG_PPPD y
+#define ZEBRA_SUPPORT 1
+#define CONFIG_ZEBRA y
+#define TFTPD_SUPPORT 1
+#define CONFIG_TFTPD y
+#define DDNS_SUPPORT 1
+#define CONFIG_DDNS y
+#define CRON_SUPPORT 1
+#define CONFIG_CRON y
+#define HTTPD_SUPPORT 1
+#define CONFIG_HTTPD y
+#define GET_POST_SUPPORT 1
+#define CONFIG_GET_POST y
+
+#if 1
+#define HEARTBEAT_SUPPORT 1
+#define CONFIG_HEARTBEAT y
+#define MULTICAST_SUPPORT 1
+#define CONFIG_MULTICAST y
+#define SETUP_WIZARD_SUPPORT 1
+#define CONFIG_SETUP_WIZARD y
+#define PARENTAL_CONTROL_SUPPORT 1
+#define CONFIG_PARENTAL_CONTROL y
+#define HTTPS_SUPPORT 1
+#define CONFIG_HTTPS y
+#define EOU_SUPPORT 1
+#define CONFIG_EOU y
+#define EZC_SUPPORT 1
+#define CONFIG_EZC y
+#define WRITE_MAC_SUPPORT 1
+#define CONFIG_WRITE_MAC y
+#define DIAG_SUPPORT 1
+#define CONFIG_DIAG y
+#endif
+
+#define SPEED_BOOSTER_SUPPORT 1
+#define CONFIG_SPEED_BOOSTER y
+#define XBOX_SUPPORT 1
+#define CONFIG_XBOX y
+
+#if 0
+#define MPPPOE_SUPPORT 1
+#define CONFIG_MPPPOE y
+#define UNNUMBERIP_SUPPORT 1
+#define CONFIG_UNNUMBERIP y
+#endif
+
+#define WL_STA_SUPPORT 1
+#define CONFIG_WL_STA y
+#define BACKUP_RESTORE_SUPPORT 1
+#define CONFIG_BACKUP_RESTORE y
+#define PORT_TRIGGER_SUPPORT 1
+#define CONFIG_PORT_TRIGGER y
+#define HW_QOS_SUPPORT 1
+#define CONFIG_HW_QOS y
diff --git a/package/wlcompat/src/include/epivers.h b/package/wlcompat/src/include/epivers.h
new file mode 100644
index 0000000000..e174fb50d8
--- /dev/null
+++ b/package/wlcompat/src/include/epivers.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ *
+*/
+
+#ifndef _epivers_h_
+#define _epivers_h_
+
+#ifdef linux
+#include <linux/config.h>
+#endif
+
+/* Vendor Name, ASCII, 32 chars max */
+#ifdef COMPANYNAME
+#define HPNA_VENDOR COMPANYNAME
+#else
+#define HPNA_VENDOR "Broadcom Corporation"
+#endif
+
+/* Driver Date, ASCII, 32 chars max */
+#define HPNA_DRV_BUILD_DATE __DATE__
+
+/* Hardware Manufacture Date, ASCII, 32 chars max */
+#define HPNA_HW_MFG_DATE "Not Specified"
+
+/* See documentation for Device Type values, 32 values max */
+#ifndef HPNA_DEV_TYPE
+
+#if defined(CONFIG_BRCM_VJ)
+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_DISPLAY }
+
+#elif defined(CONFIG_BCRM_93725)
+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY }
+
+#else
+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_PCINIC }
+
+#endif
+
+#endif /* !HPNA_DEV_TYPE */
+
+
+#define EPI_MAJOR_VERSION 3
+
+#define EPI_MINOR_VERSION 60
+
+#define EPI_RC_NUMBER 13
+
+#define EPI_INCREMENTAL_NUMBER 0
+
+#define EPI_BUILD_NUMBER 0
+
+#define EPI_VERSION 3,60,13,0
+
+#define EPI_VERSION_NUM 0x033c0d00
+
+/* Driver Version String, ASCII, 32 chars max */
+#define EPI_VERSION_STR "3.60.13.0"
+#define EPI_ROUTER_VERSION_STR "3.61.13.0"
+
+#endif /* _epivers_h_ */
diff --git a/package/wlcompat/src/include/proto/802.11.h b/package/wlcompat/src/include/proto/802.11.h
new file mode 100644
index 0000000000..ea57850ce5
--- /dev/null
+++ b/package/wlcompat/src/include/proto/802.11.h
@@ -0,0 +1,852 @@
+/*
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * Fundamental types and constants relating to 802.11
+ *
+ * $Id$
+ */
+
+#ifndef _802_11_H_
+#define _802_11_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+#ifndef _NET_ETHERNET_H_
+#include <proto/ethernet.h>
+#endif
+
+/* enable structure packing */
+#if !defined(__GNUC__)
+#pragma pack(1)
+#endif
+
+/* some platforms require stronger medicine */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#define PACKED
+#endif
+
+
+#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */
+
+/* Generic 802.11 frame constants */
+#define DOT11_A3_HDR_LEN 24
+#define DOT11_A4_HDR_LEN 30
+#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN
+#define DOT11_FCS_LEN 4
+#define DOT11_ICV_LEN 4
+#define DOT11_ICV_AES_LEN 8
+#define DOT11_QOS_LEN 2
+
+#define DOT11_KEY_INDEX_SHIFT 6
+#define DOT11_IV_LEN 4
+#define DOT11_IV_TKIP_LEN 8
+#define DOT11_IV_AES_OCB_LEN 4
+#define DOT11_IV_AES_CCM_LEN 8
+
+/* Includes MIC */
+#define DOT11_MAX_MPDU_BODY_LEN 2304
+/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */
+#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \
+ DOT11_QOS_LEN + \
+ DOT11_IV_AES_CCM_LEN + \
+ DOT11_MAX_MPDU_BODY_LEN + \
+ DOT11_ICV_LEN + \
+ DOT11_FCS_LEN)
+
+#define DOT11_MAX_SSID_LEN 32
+
+/* dot11RTSThreshold */
+#define DOT11_DEFAULT_RTS_LEN 2347
+#define DOT11_MAX_RTS_LEN 2347
+
+/* dot11FragmentationThreshold */
+#define DOT11_MIN_FRAG_LEN 256
+#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength of the attached PHY */
+#define DOT11_DEFAULT_FRAG_LEN 2346
+
+/* dot11BeaconPeriod */
+#define DOT11_MIN_BEACON_PERIOD 1
+#define DOT11_MAX_BEACON_PERIOD 0xFFFF
+
+/* dot11DTIMPeriod */
+#define DOT11_MIN_DTIM_PERIOD 1
+#define DOT11_MAX_DTIM_PERIOD 0xFF
+
+/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */
+#define DOT11_LLC_SNAP_HDR_LEN 8
+#define DOT11_OUI_LEN 3
+struct dot11_llc_snap_header {
+ uint8 dsap; /* always 0xAA */
+ uint8 ssap; /* always 0xAA */
+ uint8 ctl; /* always 0x03 */
+ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00
+ Bridge-Tunnel: 0x00 0x00 0xF8 */
+ uint16 type; /* ethertype */
+} PACKED;
+
+/* RFC1042 header used by 802.11 per 802.1H */
+#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN)
+
+/* Generic 802.11 MAC header */
+/*
+ * N.B.: This struct reflects the full 4 address 802.11 MAC header.
+ * The fields are defined such that the shorter 1, 2, and 3
+ * address headers just use the first k fields.
+ */
+struct dot11_header {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr a1; /* address 1 */
+ struct ether_addr a2; /* address 2 */
+ struct ether_addr a3; /* address 3 */
+ uint16 seq; /* sequence control */
+ struct ether_addr a4; /* address 4 */
+} PACKED;
+
+/* Control frames */
+
+struct dot11_rts_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+ struct ether_addr ta; /* transmitter address */
+} PACKED;
+#define DOT11_RTS_LEN 16
+
+struct dot11_cts_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+} PACKED;
+#define DOT11_CTS_LEN 10
+
+struct dot11_ack_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+} PACKED;
+#define DOT11_ACK_LEN 10
+
+struct dot11_ps_poll_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* AID */
+ struct ether_addr bssid; /* receiver address, STA in AP */
+ struct ether_addr ta; /* transmitter address */
+} PACKED;
+#define DOT11_PS_POLL_LEN 16
+
+struct dot11_cf_end_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+ struct ether_addr bssid; /* transmitter address, STA in AP */
+} PACKED;
+#define DOT11_CS_END_LEN 16
+
+/* Management frame header */
+struct dot11_management_header {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr da; /* receiver address */
+ struct ether_addr sa; /* transmitter address */
+ struct ether_addr bssid; /* BSS ID */
+ uint16 seq; /* sequence control */
+} PACKED;
+#define DOT11_MGMT_HDR_LEN 24
+
+/* Management frame payloads */
+
+struct dot11_bcn_prb {
+ uint32 timestamp[2];
+ uint16 beacon_interval;
+ uint16 capability;
+} PACKED;
+#define DOT11_BCN_PRB_LEN 12
+
+struct dot11_auth {
+ uint16 alg; /* algorithm */
+ uint16 seq; /* sequence control */
+ uint16 status; /* status code */
+} PACKED;
+#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge info elt */
+
+struct dot11_assoc_req {
+ uint16 capability; /* capability information */
+ uint16 listen; /* listen interval */
+} PACKED;
+
+struct dot11_assoc_resp {
+ uint16 capability; /* capability information */
+ uint16 status; /* status code */
+ uint16 aid; /* association ID */
+} PACKED;
+
+struct dot11_action_measure {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 data[1];
+} PACKED;
+#define DOT11_ACTION_MEASURE_LEN 3
+
+/**************
+ 802.11h related definitions.
+**************/
+typedef struct {
+ uint8 id;
+ uint8 len;
+ uint8 power;
+} dot11_power_cnst_t;
+
+typedef struct {
+ uint8 min;
+ uint8 max;
+} dot11_power_cap_t;
+
+typedef struct {
+ uint8 id;
+ uint8 len;
+ uint8 tx_pwr;
+ uint8 margin;
+} dot11_tpc_rep_t;
+#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */
+
+typedef struct {
+ uint8 id;
+ uint8 len;
+ uint8 first_channel;
+ uint8 num_channels;
+} dot11_supp_channels_t;
+
+struct dot11_channel_switch {
+ uint8 id;
+ uint8 len;
+ uint8 mode;
+ uint8 channel;
+ uint8 count;
+} PACKED;
+typedef struct dot11_channel_switch dot11_channel_switch_t;
+
+/* 802.11h Measurement Request/Report IEs */
+/* Measurement Type field */
+#define DOT11_MEASURE_TYPE_BASIC 0
+#define DOT11_MEASURE_TYPE_CCA 1
+#define DOT11_MEASURE_TYPE_RPI 2
+
+/* Measurement Mode field */
+
+/* Measurement Request Modes */
+#define DOT11_MEASURE_MODE_ENABLE (1<<1)
+#define DOT11_MEASURE_MODE_REQUEST (1<<2)
+#define DOT11_MEASURE_MODE_REPORT (1<<3)
+/* Measurement Report Modes */
+#define DOT11_MEASURE_MODE_LATE (1<<0)
+#define DOT11_MEASURE_MODE_INCAPABLE (1<<1)
+#define DOT11_MEASURE_MODE_REFUSED (1<<2)
+/* Basic Measurement Map bits */
+#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0))
+#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1))
+#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2))
+#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3))
+#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4))
+
+typedef struct {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+} dot11_meas_req_t;
+#define DOT11_MNG_IE_MREQ_LEN 14
+/* length of Measure Request IE data not including variable len */
+#define DOT11_MNG_IE_MREQ_FIXED_LEN 3
+
+struct dot11_meas_rep {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ union
+ {
+ struct {
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+ uint8 map;
+ } PACKED basic;
+ uint8 data[1];
+ } PACKED rep;
+} PACKED;
+typedef struct dot11_meas_rep dot11_meas_rep_t;
+
+/* length of Measure Report IE data not including variable len */
+#define DOT11_MNG_IE_MREP_FIXED_LEN 3
+
+struct dot11_meas_rep_basic {
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+ uint8 map;
+} PACKED;
+typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t;
+#define DOT11_MEASURE_BASIC_REP_LEN 12
+
+struct dot11_quiet {
+ uint8 id;
+ uint8 len;
+ uint8 count; /* TBTTs until beacon interval in quiet starts */
+ uint8 period; /* Beacon intervals between periodic quiet periods ? */
+ uint16 duration;/* Length of quiet period, in TU's */
+ uint16 offset; /* TU's offset from TBTT in Count field */
+} PACKED;
+typedef struct dot11_quiet dot11_quiet_t;
+
+typedef struct {
+ uint8 channel;
+ uint8 map;
+} chan_map_tuple_t;
+
+typedef struct {
+ uint8 id;
+ uint8 len;
+ uint8 eaddr[ETHER_ADDR_LEN];
+ uint8 interval;
+ chan_map_tuple_t map[1];
+} dot11_ibss_dfs_t;
+
+/* WME Elements */
+#define WME_OUI "\x00\x50\xf2"
+#define WME_VER 1
+#define WME_TYPE 2
+#define WME_SUBTYPE_IE 0 /* Information Element */
+#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */
+#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */
+
+/* WME Access Category Indices (ACIs) */
+#define AC_BE 0 /* Best Effort */
+#define AC_BK 1 /* Background */
+#define AC_VI 2 /* Video */
+#define AC_VO 3 /* Voice */
+#define AC_MAX 4
+
+/* WME Information Element (IE) */
+struct wme_ie {
+ uint8 oui[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ uint8 acinfo;
+} PACKED;
+typedef struct wme_ie wme_ie_t;
+#define WME_IE_LEN 7
+
+struct wme_acparam {
+ uint8 ACI;
+ uint8 ECW;
+ uint16 TXOP; /* stored in network order (ls octet first) */
+} PACKED;
+typedef struct wme_acparam wme_acparam_t;
+
+/* WME Parameter Element (PE) */
+struct wme_params {
+ uint8 oui[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ uint8 acinfo;
+ uint8 rsvd;
+ wme_acparam_t acparam[4];
+} PACKED;
+typedef struct wme_params wme_params_t;
+#define WME_PARAMS_IE_LEN 24
+
+/* acinfo */
+#define WME_COUNT_MASK 0x0f
+/* ACI */
+#define WME_AIFS_MASK 0x0f
+#define WME_ACM_MASK 0x10
+#define WME_ACI_MASK 0x60
+#define WME_ACI_SHIFT 5
+/* ECW */
+#define WME_CWMIN_MASK 0x0f
+#define WME_CWMAX_MASK 0xf0
+#define WME_CWMAX_SHIFT 4
+
+#define WME_TXOP_UNITS 32
+
+/* WME Traffic Specification (TSPEC) element */
+#define WME_SUBTYPE_TSPEC 2
+#define WME_TSPEC_HDR_LEN 2
+#define WME_TSPEC_BODY_OFF 2
+struct wme_tspec {
+ uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */
+ uint8 type; /* WME_TYPE */
+ uint8 subtype; /* WME_SUBTYPE_TSPEC */
+ uint8 version; /* WME_VERSION */
+ uint16 ts_info; /* TS Info */
+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */
+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */
+ uint32 min_service_interval; /* Minimum Service Interval (us) */
+ uint32 max_service_interval; /* Maximum Service Interval (us) */
+ uint32 inactivity_interval; /* Inactivity Interval (us) */
+ uint32 service_start; /* Service Start Time (us) */
+ uint32 min_rate; /* Minimum Data Rate (bps) */
+ uint32 mean_rate; /* Mean Data Rate (bps) */
+ uint32 max_burst_size; /* Maximum Burst Size (bytes) */
+ uint32 min_phy_rate; /* Minimum PHY Rate (bps) */
+ uint32 peak_rate; /* Peak Data Rate (bps) */
+ uint32 delay_bound; /* Delay Bound (us) */
+ uint16 surplus_bandwidth; /* Surplus Bandwidth Allowance Factor */
+ uint16 medium_time; /* Medium Time (32 us/s periods) */
+} PACKED;
+typedef struct wme_tspec wme_tspec_t;
+#define WME_TSPEC_LEN 56 /* not including 2-byte header */
+
+/* ts_info */
+/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */
+#define TS_INFO_PRIO_SHIFT_HI 11
+#define TS_INFO_PRIO_MASK_HI (0x7 << TS_INFO_PRIO_SHIFT_HI)
+#define TS_INFO_PRIO_SHIFT_LO 1
+#define TS_INFO_PRIO_MASK_LO (0x7 << TS_INFO_PRIO_SHIFT_LO)
+#define TS_INFO_CONTENTION_SHIFT 7
+#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT)
+#define TS_INFO_DIRECTION_SHIFT 5
+#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT)
+#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT)
+#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT)
+#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT)
+
+/* nom_msdu_size */
+#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */
+#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */
+
+/* surplus_bandwidth */
+/* Represented as 3 bits of integer, binary point, 13 bits fraction */
+#define INTEGER_SHIFT 13
+#define FRACTION_MASK 0x1FFF
+
+/* Management Notification Frame */
+struct dot11_management_notification {
+ uint8 category; /* DOT11_ACTION_NOTIFICATION */
+ uint8 action;
+ uint8 token;
+ uint8 status;
+ uint8 data[1]; /* Elements */
+} PACKED;
+#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */
+
+/* WME Action Codes */
+#define WME_SETUP_REQUEST 0
+#define WME_SETUP_RESPONSE 1
+#define WME_TEARDOWN 2
+
+/* WME Setup Response Status Codes */
+#define WME_ADMISSION_ACCEPTED 0
+#define WME_INVALID_PARAMETERS 1
+#define WME_ADMISSION_REFUSED 3
+
+/* Macro to take a pointer to a beacon or probe response
+ * header and return the char* pointer to the SSID info element
+ */
+#define BCN_PRB_SSID(hdr) ((char*)(hdr) + DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_LEN)
+
+/* Authentication frame payload constants */
+#define DOT11_OPEN_SYSTEM 0
+#define DOT11_SHARED_KEY 1
+#define DOT11_CHALLENGE_LEN 128
+
+/* Frame control macros */
+#define FC_PVER_MASK 0x3
+#define FC_PVER_SHIFT 0
+#define FC_TYPE_MASK 0xC
+#define FC_TYPE_SHIFT 2
+#define FC_SUBTYPE_MASK 0xF0
+#define FC_SUBTYPE_SHIFT 4
+#define FC_TODS 0x100
+#define FC_TODS_SHIFT 8
+#define FC_FROMDS 0x200
+#define FC_FROMDS_SHIFT 9
+#define FC_MOREFRAG 0x400
+#define FC_MOREFRAG_SHIFT 10
+#define FC_RETRY 0x800
+#define FC_RETRY_SHIFT 11
+#define FC_PM 0x1000
+#define FC_PM_SHIFT 12
+#define FC_MOREDATA 0x2000
+#define FC_MOREDATA_SHIFT 13
+#define FC_WEP 0x4000
+#define FC_WEP_SHIFT 14
+#define FC_ORDER 0x8000
+#define FC_ORDER_SHIFT 15
+
+/* sequence control macros */
+#define SEQNUM_SHIFT 4
+#define FRAGNUM_MASK 0xF
+
+/* Frame Control type/subtype defs */
+
+/* FC Types */
+#define FC_TYPE_MNG 0
+#define FC_TYPE_CTL 1
+#define FC_TYPE_DATA 2
+
+/* Management Subtypes */
+#define FC_SUBTYPE_ASSOC_REQ 0
+#define FC_SUBTYPE_ASSOC_RESP 1
+#define FC_SUBTYPE_REASSOC_REQ 2
+#define FC_SUBTYPE_REASSOC_RESP 3
+#define FC_SUBTYPE_PROBE_REQ 4
+#define FC_SUBTYPE_PROBE_RESP 5
+#define FC_SUBTYPE_BEACON 8
+#define FC_SUBTYPE_ATIM 9
+#define FC_SUBTYPE_DISASSOC 10
+#define FC_SUBTYPE_AUTH 11
+#define FC_SUBTYPE_DEAUTH 12
+#define FC_SUBTYPE_ACTION 13
+
+/* Control Subtypes */
+#define FC_SUBTYPE_PS_POLL 10
+#define FC_SUBTYPE_RTS 11
+#define FC_SUBTYPE_CTS 12
+#define FC_SUBTYPE_ACK 13
+#define FC_SUBTYPE_CF_END 14
+#define FC_SUBTYPE_CF_END_ACK 15
+
+/* Data Subtypes */
+#define FC_SUBTYPE_DATA 0
+#define FC_SUBTYPE_DATA_CF_ACK 1
+#define FC_SUBTYPE_DATA_CF_POLL 2
+#define FC_SUBTYPE_DATA_CF_ACK_POLL 3
+#define FC_SUBTYPE_NULL 4
+#define FC_SUBTYPE_CF_ACK 5
+#define FC_SUBTYPE_CF_POLL 6
+#define FC_SUBTYPE_CF_ACK_POLL 7
+#define FC_SUBTYPE_QOS_DATA 8
+#define FC_SUBTYPE_QOS_NULL 12
+
+/* type-subtype combos */
+#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK)
+
+#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT))
+
+#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ)
+#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP)
+#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ)
+#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP)
+#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ)
+#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP)
+#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON)
+#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC)
+#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH)
+#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH)
+#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION)
+
+#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL)
+#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS)
+#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS)
+#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK)
+#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END)
+#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK)
+
+#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA)
+#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL)
+#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK)
+#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA)
+#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL)
+
+/* QoS Control Field */
+
+/* 802.1D Tag */
+#define QOS_PRIO_SHIFT 0
+#define QOS_PRIO_MASK 0x0007
+#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT)
+
+/* Ack Policy (0 means Acknowledge) */
+#define QOS_ACK_SHIFT 5
+#define QOS_ACK_MASK 0x0060
+#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT)
+
+/* Management Frames */
+
+/* Management Frame Constants */
+
+/* Fixed fields */
+#define DOT11_MNG_AUTH_ALGO_LEN 2
+#define DOT11_MNG_AUTH_SEQ_LEN 2
+#define DOT11_MNG_BEACON_INT_LEN 2
+#define DOT11_MNG_CAP_LEN 2
+#define DOT11_MNG_AP_ADDR_LEN 6
+#define DOT11_MNG_LISTEN_INT_LEN 2
+#define DOT11_MNG_REASON_LEN 2
+#define DOT11_MNG_AID_LEN 2
+#define DOT11_MNG_STATUS_LEN 2
+#define DOT11_MNG_TIMESTAMP_LEN 8
+
+/* DUR/ID field in assoc resp is 0xc000 | AID */
+#define DOT11_AID_MASK 0x3fff
+
+/* Reason Codes */
+#define DOT11_RC_RESERVED 0
+#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */
+#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */
+#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station is
+ leaving (or has left) IBSS or ESS */
+#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */
+#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle
+ all currently associated stations */
+#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from
+ nonauthenticated station */
+#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from
+ nonassociated station */
+#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is
+ leaving (or has left) BSS */
+#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is
+ not authenticated with responding station */
+#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */
+
+/* Status Codes */
+#define DOT11_STATUS_SUCCESS 0 /* Successful */
+#define DOT11_STATUS_FAILURE 1 /* Unspecified failure */
+#define DOT11_STATUS_CAP_MISMATCH 10 /* Cannot support all requested capabilities
+ in the Capability Information field */
+#define DOT11_STATUS_REASSOC_FAIL 11 /* Reassociation denied due to inability to
+ confirm that association exists */
+#define DOT11_STATUS_ASSOC_FAIL 12 /* Association denied due to reason outside
+ the scope of this standard */
+#define DOT11_STATUS_AUTH_MISMATCH 13 /* Responding station does not support the
+ specified authentication algorithm */
+#define DOT11_STATUS_AUTH_SEQ 14 /* Received an Authentication frame with
+ authentication transaction sequence number
+ out of expected sequence */
+#define DOT11_STATUS_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of challenge failure */
+#define DOT11_STATUS_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout waiting
+ for next frame in sequence */
+#define DOT11_STATUS_ASSOC_BUSY_FAIL 17 /* Association denied because AP is unable to
+ handle additional associated stations */
+#define DOT11_STATUS_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting station
+ not supporting all of the data rates in the
+ BSSBasicRateSet parameter */
+#define DOT11_STATUS_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting station
+ not supporting the Short Preamble option */
+#define DOT11_STATUS_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting station
+ not supporting the PBCC Modulation option */
+#define DOT11_STATUS_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting station
+ not supporting the Channel Agility option */
+#define DOT11_STATUS_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum Management
+ capability is required. */
+#define DOT11_STATUS_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info in the
+ Power Cap element is unacceptable. */
+#define DOT11_STATUS_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info in the
+ Supported Channel element is unacceptable */
+#define DOT11_STATUS_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting station
+ not supporting the Short Slot Time option */
+#define DOT11_STATUS_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting station
+ not supporting the ER-PBCC Modulation option */
+#define DOT11_STATUS_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting station
+ not supporting the DSS-OFDM option */
+
+/* Info Elts, length of INFORMATION portion of Info Elts */
+#define DOT11_MNG_DS_PARAM_LEN 1
+#define DOT11_MNG_IBSS_PARAM_LEN 2
+
+/* TIM Info element has 3 bytes fixed info in INFORMATION field,
+ * followed by 1 to 251 bytes of Partial Virtual Bitmap */
+#define DOT11_MNG_TIM_FIXED_LEN 3
+#define DOT11_MNG_TIM_DTIM_COUNT 0
+#define DOT11_MNG_TIM_DTIM_PERIOD 1
+#define DOT11_MNG_TIM_BITMAP_CTL 2
+#define DOT11_MNG_TIM_PVB 3
+
+/* TLV defines */
+#define TLV_TAG_OFF 0
+#define TLV_LEN_OFF 1
+#define TLV_HDR_LEN 2
+#define TLV_BODY_OFF 2
+
+/* Management Frame Information Element IDs */
+#define DOT11_MNG_SSID_ID 0
+#define DOT11_MNG_RATES_ID 1
+#define DOT11_MNG_FH_PARMS_ID 2
+#define DOT11_MNG_DS_PARMS_ID 3
+#define DOT11_MNG_CF_PARMS_ID 4
+#define DOT11_MNG_TIM_ID 5
+#define DOT11_MNG_IBSS_PARMS_ID 6
+#define DOT11_MNG_COUNTRY_ID 7
+#define DOT11_MNG_HOPPING_PARMS_ID 8
+#define DOT11_MNG_HOPPING_TABLE_ID 9
+#define DOT11_MNG_REQUEST_ID 10
+#define DOT11_MNG_CHALLENGE_ID 16
+#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */
+#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */
+#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */
+#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */
+#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */
+#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement*/
+#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */
+#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */
+#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */
+#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */
+#define DOT11_MNG_ERP_ID 42
+#define DOT11_MNG_NONERP_ID 47
+#define DOT11_MNG_EXT_RATES_ID 50
+#define DOT11_MNG_WPA_ID 221
+#define DOT11_MNG_PROPR_ID 221
+
+/* ERP info element bit values */
+#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */
+#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present in the BSS */
+#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for ERP-OFDM frames */
+#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, 1 == not allowed */
+
+/* Capability Information Field */
+#define DOT11_CAP_ESS 0x0001
+#define DOT11_CAP_IBSS 0x0002
+#define DOT11_CAP_POLLABLE 0x0004
+#define DOT11_CAP_POLL_RQ 0x0008
+#define DOT11_CAP_PRIVACY 0x0010
+#define DOT11_CAP_SHORT 0x0020
+#define DOT11_CAP_PBCC 0x0040
+#define DOT11_CAP_AGILITY 0x0080
+#define DOT11_CAP_SPECTRUM 0x0100
+#define DOT11_CAP_SHORTSLOT 0x0400
+#define DOT11_CAP_CCK_OFDM 0x2000
+
+/* Action Frame Constants */
+#define DOT11_ACTION_CAT_ERR_MASK 0x80
+#define DOT11_ACTION_CAT_SPECT_MNG 0x00
+#define DOT11_ACTION_NOTIFICATION 0x11 /* 17 */
+
+#define DOT11_ACTION_ID_M_REQ 0
+#define DOT11_ACTION_ID_M_REP 1
+#define DOT11_ACTION_ID_TPC_REQ 2
+#define DOT11_ACTION_ID_TPC_REP 3
+#define DOT11_ACTION_ID_CHANNEL_SWITCH 4
+
+/* MLME Enumerations */
+#define DOT11_BSSTYPE_INFRASTRUCTURE 0
+#define DOT11_BSSTYPE_INDEPENDENT 1
+#define DOT11_BSSTYPE_ANY 2
+#define DOT11_SCANTYPE_ACTIVE 0
+#define DOT11_SCANTYPE_PASSIVE 1
+
+/* 802.11 A PHY constants */
+#define APHY_SLOT_TIME 9
+#define APHY_SIFS_TIME 16
+#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME))
+#define APHY_PREAMBLE_TIME 16
+#define APHY_SIGNAL_TIME 4
+#define APHY_SYMBOL_TIME 4
+#define APHY_SERVICE_NBITS 16
+#define APHY_TAIL_NBITS 6
+#define APHY_CWMIN 15
+
+/* 802.11 B PHY constants */
+#define BPHY_SLOT_TIME 20
+#define BPHY_SIFS_TIME 10
+#define BPHY_DIFS_TIME 50
+#define BPHY_PLCP_TIME 192
+#define BPHY_PLCP_SHORT_TIME 96
+#define BPHY_CWMIN 31
+
+/* 802.11 G constants */
+#define DOT11_OFDM_SIGNAL_EXTENSION 6
+
+#define PHY_CWMAX 1023
+
+#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */
+
+/* dot11Counters Table - 802.11 spec., Annex D */
+typedef struct d11cnt {
+ uint32 txfrag; /* dot11TransmittedFragmentCount */
+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */
+ uint32 txfail; /* dot11FailedCount */
+ uint32 txretry; /* dot11RetryCount */
+ uint32 txretrie; /* dot11MultipleRetryCount */
+ uint32 rxdup; /* dot11FrameduplicateCount */
+ uint32 txrts; /* dot11RTSSuccessCount */
+ uint32 txnocts; /* dot11RTSFailureCount */
+ uint32 txnoack; /* dot11ACKFailureCount */
+ uint32 rxfrag; /* dot11ReceivedFragmentCount */
+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */
+ uint32 rxcrc; /* dot11FCSErrorCount */
+ uint32 txfrmsnt; /* dot11TransmittedFrameCount */
+ uint32 rxundec; /* dot11WEPUndecryptableCount */
+} d11cnt_t;
+
+/* BRCM OUI */
+#define BRCM_OUI "\x00\x10\x18"
+
+/* BRCM info element */
+struct brcm_ie {
+ uchar id;
+ uchar len;
+ uchar oui[3];
+ uchar ver;
+ uchar assoc; /* # of assoc STAs */
+ uchar flags; /* misc flags */
+} PACKED;
+#define BRCM_IE_LEN 8
+typedef struct brcm_ie brcm_ie_t;
+#define BRCM_IE_VER 1
+
+/* brcm_ie flags */
+#define BRF_ABCAP 0x1 /* afterburner capable */
+#define BRF_ABRQRD 0x2 /* afterburner requested */
+
+/* WPA definitions */
+#define WPA_VERSION 1
+#define WPA_OUI "\x00\x50\xF2"
+
+#define WPA_OUI_LEN 3
+
+/* WPA authentication modes */
+#define WPA_AUTH_NONE 0 /* None */
+#define WPA_AUTH_UNSPECIFIED 1 /* Unspecified authentication over 802.1X: default for WPA */
+#define WPA_AUTH_PSK 2 /* Pre-shared Key over 802.1X */
+#define WPA_AUTH_DISABLED 255 /* Legacy (i.e., non-WPA) */
+
+#define IS_WPA_AUTH(auth) ((auth) == WPA_AUTH_NONE || \
+ (auth) == WPA_AUTH_UNSPECIFIED || \
+ (auth) == WPA_AUTH_PSK)
+
+
+/* Key related defines */
+#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */
+#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */
+#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */
+#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */
+
+#define WEP1_KEY_SIZE 5 /* max size of any WEP key */
+#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */
+#define WEP128_KEY_SIZE 13 /* max size of any WEP key */
+#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */
+#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */
+#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */
+#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */
+#define TKIP_KEY_SIZE 32 /* size of any TKIP key */
+#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */
+#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */
+#define TKIP_MIC_SUP_RX 16 /* offset to Supplicant MIC RX key */
+#define TKIP_MIC_SUP_TX 24 /* offset to Supplicant MIC TX key */
+#define AES_KEY_SIZE 16 /* size of AES key */
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _802_11_H_ */
diff --git a/package/wlcompat/src/include/proto/ethernet.h b/package/wlcompat/src/include/proto/ethernet.h
new file mode 100644
index 0000000000..173464af63
--- /dev/null
+++ b/package/wlcompat/src/include/proto/ethernet.h
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * $Id$
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet.
+ ******************************************************************************/
+
+#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */
+#define _NET_ETHERNET_H_
+
+#ifndef _TYPEDEFS_H_
+#include "typedefs.h"
+#endif
+
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#define PACKED
+#endif
+
+/*
+ * The number of bytes in an ethernet (MAC) address.
+ */
+#ifndef ETHER_ADDR_LEN
+#define ETHER_ADDR_LEN 6
+#endif
+
+/*
+ * The number of bytes in the type field.
+ */
+#ifndef ETHER_TYPE_LEN
+#define ETHER_TYPE_LEN 2
+#endif
+
+/*
+ * The number of bytes in the trailing CRC field.
+ */
+#ifndef ETHER_CRC_LEN
+#define ETHER_CRC_LEN 4
+#endif
+
+/*
+ * The length of the combined header.
+ */
+#ifndef ETHER_HDR_LEN
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
+#endif
+
+/*
+ * The minimum packet length.
+ */
+#ifndef ETHER_MIN_LEN
+#define ETHER_MIN_LEN 64
+#endif
+
+/*
+ * The minimum packet user data length.
+ */
+#ifndef ETHER_MIN_DATA
+#define ETHER_MIN_DATA 46
+#endif
+
+/*
+ * The maximum packet length.
+ */
+#ifndef ETHER_MAX_LEN
+#define ETHER_MAX_LEN 1518
+#endif
+
+/*
+ * The maximum packet user data length.
+ */
+#define ETHER_MAX_DATA 1500
+
+/*
+ * Used to uniquely identify a 802.1q VLAN-tagged header.
+ */
+#define VLAN_TAG 0x8100
+
+/*
+ * Located after dest & src address in ether header.
+ */
+#define VLAN_FIELDS_OFFSET (ETHER_ADDR_LEN * 2)
+
+/*
+ * 4 bytes of vlan field info.
+ */
+#define VLAN_FIELDS_SIZE 4
+
+/* location of bits in 16-bit vlan fields */
+#define VLAN_PRI_SHIFT 13 /* user priority */
+#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */
+
+/* 3 bits of priority */
+#define VLAN_PRI_MASK 7
+/* 12 bits of vlan identfier (VID) */
+#define VLAN_VID_MASK 0xFFF /* VLAN identifier (VID) field */
+
+struct vlan_tags {
+ uint16 tag_type; /* 0x8100 for VLAN */
+ uint16 tag_control; /* prio | cfi | vid */
+} PACKED ;
+
+/* 802.1X ethertype */
+
+#define ETHER_TYPE_IP 0x0800 /* IP */
+#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */
+#define ETHER_TYPE_802_1X 0x888e /* 802.1x */
+
+#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4byte subtype follows ethertype */
+#define ETHER_BRCM_CRAM 0x1 /* Broadcom subtype cram protocol */
+
+/*
+ * A macro to validate a length with
+ */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+#ifndef __NET_ETHERNET_H
+#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+struct ether_header {
+ uint8 ether_dhost[ETHER_ADDR_LEN];
+ uint8 ether_shost[ETHER_ADDR_LEN];
+ uint16 ether_type;
+} PACKED ;
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+struct ether_addr {
+ uint8 octet[ETHER_ADDR_LEN];
+} PACKED ;
+#endif
+#endif
+
+/*
+ * Takes a pointer, returns true if a 48-bit multicast address
+ * (including broadcast, since it is all ones)
+ */
+#define ETHER_ISMULTI(ea) (((uint8 *)(ea))[0] & 1)
+
+/*
+ * Takes a pointer, returns true if a 48-bit broadcast (all ones)
+ */
+#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \
+ ((uint8 *)(ea))[1] & \
+ ((uint8 *)(ea))[2] & \
+ ((uint8 *)(ea))[3] & \
+ ((uint8 *)(ea))[4] & \
+ ((uint8 *)(ea))[5]) == 0xff)
+
+static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}};
+
+/*
+ * Takes a pointer, returns true if a 48-bit null address (all zeros)
+ */
+#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \
+ ((uint8 *)(ea))[1] | \
+ ((uint8 *)(ea))[2] | \
+ ((uint8 *)(ea))[3] | \
+ ((uint8 *)(ea))[4] | \
+ ((uint8 *)(ea))[5]) == 0)
+
+/* Differentiated Services Codepoint - lower 6 bits of tos in iphdr */
+#define DSCP_PRI_MASK 0x3F /* bits 0-6 */
+#define DSCP_WME_PRI_MASK 0x38 /* bits 3-6 */
+#define DSCP_WME_PRI_SHIFT 3
+
+#undef PACKED
+
+#endif /* _NET_ETHERNET_H_ */
diff --git a/package/wlcompat/src/include/shutils.h b/package/wlcompat/src/include/shutils.h
new file mode 100644
index 0000000000..783ee9ede1
--- /dev/null
+++ b/package/wlcompat/src/include/shutils.h
@@ -0,0 +1,200 @@
+/*
+ * Shell-like utility functions
+ *
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _shutils_h_
+#define _shutils_h_
+#include <string.h>
+/*
+ * Reads file and returns contents
+ * @param fd file descriptor
+ * @return contents of file or NULL if an error occurred
+ */
+extern char * fd2str(int fd);
+
+/*
+ * Reads file and returns contents
+ * @param path path to file
+ * @return contents of file or NULL if an error occurred
+ */
+extern char * file2str(const char *path);
+
+/*
+ * Waits for a file descriptor to become available for reading or unblocked signal
+ * @param fd file descriptor
+ * @param timeout seconds to wait before timing out or 0 for no timeout
+ * @return 1 if descriptor changed status or 0 if timed out or -1 on error
+ */
+extern int waitfor(int fd, int timeout);
+
+/*
+ * Concatenates NULL-terminated list of arguments into a single
+ * commmand and executes it
+ * @param argv argument list
+ * @param path NULL, ">output", or ">>output"
+ * @param timeout seconds to wait before timing out or 0 for no timeout
+ * @param ppid NULL to wait for child termination or pointer to pid
+ * @return return value of executed command or errno
+ */
+extern int _eval(char *const argv[], char *path, int timeout, pid_t *ppid);
+
+/*
+ * Concatenates NULL-terminated list of arguments into a single
+ * commmand and executes it
+ * @param argv argument list
+ * @return stdout of executed command or NULL if an error occurred
+ */
+extern char * _backtick(char *const argv[]);
+
+/*
+ * Kills process whose PID is stored in plaintext in pidfile
+ * @param pidfile PID file
+ * @return 0 on success and errno on failure
+ */
+extern int kill_pidfile(char *pidfile);
+
+/*
+ * fread() with automatic retry on syscall interrupt
+ * @param ptr location to store to
+ * @param size size of each element of data
+ * @param nmemb number of elements
+ * @param stream file stream
+ * @return number of items successfully read
+ */
+extern int safe_fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+
+/*
+ * fwrite() with automatic retry on syscall interrupt
+ * @param ptr location to read from
+ * @param size size of each element of data
+ * @param nmemb number of elements
+ * @param stream file stream
+ * @return number of items successfully written
+ */
+extern int safe_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
+
+/*
+ * Convert Ethernet address string representation to binary data
+ * @param a string in xx:xx:xx:xx:xx:xx notation
+ * @param e binary data
+ * @return TRUE if conversion was successful and FALSE otherwise
+ */
+extern int ether_atoe(const char *a, unsigned char *e);
+
+/*
+ * Convert Ethernet address binary data to string representation
+ * @param e binary data
+ * @param a string in xx:xx:xx:xx:xx:xx notation
+ * @return a
+ */
+extern char * ether_etoa(const unsigned char *e, char *a);
+
+/*
+ * Concatenate two strings together into a caller supplied buffer
+ * @param s1 first string
+ * @param s2 second string
+ * @param buf buffer large enough to hold both strings
+ * @return buf
+ */
+static inline char * strcat_r(const char *s1, const char *s2, char *buf)
+{
+ strcpy(buf, s1);
+ strcat(buf, s2);
+ return buf;
+}
+
+/* Check for a blank character; that is, a space or a tab */
+#define isblank(c) ((c) == ' ' || (c) == '\t')
+
+/* Strip trailing CR/NL from string <s> */
+#define chomp(s) ({ \
+ char *c = (s) + strlen((s)) - 1; \
+ while ((c > (s)) && (*c == '\n' || *c == '\r' || *c == ' ')) \
+ *c-- = '\0'; \
+ s; \
+})
+
+/* Simple version of _backtick() */
+#define backtick(cmd, args...) ({ \
+ char *argv[] = { cmd, ## args, NULL }; \
+ _backtick(argv); \
+})
+
+/* Simple version of _eval() (no timeout and wait for child termination) */
+#define eval(cmd, args...) ({ \
+ char *argv[] = { cmd, ## args, NULL }; \
+ _eval(argv, ">/dev/console", 0, NULL); \
+})
+
+/* Copy each token in wordlist delimited by space into word */
+#define foreach(word, wordlist, next) \
+ for (next = &wordlist[strspn(wordlist, " ")], \
+ strncpy(word, next, sizeof(word)), \
+ word[strcspn(word, " ")] = '\0', \
+ word[sizeof(word) - 1] = '\0', \
+ next = strchr(next, ' '); \
+ strlen(word); \
+ next = next ? &next[strspn(next, " ")] : "", \
+ strncpy(word, next, sizeof(word)), \
+ word[strcspn(word, " ")] = '\0', \
+ word[sizeof(word) - 1] = '\0', \
+ next = strchr(next, ' '))
+
+/* Return NUL instead of NULL if undefined */
+#define safe_getenv(s) (getenv(s) ? : "")
+
+/* Print directly to the console */
+#define cprintf(fmt, args...) do { \
+ FILE *fp = fopen("/dev/console", "w"); \
+ if (fp) { \
+ fprintf(fp, fmt, ## args); \
+ fclose(fp); \
+ } \
+} while (0)
+
+/* Debug print */
+#ifdef DEBUG
+#define dprintf(fmt, args...) cprintf("%s: " fmt, __FUNCTION__, ## args)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+#ifdef vxworks
+
+#include <inetLib.h>
+#define inet_aton(a, n) ((inet_aton((a), (n)) == ERROR) ? 0 : 1)
+#define inet_ntoa(n) ({ char a[INET_ADDR_LEN]; inet_ntoa_b ((n), a); a; })
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#define ether_atoe(a, e) bcm_ether_atoe((a), (e))
+#define ether_etoa(e, a) bcm_ether_ntoa((e), (a))
+
+/* These declarations are not available where you would expect them */
+extern int vsnprintf (char *, size_t, const char *, va_list);
+extern int snprintf(char *str, size_t count, const char *fmt, ...);
+extern char *strdup(const char *);
+extern char *strsep(char **stringp, char *delim);
+extern int strcasecmp(const char *s1, const char *s2);
+extern int strncasecmp(const char *s1, const char *s2, size_t n);
+
+/* Neither are socket() and connect() */
+#include <sockLib.h>
+
+#ifdef DEBUG
+#undef dprintf
+#define dprintf printf
+#endif
+#endif
+
+#endif /* _shutils_h_ */
diff --git a/package/wlcompat/src/include/typedefs.h b/package/wlcompat/src/include/typedefs.h
new file mode 100644
index 0000000000..6b0c25e042
--- /dev/null
+++ b/package/wlcompat/src/include/typedefs.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ * $Id$
+ */
+
+#ifndef _TYPEDEFS_H_
+#define _TYPEDEFS_H_
+
+
+/* Define 'SITE_TYPEDEFS' in the compile to include a site specific
+ * typedef file "site_typedefs.h".
+ *
+ * If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs"
+ * section of this file makes inferences about the compile environment
+ * based on defined symbols and possibly compiler pragmas.
+ *
+ * Following these two sections is the "Default Typedefs"
+ * section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is
+ * defined. This section has a default set of typedefs and a few
+ * proprocessor symbols (TRUE, FALSE, NULL, ...).
+ */
+
+#ifdef SITE_TYPEDEFS
+
+/*******************************************************************************
+ * Site Specific Typedefs
+ *******************************************************************************/
+
+#include "site_typedefs.h"
+
+#else
+
+/*******************************************************************************
+ * Inferred Typedefs
+ *******************************************************************************/
+
+/* Infer the compile environment based on preprocessor symbols and pramas.
+ * Override type definitions as needed, and include configuration dependent
+ * header files to define types.
+ */
+
+#ifdef __cplusplus
+
+#define TYPEDEF_BOOL
+#ifndef FALSE
+#define FALSE false
+#endif
+#ifndef TRUE
+#define TRUE true
+#endif
+
+#else /* ! __cplusplus */
+
+/* for Windows build, define bool as a uchar instead of the default int */
+#if defined(_WIN32)
+
+#define TYPEDEF_BOOL
+typedef unsigned char bool;
+
+#endif /* _WIN32 */
+
+#endif /* ! __cplusplus */
+
+#ifdef _MSC_VER /* Microsoft C */
+#define TYPEDEF_INT64
+#define TYPEDEF_UINT64
+typedef signed __int64 int64;
+typedef unsigned __int64 uint64;
+#endif
+
+#if defined(MACOSX) && defined(KERNEL)
+#define TYPEDEF_BOOL
+#endif
+
+
+#if defined(linux)
+#define TYPEDEF_UINT
+#define TYPEDEF_USHORT
+#define TYPEDEF_ULONG
+#endif
+
+#if !defined(linux) && !defined(_WIN32) && !defined(PMON) && !defined(_CFE_)
+#define TYPEDEF_UINT
+#define TYPEDEF_USHORT
+#endif
+
+
+/* Do not support the (u)int64 types with strict ansi for GNU C */
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+#define TYPEDEF_INT64
+#define TYPEDEF_UINT64
+#endif
+
+/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode
+ * for singned or unsigned */
+#if defined(__ICL)
+
+#define TYPEDEF_INT64
+
+#if defined(__STDC__)
+#define TYPEDEF_UINT64
+#endif
+
+#endif /* __ICL */
+
+
+#if !defined(_WIN32) && !defined(PMON) && !defined(_CFE_)
+
+/* pick up ushort & uint from standard types.h */
+#if defined(linux) && defined(__KERNEL__)
+
+#include <linux/types.h> /* sys/types.h and linux/types.h are oil and water */
+
+#else
+
+#include <sys/types.h>
+
+#endif
+
+#endif /* !_WIN32 && !PMON && !_CFE_ */
+
+#if defined(MACOSX) && defined(KERNEL)
+#include <IOKit/IOTypes.h>
+#endif
+
+
+/* use the default typedefs in the next section of this file */
+#define USE_TYPEDEF_DEFAULTS
+
+#endif /* SITE_TYPEDEFS */
+
+
+/*******************************************************************************
+ * Default Typedefs
+ *******************************************************************************/
+
+#ifdef USE_TYPEDEF_DEFAULTS
+#undef USE_TYPEDEF_DEFAULTS
+
+#ifndef TYPEDEF_BOOL
+typedef int bool;
+#endif
+
+/*----------------------- define uchar, ushort, uint, ulong ----------------*/
+
+#ifndef TYPEDEF_UCHAR
+typedef unsigned char uchar;
+#endif
+
+#ifndef TYPEDEF_USHORT
+typedef unsigned short ushort;
+#endif
+
+#ifndef TYPEDEF_UINT
+typedef unsigned int uint;
+#endif
+
+#ifndef TYPEDEF_ULONG
+typedef unsigned long ulong;
+#endif
+
+/*----------------------- define [u]int8/16/32/64 --------------------------*/
+
+#ifndef TYPEDEF_UINT8
+typedef unsigned char uint8;
+#endif
+
+#ifndef TYPEDEF_UINT16
+typedef unsigned short uint16;
+#endif
+
+#ifndef TYPEDEF_UINT32
+typedef unsigned int uint32;
+#endif
+
+#ifndef TYPEDEF_UINT64
+typedef unsigned long long uint64;
+#endif
+
+#ifndef TYPEDEF_INT8
+typedef signed char int8;
+#endif
+
+#ifndef TYPEDEF_INT16
+typedef signed short int16;
+#endif
+
+#ifndef TYPEDEF_INT32
+typedef signed int int32;
+#endif
+
+#ifndef TYPEDEF_INT64
+typedef signed long long int64;
+#endif
+
+/*----------------------- define float32/64, float_t -----------------------*/
+
+#ifndef TYPEDEF_FLOAT32
+typedef float float32;
+#endif
+
+#ifndef TYPEDEF_FLOAT64
+typedef double float64;
+#endif
+
+/*
+ * abstracted floating point type allows for compile time selection of
+ * single or double precision arithmetic. Compiling with -DFLOAT32
+ * selects single precision; the default is double precision.
+ */
+
+#ifndef TYPEDEF_FLOAT_T
+
+#if defined(FLOAT32)
+typedef float32 float_t;
+#else /* default to double precision floating point */
+typedef float64 float_t;
+#endif
+
+#endif /* TYPEDEF_FLOAT_T */
+
+/*----------------------- define macro values -----------------------------*/
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef OFF
+#define OFF 0
+#endif
+
+#ifndef ON
+#define ON 1
+#endif
+
+/*----------------------- define PTRSZ, INLINE ----------------------------*/
+
+#ifndef PTRSZ
+#define PTRSZ sizeof (char*)
+#endif
+
+#ifndef INLINE
+
+#ifdef _MSC_VER
+
+#define INLINE __inline
+
+#elif __GNUC__
+
+#define INLINE __inline__
+
+#else
+
+#define INLINE
+
+#endif /* _MSC_VER */
+
+#endif /* INLINE */
+
+#undef TYPEDEF_BOOL
+#undef TYPEDEF_UCHAR
+#undef TYPEDEF_USHORT
+#undef TYPEDEF_UINT
+#undef TYPEDEF_ULONG
+#undef TYPEDEF_UINT8
+#undef TYPEDEF_UINT16
+#undef TYPEDEF_UINT32
+#undef TYPEDEF_UINT64
+#undef TYPEDEF_INT8
+#undef TYPEDEF_INT16
+#undef TYPEDEF_INT32
+#undef TYPEDEF_INT64
+#undef TYPEDEF_FLOAT32
+#undef TYPEDEF_FLOAT64
+#undef TYPEDEF_FLOAT_T
+
+#endif /* USE_TYPEDEF_DEFAULTS */
+
+#endif /* _TYPEDEFS_H_ */
diff --git a/package/wlcompat/src/include/utils.h b/package/wlcompat/src/include/utils.h
new file mode 100644
index 0000000000..b8d1cdb7bf
--- /dev/null
+++ b/package/wlcompat/src/include/utils.h
@@ -0,0 +1,131 @@
+#include <cy_conf.h>
+
+extern int diag_led(int type, int act);
+extern int C_led(int i);
+extern int get_single_ip(char *ipaddr, int which);
+extern char *get_mac_from_ip(char *ip);
+extern struct dns_lists *get_dns_list(int no);
+extern int dns_to_resolv(void);
+extern char *get_wan_face(void);
+extern int check_wan_link(int num);
+extern char *get_complete_lan_ip(char *ip);
+extern int get_int_len(int num);
+extern int file_to_buf(char *path, char *buf, int len);
+extern int buf_to_file(char *path, char *buf);
+extern pid_t* find_pid_by_name( char* pidName);
+extern int find_pid_by_ps(char* pidName);
+extern int *find_all_pid_by_ps(char* pidName);
+extern char *find_name_by_proc(int pid);
+extern int get_ppp_pid(char *file);
+extern long convert_ver(char *ver);
+extern int check_flash(void);
+extern int check_action(void);
+extern int check_now_boot(void);
+extern int check_hw_type(void);
+extern int is_exist(char *filename);
+extern void set_ip_forward(char c);
+struct mtu_lists *get_mtu(char *proto);
+extern void set_host_domain_name(void);
+
+extern void encode(char *buf, int len);
+extern void decode(char *buf, int len);
+
+extern int sys_netdev_ioctl(int family, int socket, char *if_name, int cmd, struct ifreq *ifr);
+
+int ct_openlog(const char *ident, int option, int facility, char *log_name);
+void ct_syslog(int level, int enable, const char *fmt,...);
+void ct_logger(int level, const char *fmt,...);
+struct wl_assoc_mac * get_wl_assoc_mac(int *c);
+
+
+
+enum { DMZ, SESSION, DIAG , WL};
+
+enum { START_LED, STOP_LED };
+
+typedef enum { ACT_IDLE,
+ ACT_TFTP_UPGRADE,
+ ACT_WEB_UPGRADE,
+ ACT_WEBS_UPGRADE,
+ ACT_SW_RESTORE,
+ ACT_HW_RESTORE } ACTION;
+
+enum { UNKNOWN_BOOT = -1, PMON_BOOT, CFE_BOOT };
+
+enum { BCM4702_CHIP, BCM4712_CHIP, BCM5325E_CHIP };
+
+enum { FIRST, SECOND };
+
+enum { SYSLOG_LOG=1, SYSLOG_DEBUG, CONSOLE_ONLY, LOG_CONSOLE, DEBUG_CONSOLE };
+
+#define ACTION(cmd) buf_to_file(ACTION_FILE, cmd)
+
+struct dns_lists {
+ int num_servers;
+ char dns_server[4][16];
+};
+
+#define NOT_USING 0
+#define USING 1
+
+struct wl_assoc_mac
+{
+ char mac[18];
+};
+
+struct mtu_lists {
+ char *proto; /* protocol */
+ char *min; /* min mtu */
+ char *max; /* max mtu */
+};
+
+
+#define PPP_PSEUDO_IP "10.64.64.64"
+#define PPP_PSEUDO_NM "255.255.255.255"
+#define PPP_PSEUDO_GW "10.112.112.112"
+
+#define PING_TMP "/tmp/ping.log"
+#define TRACEROUTE_TMP "/tmp/traceroute.log"
+#define MAX_BUF_LEN 254
+
+#define RESOLV_FILE "/tmp/resolv.conf"
+#define HOSTS_FILE "/tmp/hosts"
+
+#define LOG_FILE "/var/log/mess"
+
+#define ACTION_FILE "/tmp/action"
+
+
+#define split(word, wordlist, next, delim) \
+ for (next = wordlist, \
+ strncpy(word, next, sizeof(word)), \
+ word[(next=strstr(next, delim)) ? strstr(word, delim) - word : sizeof(word) - 1] = '\0', \
+ next = next ? next + sizeof(delim) - 1 : NULL ; \
+ strlen(word); \
+ next = next ? : "", \
+ strncpy(word, next, sizeof(word)), \
+ word[(next=strstr(next, delim)) ? strstr(word, delim) - word : sizeof(word) - 1] = '\0', \
+ next = next ? next + sizeof(delim) - 1 : NULL)
+
+#define STRUCT_LEN(name) sizeof(name)/sizeof(name[0])
+
+#define printHEX(str,len) { \
+ int i; \
+ for (i=0 ; i<len ; i++) { \
+ printf("%02X ", (unsigned char)*(str+i)); \
+ if(((i+1)%16) == 0) printf("- "); \
+ if(((i+1)%32) == 0) printf("\n"); \
+ } \
+ printf("\n\n"); \
+}
+
+
+#define printASC(str,len) { \
+ int i; \
+ for (i=0 ; i<len ; i++) { \
+ printf("%c", (unsigned char)*(str+i)); \
+ if(((i+1)%16) == 0) printf("- "); \
+ if(((i+1)%32) == 0) printf("\n"); \
+ } \
+ printf("\n\n"); \
+}
diff --git a/package/wlcompat/src/include/wlcompat.h b/package/wlcompat/src/include/wlcompat.h
new file mode 100644
index 0000000000..a4fc13439d
--- /dev/null
+++ b/package/wlcompat/src/include/wlcompat.h
@@ -0,0 +1,36 @@
+/*
+ * wlcompat.h
+ *
+ * Copyright (C) 2005 Felix Fietkau <nbd@vd-s.ath.cx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+#include <linux/wireless.h>
+
+#ifndef WLCOMPAT_H
+#define WLCOMPAT_H
+
+#define WLCOMPAT_SET_MONITOR SIOCIWFIRSTPRIV + 0
+#define WLCOMPAT_GET_MONITOR SIOCIWFIRSTPRIV + 1
+#define WLCOMPAT_SET_TXPWR_LIMIT SIOCIWFIRSTPRIV + 2
+#define WLCOMPAT_GET_TXPWR_LIMIT SIOCIWFIRSTPRIV + 3
+#define WLCOMPAT_SET_ANTDIV SIOCIWFIRSTPRIV + 4
+#define WLCOMPAT_GET_ANTDIV SIOCIWFIRSTPRIV + 5
+#define WLCOMPAT_SET_TXANT SIOCIWFIRSTPRIV + 6
+#define WLCOMPAT_GET_TXANT SIOCIWFIRSTPRIV + 7
+
+#endif
diff --git a/package/wlcompat/src/include/wlioctl.h b/package/wlcompat/src/include/wlioctl.h
new file mode 100644
index 0000000000..d5ef11f9ed
--- /dev/null
+++ b/package/wlcompat/src/include/wlioctl.h
@@ -0,0 +1,1094 @@
+/*
+ * Custom OID/ioctl definitions for
+ * Broadcom 802.11abg Networking Device Driver
+ *
+ * Definitions subject to change without notice.
+ *
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _wlioctl_h_
+#define _wlioctl_h_
+
+#include <typedefs.h>
+#include <proto/ethernet.h>
+#include <proto/802.11.h>
+
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#define PACKED
+#endif
+
+#define WLC_ESSID_MAX_SIZE 32
+
+#define WL_NUMRATES 255 /* max # of rates in a rateset */
+
+typedef struct wl_rateset {
+ uint32 count; /* # rates in this set */
+ uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */
+} wl_rateset_t;
+
+#define WL_CHANSPEC_CHAN_MASK 0x0fff
+#define WL_CHANSPEC_BAND_MASK 0xf000
+#define WL_CHANSPEC_BAND_SHIFT 12
+#define WL_CHANSPEC_BAND_A 0x1000
+#define WL_CHANSPEC_BAND_B 0x2000
+
+/*
+ * Per-bss information structure.
+ */
+
+#define WL_LEGACY_BSS_INFO_VERSION 106 /* an older supported version of wl_bss_info struct */
+#define WL_BSS_INFO_VERSION 107 /* current version of wl_bss_info struct */
+
+typedef struct wl_bss_info106 {
+ uint version; /* version field */
+ struct ether_addr BSSID;
+ uint8 SSID_len;
+ uint8 SSID[32];
+ uint8 Privacy; /* 0=No WEP, 1=Use WEP */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ uint16 beacon_period; /* units are Kusec */
+ uint16 atim_window; /* units are Kusec */
+ uint8 channel; /* Channel no. */
+ int8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */
+ struct {
+ uint count; /* # rates in this set */
+ uint8 rates[12]; /* rates in 500kbps units w/hi bit set if basic */
+ } rateset; /* supported rates */
+ uint8 dtim_period; /* DTIM period */
+ int8 phy_noise; /* noise right after tx (in dBm) */
+ uint16 capability; /* Capability information */
+ struct dot11_bcn_prb *prb; /* probe response frame (ioctl na) */
+ uint16 prb_len; /* probe response frame length (ioctl na) */
+ struct {
+ uint8 supported; /* wpa supported */
+ uint8 multicast; /* multicast cipher */
+ uint8 ucount; /* count of unicast ciphers */
+ uint8 unicast[4]; /* unicast ciphers */
+ uint8 acount; /* count of auth modes */
+ uint8 auth[4]; /* Authentication modes */
+ } wpa;
+} wl_bss_info106_t;
+
+typedef struct wl_bss_info {
+ uint32 version; /* version field */
+ uint32 length; /* byte length of data in this record, starting at version and including IEs */
+ struct ether_addr BSSID;
+ uint16 beacon_period; /* units are Kusec */
+ uint16 capability; /* Capability information */
+ uint8 SSID_len;
+ uint8 SSID[32];
+ struct {
+ uint count; /* # rates in this set */
+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
+ } rateset; /* supported rates */
+ uint8 channel; /* Channel no. */
+ uint16 atim_window; /* units are Kusec */
+ uint8 dtim_period; /* DTIM period */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ int8 phy_noise; /* noise (in dBm) */
+ uint32 ie_length; /* byte length of Information Elements */
+ /* variable length Information Elements */
+} wl_bss_info_t;
+
+typedef struct wlc_ssid {
+ uint32 SSID_len;
+ uchar SSID[32];
+} wlc_ssid_t;
+
+typedef struct wl_scan_params {
+ wlc_ssid_t ssid; /* default is {0, ""} */
+ struct ether_addr bssid;/* default is bcast */
+ int8 bss_type; /* default is any, DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT */
+ int8 scan_type; /* -1 use default, DOT11_SCANTYPE_ACTIVE/PASSIVE */
+ int32 nprobes; /* -1 use default, number of probes per channel */
+ int32 active_time; /* -1 use default, dwell time per channel for active scanning */
+ int32 passive_time; /* -1 use default, dwell time per channel for passive scanning */
+ int32 home_time; /* -1 use default, dwell time for the home channel between channel scans */
+ int32 channel_num; /* 0 use default (all available channels), count of channels in channel_list */
+ uint16 channel_list[1]; /* list of chanspecs */
+} wl_scan_params_t;
+/* size of wl_scan_params not including variable length array */
+#define WL_SCAN_PARAMS_FIXED_SIZE 64
+
+typedef struct wl_scan_results {
+ uint32 buflen;
+ uint32 version;
+ uint32 count;
+ wl_bss_info_t bss_info[1];
+} wl_scan_results_t;
+/* size of wl_scan_results not including variable length array */
+#define WL_SCAN_RESULTS_FIXED_SIZE 12
+
+/* uint32 list */
+typedef struct wl_uint32_list {
+ /* in - # of elements, out - # of entries */
+ uint32 count;
+ /* variable length uint32 list */
+ uint32 element[1];
+} wl_uint32_list_t;
+
+#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NULL */
+
+typedef struct wl_channels_in_country {
+ uint32 buflen;
+ uint32 band;
+ char country_abbrev[WLC_CNTRY_BUF_SZ];
+ uint32 count;
+ uint32 channel[1];
+} wl_channels_in_country_t;
+
+typedef struct wl_country_list {
+ uint32 buflen;
+ uint32 band_set;
+ uint32 band;
+ uint32 count;
+ char country_abbrev[1];
+} wl_country_list_t;
+
+#define WL_RM_TYPE_BASIC 1
+#define WL_RM_TYPE_CCA 2
+#define WL_RM_TYPE_RPI 3
+
+#define WL_RM_FLAG_PARALLEL (1<<0)
+
+#define WL_RM_FLAG_LATE (1<<1)
+#define WL_RM_FLAG_INCAPABLE (1<<2)
+#define WL_RM_FLAG_REFUSED (1<<3)
+
+typedef struct wl_rm_req_elt {
+ int8 type;
+ int8 flags;
+ uint16 chanspec;
+ uint32 token; /* token for this measurement */
+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */
+ uint32 tsf_l; /* TSF low 32-bits */
+ uint32 dur; /* TUs */
+} wl_rm_req_elt_t;
+
+typedef struct wl_rm_req {
+ uint32 token; /* overall measurement set token */
+ uint32 count; /* number of measurement reqests */
+ wl_rm_req_elt_t req[1]; /* variable length block of requests */
+} wl_rm_req_t;
+#define WL_RM_REQ_FIXED_LEN 8
+
+typedef struct wl_rm_rep_elt {
+ int8 type;
+ int8 flags;
+ uint16 chanspec;
+ uint32 token; /* token for this measurement */
+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */
+ uint32 tsf_l; /* TSF low 32-bits */
+ uint32 dur; /* TUs */
+ uint32 len; /* byte length of data block */
+ uint8 data[1]; /* variable length data block */
+} wl_rm_rep_elt_t;
+#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */
+
+#define WL_RPI_REP_BIN_NUM 8
+typedef struct wl_rm_rpi_rep {
+ uint8 rpi[WL_RPI_REP_BIN_NUM];
+ int8 rpi_max[WL_RPI_REP_BIN_NUM];
+} wl_rm_rpi_rep_t;
+
+typedef struct wl_rm_rep {
+ uint32 token; /* overall measurement set token */
+ uint32 len; /* length of measurement report block */
+ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */
+} wl_rm_rep_t;
+#define WL_RM_REP_FIXED_LEN 8
+
+
+#define WLC_MAX_KEY_SIZE 32 /* max size of any key */
+#define WLC_MAX_IV_SIZE 16 /* max size of any IV */
+#define WLC_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */
+#define WLC_MAX_DEFAULT_KEYS 4 /* # of default WEP keys */
+#define WLC_MAX_KEYS 54 /* Max # of WEP keys */
+#define WLC_WEP1_KEY_SIZE 5 /* max size of any WEP key */
+#define WLC_WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */
+#define WLC_WEP128_KEY_SIZE 13 /* max size of any WEP key */
+#define WLC_WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */
+#define WLC_TKIP_MIC_SIZE 8 /* size of TKIP MIC */
+#define WLC_TKIP_EOM_SIZE 7 /* max size of TKIP EOM */
+#define WLC_TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */
+#define WLC_TKIP_KEY_SIZE 32 /* size of any TKIP key */
+#define WLC_TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */
+#define WLC_TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */
+#define WLC_TKIP_MIC_SUP_RX 16 /* offset to Supplicant MIC RX key */
+#define WLC_TKIP_MIC_SUP_TX 24 /* offset to Supplicant MIC TX key */
+#define WLC_TKIP_P1_KEY_SIZE 10 /* size of TKHash Phase1 output, in bytes */
+#define WLC_TKIP_P2_KEY_SIZE 16 /* size of TKHash Phase2 output */
+#define WLC_AES_KEY_SIZE 16 /* size of AES key */
+
+
+typedef enum sup_auth_status {
+ WLC_SUP_DISCONNECTED = 0,
+ WLC_SUP_CONNECTING,
+ WLC_SUP_IDREQUIRED,
+ WLC_SUP_AUTHENTICATING,
+ WLC_SUP_AUTHENTICATED,
+ WLC_SUP_KEYXCHANGE,
+ WLC_SUP_KEYED
+} sup_auth_status_t;
+
+/* Enumerate crypto algorithms */
+#define CRYPTO_ALGO_OFF 0
+#define CRYPTO_ALGO_WEP1 1
+#define CRYPTO_ALGO_TKIP 2
+#define CRYPTO_ALGO_WEP128 3
+#define CRYPTO_ALGO_AES_CCM 4
+#define CRYPTO_ALGO_AES_OCB_MSDU 5
+#define CRYPTO_ALGO_AES_OCB_MPDU 6
+#define CRYPTO_ALGO_NALG 7
+
+#define WSEC_GEN_MIC_ERROR 0x0001
+#define WSEC_GEN_REPLAY 0x0002
+
+#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */
+#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */
+#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */
+#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */
+
+
+typedef struct wlc_tkip_info {
+ uint16 phase1[WLC_TKIP_P1_KEY_SIZE/sizeof(uint16)]; /* tkhash phase1 result */
+ uint8 phase2[WLC_TKIP_P2_KEY_SIZE]; /* tkhash phase2 result */
+ uint32 micl;
+ uint32 micr;
+} tkip_info_t;
+
+typedef struct _wsec_iv {
+ uint32 hi; /* upper 32 bits of IV */
+ uint16 lo; /* lower 16 bits of IV */
+} wsec_iv_t;
+
+typedef struct wsec_key {
+ uint32 index; /* key index */
+ uint32 len; /* key length */
+ uint8 data[WLC_MAX_KEY_SIZE]; /* key data */
+ tkip_info_t tkip_tx; /* tkip transmit state */
+ tkip_info_t tkip_rx; /* tkip receive state */
+ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+ uint32 flags; /* misc flags */
+ uint32 algo_hw; /* cache for hw register*/
+ uint32 aes_mode; /* cache for hw register*/
+ int iv_len; /* IV length */
+ int iv_initialized; /* has IV been initialized already? */
+ int icv_len; /* ICV length */
+ wsec_iv_t rxiv; /* Rx IV */
+ wsec_iv_t txiv; /* Tx IV */
+ struct ether_addr ea; /* per station */
+} wsec_key_t;
+
+
+
+typedef struct wl_wsec_key {
+ uint32 index; /* key index */
+ uint32 len; /* key length */
+ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */
+ uint32 pad_1[18];
+ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+ uint32 flags; /* misc flags */
+ uint32 pad_2[2];
+ int pad_3;
+ int iv_initialized; /* has IV been initialized already? */
+ int pad_4;
+ /* Rx IV */
+ struct {
+ uint32 hi; /* upper 32 bits of IV */
+ uint16 lo; /* lower 16 bits of IV */
+ } rxiv;
+ uint32 pad_5[2];
+ struct ether_addr ea; /* per station */
+} wl_wsec_key_t;
+
+/* For use with wlc_wep_key.flags */
+#define WSEC_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */
+#define WSEC_TKIP_ERROR (1 << 2) /* Provoke deliberate error */
+
+#define WSEC_MIN_PSK_LEN 8
+#define WSEC_MAX_PSK_LEN 64
+
+/* Flag for key material needing passhash'ing */
+#define WSEC_PASSPHRASE (1<<0)
+
+/* recepticle for WLC_SET_WSEC_PMK parameter */
+typedef struct {
+ ushort key_len; /* octets in key material */
+ ushort flags; /* key handling qualification */
+ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */
+} wsec_pmk_t;
+
+/* wireless security bitvec */
+#define WEP_ENABLED 1
+#define TKIP_ENABLED 2
+#define AES_ENABLED 4
+#define WSEC_SWFLAG 8
+
+#define WSEC_SW(wsec) ((wsec) & WSEC_SWFLAG)
+#define WSEC_HW(wsec) (!WSEC_SW(wsec))
+#define WSEC_WEP_ENABLED(wsec) ((wsec) & WEP_ENABLED)
+#define WSEC_TKIP_ENABLED(wsec) ((wsec) & TKIP_ENABLED)
+#define WSEC_AES_ENABLED(wsec) ((wsec) & AES_ENABLED)
+#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
+
+
+/* wireless authentication bit vector */
+#define WPA_ENABLED 1
+#define PSK_ENABLED 2
+
+#define WAUTH_WPA_ENABLED(wauth) ((wauth) & WPA_ENABLED)
+#define WAUTH_PSK_ENABLED(wauth) ((wauth) & PSK_ENABLED)
+#define WAUTH_ENABLED(wauth) ((wauth) & (WPA_ENABLED | PSK_ENABLED))
+
+/* group/mcast cipher */
+#define WPA_MCAST_CIPHER(wsec) (((wsec) & TKIP_ENABLED) ? WPA_CIPHER_TKIP : \
+ ((wsec) & AES_ENABLED) ? WPA_CIPHER_AES_CCM : \
+ WPA_CIPHER_NONE)
+
+
+typedef struct wl_led_info {
+ uint32 index; /* led index */
+ uint32 behavior;
+ bool activehi;
+} wl_led_info_t;
+
+/*
+ * definitions for driver messages passed from WL to NAS.
+ */
+/* Use this to recognize wpa and 802.1x driver messages. */
+static const uint8 wl_wpa_snap_template[] =
+ { 0xaa, 0xaa, 0x03, 0x00, 0x90, 0x4c };
+
+#define WL_WPA_MSG_IFNAME_MAX 16
+
+/* WPA driver message */
+typedef struct wl_wpa_header {
+ struct ether_header eth;
+ struct dot11_llc_snap_header snap;
+ uint8 version;
+ uint8 type;
+ /* version 2 additions */
+ char ifname[WL_WPA_MSG_IFNAME_MAX];
+ /* version specific data */
+ /* uint8 data[1]; */
+} wl_wpa_header_t PACKED;
+
+/*
+ * definitions for 802.2 messages passed from WL to NAS.
+ */
+/* This seems not to be defined outside the kernel on linux. */
+#ifndef ETH_P_802_2
+#define ETH_P_802_2 4
+#endif
+
+#define WL_WPA_HEADER_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN + 2 + WL_WPA_MSG_IFNAME_MAX)
+
+/* WPA driver message ethertype - private between wlc and nas */
+#define WL_WPA_ETHER_TYPE 0x9999
+
+/* WPA driver message current version */
+#define WL_WPA_MSG_VERSION 2
+
+/* Type field values for the 802.2 driver messages for WPA. */
+#define WLC_ASSOC_MSG 1
+#define WLC_DISASSOC_MSG 2
+#define WLC_PTK_MIC_MSG 3
+#define WLC_GTK_MIC_MSG 4
+
+/* Use this to recognize 802.2 driver messages. */
+static const uint8 wpa_snap_template[] =
+ { 0xaa, 0xaa, 0x03, 0x00, 0x90, 0x4c };
+
+
+/* 802.1x driver message */
+typedef struct wl_eapol_header {
+ struct ether_header eth;
+ struct dot11_llc_snap_header snap;
+ uint8 version;
+ uint8 reserved;
+ char ifname[WL_WPA_MSG_IFNAME_MAX];
+ /* version specific data */
+ /* uint8 802_1x_msg[1]; */
+} wl_eapol_header_t PACKED;
+
+#define WL_EAPOL_HEADER_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN + 2 + WL_WPA_MSG_IFNAME_MAX)
+
+/* 802.1x driver message ethertype - private between wlc and nas */
+#define WL_EAPOL_ETHER_TYPE 0x999A
+
+/* 802.1x driver message current version */
+#define WL_EAPOL_MSG_VERSION 1
+
+/* srom read/write struct passed through ioctl */
+typedef struct {
+ uint byteoff; /* byte offset */
+ uint nbytes; /* number of bytes */
+ uint16 buf[1];
+} srom_rw_t;
+
+/* R_REG and W_REG struct passed through ioctl */
+typedef struct {
+ uint32 byteoff; /* byte offset of the field in d11regs_t */
+ uint32 val; /* read/write value of the field */
+ uint32 size; /* sizeof the field */
+} rw_reg_t;
+
+/* Structure used by GET/SET_ATTEN ioctls */
+typedef struct {
+ uint16 auto_ctrl; /* 1: Automatic control, 0: overriden */
+ uint16 bb; /* Baseband attenuation */
+ uint16 radio; /* Radio attenuation */
+ uint16 txctl1; /* Radio TX_CTL1 value */
+} atten_t;
+
+/* Used to get specific STA parameters */
+typedef struct {
+ uint32 val;
+ struct ether_addr ea;
+} scb_val_t;
+
+/* callback registration data types */
+
+typedef struct _mac_event_params {
+ uint msg;
+ struct ether_addr *addr;
+ uint result;
+ uint status;
+ uint auth_type;
+} mac_event_params_t;
+
+typedef struct _mic_error_params {
+ struct ether_addr *ea;
+ bool group;
+ bool flush_txq;
+} mic_error_params_t;
+
+typedef enum _wl_callback {
+ WL_MAC_EVENT_CALLBACK = 0,
+ WL_LINK_UP_CALLBACK,
+ WL_LINK_DOWN_CALLBACK,
+ WL_MIC_ERROR_CALLBACK,
+ WL_LAST_CALLBACK
+} wl_callback_t;
+
+typedef struct _callback {
+ void (*fn)(void *, void *);
+ void *context;
+} callback_t;
+
+typedef struct _scan_callback {
+ void (*fn)(void *);
+ void *context;
+} scan_callback_t;
+
+/* used to register an arbitrary callback via the IOCTL interface */
+typedef struct _set_callback {
+ int index;
+ callback_t callback;
+} set_callback_t;
+
+
+
+/* Event data type */
+typedef struct {
+ uint msg; /* Message (see below) */
+ struct ether_addr *addr; /* Station address (if applicable) */
+ uint status; /* Status code (see below) */
+ uint reason; /* Reason code (if applicable) */
+ uint auth_type; /* WLC_E_AUTH */
+ bool link; /* WLC_E_LINK */
+ bool group; /* WLC_E_MIC_ERROR */
+ bool flush_txq; /* WLC_E_MIC_ERROR */
+} wlc_event_t;
+
+typedef struct {
+ uint16 ver; /* version of this struct */
+ uint16 cap; /* sta's advertized capabilities */
+ uint32 flags; /* flags defined below */
+ uint32 idle; /* time since data pkt rx'd from sta */
+ struct ether_addr ea; /* Station address */
+ wl_rateset_t rateset; /* rateset in use */
+} sta_info_t;
+
+#define WL_STA_INFO_LEN 300
+#define WL_STA_VER 1
+
+/* flags fields */
+#define WL_STA_BRCM 0x01
+#define WL_STA_WME 0x02
+#define WL_STA_ABCAP 0x04
+#define WL_STA_AUTHE 0x08
+#define WL_STA_ASSOC 0x10
+#define WL_STA_AUTHO 0x20
+
+/* Event messages */
+#define WLC_E_SET_SSID 1
+#define WLC_E_JOIN 2
+#define WLC_E_START 3
+#define WLC_E_AUTH 4
+#define WLC_E_AUTH_IND 5
+#define WLC_E_DEAUTH 6
+#define WLC_E_DEAUTH_IND 7
+#define WLC_E_ASSOC 8
+#define WLC_E_ASSOC_IND 9
+#define WLC_E_REASSOC 10
+#define WLC_E_REASSOC_IND 11
+#define WLC_E_DISASSOC 12
+#define WLC_E_DISASSOC_IND 13
+#define WLC_E_QUIET_START 14 /* 802.11h Quiet period started */
+#define WLC_E_QUIET_END 15 /* 802.11h Quiet period ended */
+#define WLC_E_GOT_BEACONS 16
+#define WLC_E_LINK 17 /* Link indication */
+#define WLC_E_MIC_ERROR 18 /* TKIP MIC error occurred */
+#define WLC_E_NDIS_LINK 19 /* NDIS style link indication */
+#define WLC_E_ROAM 20
+#define WLC_E_LAST 21
+
+/* Event status codes */
+#define WLC_E_STATUS_SUCCESS 0
+#define WLC_E_STATUS_FAIL 1
+#define WLC_E_STATUS_TIMEOUT 2
+#define WLC_E_STATUS_NO_NETWORKS 3
+#define WLC_E_STATUS_ABORT 4
+
+typedef struct wlc_event_cb {
+ uint msg; /* Event message or 0 for all */
+ void (*fn)(void *, wlc_event_t *); /* Callback function */
+ void *context; /* Passed to callback function */
+ struct wlc_event_cb *next; /* Next in the chain */
+} wlc_event_cb_t;
+
+/*
+ * Country locale determines which channels are available to us.
+ */
+typedef enum _wlc_locale {
+ WLC_WW = 0, /* Worldwide */
+ WLC_THA, /* Thailand */
+ WLC_ISR, /* Israel */
+ WLC_JDN, /* Jordan */
+ WLC_PRC, /* China */
+ WLC_JPN, /* Japan */
+ WLC_FCC, /* USA */
+ WLC_EUR, /* Europe */
+ WLC_USL, /* US Low Band only */
+ WLC_JPH, /* Japan High Band only */
+ WLC_ALL, /* All the channels in this band */
+ WLC_11D, /* Represents locale recieved by 11d beacons */
+ WLC_LAST_LOCALE,
+ WLC_UNDEFINED_LOCALE = 0xf
+} wlc_locale_t;
+
+/* channel encoding */
+typedef struct channel_info {
+ int hw_channel;
+ int target_channel;
+ int scan_channel;
+} channel_info_t;
+
+/* For ioctls that take a list of MAC addresses */
+struct maclist {
+ uint count; /* number of MAC addresses */
+ struct ether_addr ea[1]; /* variable length array of MAC addresses */
+};
+
+/* get pkt count struct passed through ioctl */
+typedef struct get_pktcnt {
+ uint rx_good_pkt;
+ uint rx_bad_pkt;
+ uint tx_good_pkt;
+ uint tx_bad_pkt;
+} get_pktcnt_t;
+
+/* Linux network driver ioctl encoding */
+typedef struct wl_ioctl {
+ uint cmd; /* common ioctl definition */
+ void *buf; /* pointer to user buffer */
+ uint len; /* length of user buffer */
+ bool set; /* get or set request (optional) */
+ uint used; /* bytes read or written (optional) */
+ uint needed; /* bytes needed (optional) */
+} wl_ioctl_t;
+
+/*
+ * Structure for passing hardware and software
+ * revision info up from the driver.
+ */
+typedef struct wlc_rev_info {
+ uint vendorid; /* PCI vendor id */
+ uint deviceid; /* device id of chip */
+ uint radiorev; /* radio revision */
+ uint chiprev; /* chip revision */
+ uint corerev; /* core revision */
+ uint boardid; /* board identifier (usu. PCI sub-device id) */
+ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */
+ uint boardrev; /* board revision */
+ uint driverrev; /* driver version */
+ uint ucoderev; /* microcode version */
+ uint bus; /* bus type */
+ uint chipnum; /* chip number */
+} wlc_rev_info_t;
+
+/* check this magic number */
+#define WLC_IOCTL_MAGIC 0x14e46c77
+
+/* bump this number if you change the ioctl interface */
+#define WLC_IOCTL_VERSION 1
+
+/* maximum length buffer required */
+#define WLC_IOCTL_MAXLEN 8192
+
+/* common ioctl definitions */
+#define WLC_GET_MAGIC 0
+#define WLC_GET_VERSION 1
+#define WLC_UP 2
+#define WLC_DOWN 3
+#define WLC_GET_LOOP 4
+#define WLC_SET_LOOP 5
+#define WLC_DUMP 6
+#define WLC_GET_MSGLEVEL 7
+#define WLC_SET_MSGLEVEL 8
+#define WLC_GET_PROMISC 9
+#define WLC_SET_PROMISC 10
+#define WLC_OBSOLETE 11
+#define WLC_GET_RATE 12
+#define WLC_SET_RATE 13
+#define WLC_GET_INSTANCE 14
+#define WLC_GET_FRAG 15
+#define WLC_SET_FRAG 16
+#define WLC_GET_RTS 17
+#define WLC_SET_RTS 18
+#define WLC_GET_INFRA 19
+#define WLC_SET_INFRA 20
+#define WLC_GET_AUTH 21
+#define WLC_SET_AUTH 22
+#define WLC_GET_BSSID 23
+#define WLC_SET_BSSID 24
+#define WLC_GET_SSID 25
+#define WLC_SET_SSID 26
+#define WLC_RESTART 27
+#define WLC_DUMP_SCB 28
+#define WLC_GET_CHANNEL 29
+#define WLC_SET_CHANNEL 30
+#define WLC_GET_SRL 31
+#define WLC_SET_SRL 32
+#define WLC_GET_LRL 33
+#define WLC_SET_LRL 34
+#define WLC_GET_PLCPHDR 35
+#define WLC_SET_PLCPHDR 36
+#define WLC_GET_RADIO 37
+#define WLC_SET_RADIO 38
+#define WLC_GET_PHYTYPE 39
+#define WLC_DUMP_RATE 40
+#define WLC_SET_RATE_PARAMS 41
+#define WLC_GET_WEP 42
+#define WLC_SET_WEP 43
+#define WLC_GET_KEY 44
+#define WLC_SET_KEY 45
+#define WLC_GET_REGULATORY 46
+#define WLC_SET_REGULATORY 47
+#define WLC_GET_PASSIVE 48 /* added by nbd */
+#define WLC_SET_PASSIVE 49 /* added by nbd */
+#define WLC_SCAN 50
+#define WLC_SCAN_RESULTS 51
+#define WLC_DISASSOC 52
+#define WLC_REASSOC 53
+#define WLC_GET_ROAM_TRIGGER 54
+#define WLC_SET_ROAM_TRIGGER 55
+#define WLC_GET_ROAM_DELTA 56
+#define WLC_SET_ROAM_DELTA 57
+#define WLC_GET_ROAM_SCAN_PERIOD 58
+#define WLC_SET_ROAM_SCAN_PERIOD 59
+#define WLC_EVM 60
+#define WLC_GET_TXANT 61
+#define WLC_SET_TXANT 62
+#define WLC_GET_ANTDIV 63
+#define WLC_SET_ANTDIV 64
+#define WLC_GET_TXPWR 65
+#define WLC_SET_TXPWR 66
+#define WLC_GET_CLOSED 67
+#define WLC_SET_CLOSED 68
+#define WLC_GET_MACLIST 69
+#define WLC_SET_MACLIST 70
+#define WLC_GET_RATESET 71
+#define WLC_SET_RATESET 72
+#define WLC_GET_LOCALE 73
+#define WLC_SET_LOCALE 74
+#define WLC_GET_BCNPRD 75
+#define WLC_SET_BCNPRD 76
+#define WLC_GET_DTIMPRD 77
+#define WLC_SET_DTIMPRD 78
+#define WLC_GET_SROM 79
+#define WLC_SET_SROM 80
+#define WLC_GET_WEP_RESTRICT 81
+#define WLC_SET_WEP_RESTRICT 82
+#define WLC_GET_COUNTRY 83
+#define WLC_SET_COUNTRY 84
+#define WLC_GET_PM 85
+#define WLC_SET_PM 86
+#define WLC_GET_WAKE 87
+#define WLC_SET_WAKE 88
+#define WLC_GET_D11CNTS 89
+#define WLC_GET_FORCELINK 90 /* ndis only */
+#define WLC_SET_FORCELINK 91 /* ndis only */
+#define WLC_FREQ_ACCURACY 92
+#define WLC_CARRIER_SUPPRESS 93
+#define WLC_GET_PHYREG 94
+#define WLC_SET_PHYREG 95
+#define WLC_GET_RADIOREG 96
+#define WLC_SET_RADIOREG 97
+#define WLC_GET_REVINFO 98
+#define WLC_GET_UCANTDIV 99
+#define WLC_SET_UCANTDIV 100
+#define WLC_R_REG 101
+#define WLC_W_REG 102
+#define WLC_DIAG_LOOPBACK 103
+#define WLC_RESET_D11CNTS 104
+#define WLC_GET_MACMODE 105
+#define WLC_SET_MACMODE 106
+#define WLC_GET_MONITOR 107 /* added by nbd */
+#define WLC_SET_MONITOR 108 /* added by nbd */
+#define WLC_GET_GMODE 109
+#define WLC_SET_GMODE 110
+#define WLC_GET_LEGACY_ERP 111
+#define WLC_SET_LEGACY_ERP 112
+#define WLC_GET_RX_ANT 113
+#define WLC_GET_CURR_RATESET 114 /* current rateset */
+#define WLC_GET_SCANSUPPRESS 115
+#define WLC_SET_SCANSUPPRESS 116
+#define WLC_GET_AP 117
+#define WLC_SET_AP 118
+#define WLC_GET_EAP_RESTRICT 119
+#define WLC_SET_EAP_RESTRICT 120
+#define WLC_SCB_AUTHORIZE 121
+#define WLC_SCB_DEAUTHORIZE 122
+#define WLC_GET_WDSLIST 123
+#define WLC_SET_WDSLIST 124
+#define WLC_GET_ATIM 125
+#define WLC_SET_ATIM 126
+#define WLC_GET_RSSI 127
+#define WLC_GET_PHYANTDIV 128
+#define WLC_SET_PHYANTDIV 129
+#define WLC_AP_RX_ONLY 130
+#define WLC_GET_TX_PATH_PWR 131
+#define WLC_SET_TX_PATH_PWR 132
+#define WLC_GET_WSEC 133
+#define WLC_SET_WSEC 134
+#define WLC_GET_PHY_NOISE 135
+#define WLC_GET_BSS_INFO 136
+#define WLC_GET_PKTCNTS 137
+#define WLC_GET_LAZYWDS 138
+#define WLC_SET_LAZYWDS 139
+#define WLC_GET_BANDLIST 140
+#define WLC_GET_BAND 141
+#define WLC_SET_BAND 142
+#define WLC_SCB_DEAUTHENTICATE 143
+#define WLC_GET_SHORTSLOT 144
+#define WLC_GET_SHORTSLOT_OVERRIDE 145
+#define WLC_SET_SHORTSLOT_OVERRIDE 146
+#define WLC_GET_SHORTSLOT_RESTRICT 147
+#define WLC_SET_SHORTSLOT_RESTRICT 148
+#define WLC_GET_GMODE_PROTECTION 149
+#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150
+#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151
+#define WLC_UPGRADE 152
+#define WLC_GET_MRATE 153
+#define WLC_SET_MRATE 154
+#define WLC_GET_IGNORE_BCNS 155
+#define WLC_SET_IGNORE_BCNS 156
+#define WLC_GET_SCB_TIMEOUT 157
+#define WLC_SET_SCB_TIMEOUT 158
+#define WLC_GET_ASSOCLIST 159
+#define WLC_GET_CLK 160
+#define WLC_SET_CLK 161
+#define WLC_GET_UP 162
+#define WLC_OUT 163
+#define WLC_GET_WPA_AUTH 164
+#define WLC_SET_WPA_AUTH 165
+#define WLC_GET_UCFLAGS 166
+#define WLC_SET_UCFLAGS 167
+#define WLC_GET_PWRIDX 168
+#define WLC_SET_PWRIDX 169
+#define WLC_GET_TSSI 170
+#define WLC_GET_SUP_RATESET_OVERRIDE 171
+#define WLC_SET_SUP_RATESET_OVERRIDE 172
+#define WLC_SET_FAST_TIMER 173
+#define WLC_GET_FAST_TIMER 174
+#define WLC_SET_SLOW_TIMER 175
+#define WLC_GET_SLOW_TIMER 176
+#define WLC_DUMP_PHYREGS 177
+#define WLC_GET_GMODE_PROTECTION_CONTROL 178
+#define WLC_SET_GMODE_PROTECTION_CONTROL 179
+#define WLC_GET_PHYLIST 180
+#define WLC_ENCRYPT_STRENGTH 181 /* ndis only */
+#define WLC_DECRYPT_STATUS 182 /* ndis only */
+#define WLC_GET_KEY_SEQ 183
+#define WLC_GET_SCAN_CHANNEL_TIME 184
+#define WLC_SET_SCAN_CHANNEL_TIME 185
+#define WLC_GET_SCAN_UNASSOC_TIME 186
+#define WLC_SET_SCAN_UNASSOC_TIME 187
+#define WLC_GET_SCAN_HOME_TIME 188
+#define WLC_SET_SCAN_HOME_TIME 189
+#define WLC_GET_SCAN_PASSES 190
+#define WLC_SET_SCAN_PASSES 191
+#define WLC_GET_PRB_RESP_TIMEOUT 192
+#define WLC_SET_PRB_RESP_TIMEOUT 193
+#define WLC_GET_ATTEN 194
+#define WLC_SET_ATTEN 195
+#define WLC_GET_SHMEM 196 /* diag */
+#define WLC_SET_SHMEM 197 /* diag */
+#define WLC_GET_GMODE_PROTECTION_CTS 198
+#define WLC_SET_GMODE_PROTECTION_CTS 199
+#define WLC_SET_TKIP_MIC_FLAG 200
+#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201
+#define WLC_TKIP_COUNTERMEASURES 202
+#define WLC_GET_PIOMODE 203
+#define WLC_SET_PIOMODE 204
+#define WLC_SET_LED 209
+#define WLC_GET_LED 210
+#define WLC_GET_INTERFERENCE_MODE 211
+#define WLC_SET_INTERFERENCE_MODE 212
+#define WLC_GET_CHANNEL_QA 213
+#define WLC_START_CHANNEL_QA 214
+#define WLC_GET_CHANNEL_SEL 215
+#define WLC_START_CHANNEL_SEL 216
+#define WLC_GET_VALID_CHANNELS 217
+#define WLC_GET_FAKEFRAG 218
+#define WLC_SET_FAKEFRAG 219
+#define WLC_GET_PWROUT_PERCENTAGE 220
+#define WLC_SET_PWROUT_PERCENTAGE 221
+#define WLC_SET_BAD_FRAME_PREEMPT 222
+#define WLC_GET_BAD_FRAME_PREEMPT 223
+#define WLC_SET_LEAP_LIST 224
+#define WLC_GET_LEAP_LIST 225
+#define WLC_GET_CWMIN 226
+#define WLC_SET_CWMIN 227
+#define WLC_GET_CWMAX 228
+#define WLC_SET_CWMAX 229
+#define WLC_GET_WET 230
+#define WLC_SET_WET 231
+#define WLC_GET_KEY_PRIMARY 235
+#define WLC_SET_KEY_PRIMARY 236
+#define WLC_SCAN_WITH_CALLBACK 240
+#define WLC_WDS_GET_REMOTE_HWADDR 246 /* currently handled in wl_linux.c/wl_vx.c */
+#define WLC_SET_CS_SCAN_TIMER 248
+#define WLC_GET_CS_SCAN_TIMER 249
+#define WLC_CURRENT_PWR 256
+#define WLC_GET_CHANNELS_IN_COUNTRY 260
+#define WLC_GET_COUNTRY_LIST 261
+#define WLC_GET_VAR 262 /* get value of named variable */
+#define WLC_SET_VAR 263 /* set named variable to value */
+#define WLC_NVRAM_GET 264
+#define WLC_NVRAM_SET 265
+#define WLC_SET_WSEC_PMK 268
+#define WLC_GET_AUTH_MODE 269
+#define WLC_SET_AUTH_MODE 270
+#define WLC_LAST 273 /* do not change - use get_var/set_var */
+
+/*
+ * Minor kludge alert:
+ * Duplicate a few definitions that irelay requires from epiioctl.h here
+ * so caller doesn't have to include this file and epiioctl.h .
+ * If this grows any more, it would be time to move these irelay-specific
+ * definitions out of the epiioctl.h and into a separate driver common file.
+ */
+#ifndef EPICTRL_COOKIE
+#define EPICTRL_COOKIE 0xABADCEDE
+#endif
+
+/* vx wlc ioctl's offset */
+#define CMN_IOCTL_OFF 0x180
+
+/*
+ * custom OID support
+ *
+ * 0xFF - implementation specific OID
+ * 0xE4 - first byte of Broadcom PCI vendor ID
+ * 0x14 - second byte of Broadcom PCI vendor ID
+ * 0xXX - the custom OID number
+ */
+
+/* begin 0x1f values beyond the start of the ET driver range. */
+#define WL_OID_BASE 0xFFE41420
+
+/* NDIS overrides */
+#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE)
+#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK)
+#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK)
+#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH)
+#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS)
+
+#define WL_DECRYPT_STATUS_SUCCESS 1
+#define WL_DECRYPT_STATUS_FAILURE 2
+#define WL_DECRYPT_STATUS_UNKNOWN 3
+
+/* allows user-mode app to poll the status of USB image upgrade */
+#define WLC_UPGRADE_SUCCESS 0
+#define WLC_UPGRADE_PENDING 1
+
+/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
+#define WL_RADIO_SW_DISABLE (1<<0)
+#define WL_RADIO_HW_DISABLE (1<<1)
+
+/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */
+#define WL_TXPWR_OVERRIDE (1<<31)
+
+
+/* Bus types */
+#define WL_SB_BUS 0 /* Silicon Backplane */
+#define WL_PCI_BUS 1 /* PCI target */
+#define WL_PCMCIA_BUS 2 /* PCMCIA target */
+
+/* band types */
+#define WLC_BAND_AUTO 0 /* auto-select */
+#define WLC_BAND_A 1 /* "a" band (5 Ghz) */
+#define WLC_BAND_B 2 /* "b" band (2.4 Ghz) */
+
+/* MAC list modes */
+#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */
+#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */
+#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */
+
+
+/* 54g modes (basic bits may still be overridden) */
+#define GMODE_LEGACY_B 0 /* Rateset: 1b, 2b, 5.5, 11 */
+ /* Preamble: Long */
+ /* Shortslot: Off */
+#define GMODE_AUTO 1 /* Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 */
+ /* Extended Rateset: 6, 9, 12, 48 */
+ /* Preamble: Long */
+ /* Shortslot: Auto */
+#define GMODE_ONLY 2 /* Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 */
+ /* Extended Rateset: 6b, 9, 12b, 48 */
+ /* Preamble: Short required */
+ /* Shortslot: Auto */
+#define GMODE_B_DEFERRED 3 /* Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 */
+ /* Extended Rateset: 6, 9, 12, 48 */
+ /* Preamble: Long */
+ /* Shortslot: On */
+#define GMODE_PERFORMANCE 4 /* Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 */
+ /* Preamble: Short required */
+ /* Shortslot: On and required */
+#define GMODE_LRS 5 /* Rateset: 1b, 2b, 5.5b, 11b */
+ /* Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 */
+ /* Preamble: Long */
+ /* Shortslot: Auto */
+#define GMODE_MAX 6
+
+
+/* values for PLCPHdr_override */
+#define WLC_PLCP_AUTO -1
+#define WLC_PLCP_SHORT 0
+#define WLC_PLCP_LONG 1
+
+/* values for g_protection_override */
+#define WLC_G_PROTECTION_AUTO -1
+#define WLC_G_PROTECTION_OFF 0
+#define WLC_G_PROTECTION_ON 1
+
+/* values for g_protection_control */
+#define WLC_G_PROTECTION_CTL_OFF 0
+#define WLC_G_PROTECTION_CTL_LOCAL 1
+#define WLC_G_PROTECTION_CTL_OVERLAP 2
+
+/* Values for PM */
+#define PM_OFF 0
+#define PM_MAX 1
+#define PM_FAST 2
+
+/* interference mitigation options */
+#define INTERFERE_NONE 0 /* off */
+#define NON_WLAN 1 /* foreign/non 802.11 interference, no auto detect */
+#define WLAN_MANUAL 2 /* ACI: no auto detection */
+#define WLAN_AUTO 3 /* ACI: auto - detact */
+
+/* Message levels */
+#define WL_ERROR_VAL 0x0001
+#define WL_TRACE_VAL 0x0002
+#define WL_PRHDRS_VAL 0x0004
+#define WL_PRPKT_VAL 0x0008
+#define WL_INFORM_VAL 0x0010
+#define WL_TMP_VAL 0x0020
+#define WL_OID_VAL 0x0040
+#define WL_RATE_VAL 0x0080
+#define WL_ASSOC_VAL 0x0100
+#define WL_PRUSR_VAL 0x0200
+#define WL_PS_VAL 0x0400
+#define WL_TXPWR_VAL 0x0800
+#define WL_GMODE_VAL 0x1000
+#define WL_DUAL_VAL 0x2000
+#define WL_WSEC_VAL 0x4000
+#define WL_WSEC_DUMP_VAL 0x8000
+#define WL_LOG_VAL 0x10000
+#define WL_NRSSI_VAL 0x20000
+#define WL_LOFT_VAL 0x40000
+#define WL_REGULATORY_VAL 0x80000
+#define WL_ACI_VAL 0x100000
+
+
+/* 802.11h enforcement levels */
+#define SPECT_MNGMT_OFF 0 /* 11h disabled */
+#define SPECT_MNGMT_LOOSE 1 /* Allow scan lists to contain non-11h AP */
+ /* when 11h is enabled */
+#define SPECT_MNGMT_STRICT 2 /* Prine out non-11h APs from scan list */
+
+
+
+/* max # of leds supported by GPIO (gpio pin# == led index#) */
+#define WL_LED_NUMGPIO 16 /* gpio 0-15 */
+
+/* led per-pin behaviors */
+#define WL_LED_OFF 0 /* always off */
+#define WL_LED_ON 1 /* always on */
+#define WL_LED_ACTIVITY 2 /* activity */
+#define WL_LED_RADIO 3 /* radio enabled */
+#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */
+#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */
+#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */
+#define WL_LED_WI1 7
+#define WL_LED_WI2 8
+#define WL_LED_WI3 9
+#define WL_LED_ASSOC 10 /* associated state indicator */
+#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */
+#define WL_LED_NUMBEHAVIOR 12
+
+/* led behavior numeric value format */
+#define WL_LED_BEH_MASK 0x7f /* behavior mask */
+#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */
+
+
+/* maximum channels */
+#define WL_NUMCHANNELS 64 /* max # of channels in the band */
+
+/* rate check */
+#define WL_RATE_OFDM(r) (((r) & 0x7f) == 12 || ((r) & 0x7f) == 18 || \
+ ((r) & 0x7f) == 24 || ((r) & 0x7f) == 36 || \
+ ((r) & 0x7f) == 48 || ((r) & 0x7f) == 72 || \
+ ((r) & 0x7f) == 96 || ((r) & 0x7f) == 108)
+
+/* WDS link local endpoint WPA role */
+#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */
+#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */
+#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */
+
+/* afterburner_override */
+#define ABO_AUTO -1 /* auto - no override */
+#define ABO_OFF 0 /* force afterburner off */
+#define ABO_ON 1 /* force afterburner on */
+
+#define GMODE_AFTERBURNER 6
+
+#undef PACKED
+
+#endif /* _wlioctl_h_ */
diff --git a/package/wlcompat/src/include/wlutils.h b/package/wlcompat/src/include/wlutils.h
new file mode 100644
index 0000000000..07e2536ca3
--- /dev/null
+++ b/package/wlcompat/src/include/wlutils.h
@@ -0,0 +1,59 @@
+/*
+ * Broadcom wireless network adapter utility functions
+ *
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _wlutils_h_
+#define _wlutils_h_
+
+#include <typedefs.h>
+#include <wlioctl.h>
+
+/*
+ * Pass a wlioctl request to the specified interface.
+ * @param name interface name
+ * @param cmd WLC_GET_MAGIC <= cmd < WLC_LAST
+ * @param buf buffer for passing in and/or receiving data
+ * @param len length of buf
+ * @return >= 0 if successful or < 0 otherwise
+ */
+extern int wl_ioctl(char *name, int cmd, void *buf, int len);
+
+/*
+ * Get the MAC (hardware) address of the specified interface.
+ * @param name interface name
+ * @param hwaddr 6-byte buffer for receiving address
+ * @return >= 0 if successful or < 0 otherwise
+ */
+extern int wl_hwaddr(char *name, unsigned char *hwaddr);
+
+/*
+ * Probe the specified interface.
+ * @param name interface name
+ * @return >= 0 if a Broadcom wireless device or < 0 otherwise
+ */
+extern int wl_probe(char *name);
+
+/*
+ * Set/Get named variable.
+ * @param name interface name
+ * @param var variable name
+ * @param val variable value/buffer
+ * @param len variable value/buffer length
+ * @return success == 0, failure != 0
+ */
+extern int wl_set_val(char *name, char *var, void *val, int len);
+extern int wl_get_val(char *name, char *var, void *val, int len);
+extern int wl_set_int(char *name, char *var, int val);
+extern int wl_get_int(char *name, char *var, int *val);
+
+#endif /* _wlutils_h_ */
diff --git a/package/wlcompat/src/wlcompat.c b/package/wlcompat/src/wlcompat.c
new file mode 100644
index 0000000000..23b0d50a81
--- /dev/null
+++ b/package/wlcompat/src/wlcompat.c
@@ -0,0 +1,1056 @@
+/*
+ * wlcompat.c
+ *
+ * Copyright (C) 2005 Mike Baker,
+ * Felix Fietkau <openwrt@nbd.name>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+#include <linux/wireless.h>
+#include <linux/timer.h>
+
+#include <net/iw_handler.h>
+#include <wlioctl.h>
+
+static struct net_device *dev;
+static unsigned short bss_force;
+static struct iw_statistics wstats;
+static int random = 1;
+char buf[WLC_IOCTL_MAXLEN];
+
+/* The frequency of each channel in MHz */
+const long channel_frequency[] = {
+ 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+ 2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+#define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )
+
+#define RNG_POLL_FREQ 20
+
+typedef struct internal_wsec_key {
+ uint8 index; // 0x00
+ uint8 unknown_1; // 0x01
+ uint8 type; // 0x02
+ uint8 unknown_2[7]; // 0x03
+ uint8 len; // 0x0a
+ uint8 pad[3];
+ char data[32]; // 0x0e
+} wkey;
+
+
+static int wlcompat_private_ioctl(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra);
+#ifdef DEBUG
+void print_buffer(int len, unsigned char *buf);
+#endif
+
+static int wl_ioctl(struct net_device *dev, int cmd, void *buf, int len)
+{
+ mm_segment_t old_fs = get_fs();
+ struct ifreq ifr;
+ int ret;
+ wl_ioctl_t ioc;
+ ioc.cmd = cmd;
+ ioc.buf = buf;
+ ioc.len = len;
+ strncpy(ifr.ifr_name, dev->name, IFNAMSIZ);
+ ifr.ifr_data = (caddr_t) &ioc;
+ set_fs(KERNEL_DS);
+ ret = dev->do_ioctl(dev,&ifr,SIOCDEVPRIVATE);
+ set_fs (old_fs);
+ return ret;
+}
+
+static int wl_set_val(struct net_device *dev, char *var, void *val, int len)
+{
+ char buf[128];
+ int buf_len;
+ int ret;
+
+ /* check for overflow */
+ if ((buf_len = strlen(var)) + 1 + len > sizeof(buf))
+ return -1;
+
+ strcpy(buf, var);
+ buf_len += 1;
+
+ /* append int value onto the end of the name string */
+ memcpy(&(buf[buf_len]), val, len);
+ buf_len += len;
+
+ ret = wl_ioctl(dev, WLC_SET_VAR, buf, buf_len);
+ return ret;
+}
+
+static int wl_get_val(struct net_device *dev, char *var, void *val, int len)
+{
+ char buf[128];
+ int buf_len;
+ int ret;
+
+ /* check for overflow */
+ if ((buf_len = strlen(var)) + 1 > sizeof(buf) || len > sizeof(buf))
+ return -1;
+
+ strcpy(buf, var);
+ if (ret = wl_ioctl(dev, WLC_GET_VAR, buf, buf_len + len))
+ return ret;
+
+ memcpy(val, buf, len);
+ return 0;
+}
+
+int get_primary_key(struct net_device *dev)
+{
+ int key, val;
+
+ for (key = val = 0; (key < 4) && (val == 0); key++) {
+ val = key;
+ if (wl_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)) < 0)
+ return -EINVAL;
+ }
+ return key;
+}
+
+
+static int wlcompat_ioctl_getiwrange(struct net_device *dev,
+ char *extra)
+{
+ int i, k;
+ struct iw_range *range;
+
+ range = (struct iw_range *) extra;
+ bzero(extra, sizeof(struct iw_range));
+
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = WIRELESS_EXT;
+
+ range->min_nwid = range->max_nwid = 0;
+
+ range->num_channels = NUM_CHANNELS;
+ k = 0;
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ range->freq[k].i = i + 1;
+ range->freq[k].m = channel_frequency[i] * 100000;
+ range->freq[k].e = 1;
+ k++;
+ if (k >= IW_MAX_FREQUENCIES)
+ break;
+ }
+ range->num_frequency = k;
+ range->sensitivity = 3;
+
+ /* nbd: don't know what this means, but other drivers set it this way */
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_TIMEOUT;
+ range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
+
+ range->min_pmp = 0;
+ range->max_pmp = 65535000;
+ range->min_pmt = 0;
+ range->max_pmt = 65535 * 1000;
+
+ range->max_qual.qual = 0;
+ range->max_qual.level = 0;
+ range->max_qual.noise = 0;
+
+ range->min_rts = 0;
+ if (wl_ioctl(dev, WLC_GET_RTS, &range->max_rts, sizeof(int)) < 0)
+ range->max_rts = 2347;
+
+ range->min_frag = 256;
+
+ if (wl_ioctl(dev, WLC_GET_FRAG, &range->max_frag, sizeof(int)) < 0)
+ range->max_frag = 2346;
+
+ range->txpower_capa = IW_TXPOW_DBM;
+
+ return 0;
+}
+
+
+static int wlcompat_set_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int ap = 0, oldap = 0;
+ wl_scan_params_t params;
+
+ memset(&params, 0, sizeof(params));
+
+ /* use defaults (same parameters as wl scan) */
+ memset(&params.bssid, 0xff, sizeof(params.bssid));
+ params.bss_type = DOT11_BSSTYPE_ANY;
+ params.scan_type = -1;
+ params.nprobes = -1;
+ params.active_time = -1;
+ params.passive_time = -1;
+ params.home_time = -1;
+
+ /* can only scan in STA mode */
+ wl_ioctl(dev, WLC_GET_AP, &oldap, sizeof(oldap));
+ if (oldap > 0)
+ wl_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap));
+
+ if (wl_ioctl(dev, WLC_SCAN, &params, 64) < 0)
+ return -EINVAL;
+
+ if (oldap > 0)
+ wl_ioctl(dev, WLC_SET_AP, &oldap, sizeof(oldap));
+
+ return 0;
+}
+
+
+struct iw_statistics *wlcompat_get_wireless_stats(struct net_device *dev)
+{
+ wl_bss_info_t *bss_info = (wl_bss_info_t *) buf;
+ get_pktcnt_t pkt;
+ unsigned int rssi, noise, ap;
+
+ memset(&wstats, 0, sizeof(wstats));
+ memset(&pkt, 0, sizeof(pkt));
+ memset(buf, 0, sizeof(buf));
+ bss_info->version = 0x2000;
+ wl_ioctl(dev, WLC_GET_BSS_INFO, bss_info, WLC_IOCTL_MAXLEN);
+ wl_ioctl(dev, WLC_GET_PKTCNTS, &pkt, sizeof(pkt));
+
+ rssi = 0;
+ if ((wl_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)) < 0) || ap) {
+ if (wl_ioctl(dev, WLC_GET_PHY_NOISE, &noise, sizeof(noise)) < 0)
+ noise = 0;
+ } else {
+ // somehow the structure doesn't fit here
+ rssi = buf[82];
+ noise = buf[84];
+ }
+ rssi = (rssi == 0 ? 1 : rssi);
+ wstats.qual.updated = 0x10;
+ if (rssi <= 1)
+ wstats.qual.updated |= 0x20;
+ if (noise <= 1)
+ wstats.qual.updated |= 0x40;
+
+ if ((wstats.qual.updated & 0x60) == 0x60)
+ return NULL;
+
+ wstats.qual.level = rssi;
+ wstats.qual.noise = noise;
+ wstats.discard.misc = pkt.rx_bad_pkt;
+ wstats.discard.retries = pkt.tx_bad_pkt;
+
+ return &wstats;
+}
+
+static int wlcompat_get_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ wl_scan_results_t *results = (wl_scan_results_t *) buf;
+ wl_bss_info_t *bss_info;
+ char *info_ptr;
+ char *current_ev = extra;
+ char *current_val;
+ char *end_buf = extra + IW_SCAN_MAX_DATA;
+ struct iw_event iwe;
+ int i, j;
+ int rssi, noise;
+
+ results->buflen = WLC_IOCTL_MAXLEN - sizeof(wl_scan_results_t);
+
+ if (wl_ioctl(dev, WLC_SCAN_RESULTS, buf, WLC_IOCTL_MAXLEN) < 0)
+ return -EAGAIN;
+
+ bss_info = &(results->bss_info[0]);
+ info_ptr = (char *) bss_info;
+ for (i = 0; i < results->count; i++) {
+
+ /* send the cell address (must be sent first) */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(&iwe.u.ap_addr.sa_data, &bss_info->BSSID, sizeof(bss_info->BSSID));
+ current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+
+ /* send the ESSID */
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.length = bss_info->SSID_len;
+ if (iwe.u.data.length > IW_ESSID_MAX_SIZE)
+ iwe.u.data.length = IW_ESSID_MAX_SIZE;
+ iwe.u.data.flags = 1;
+ current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss_info->SSID);
+
+ /* send frequency/channel info */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.e = 0;
+ iwe.u.freq.m = bss_info->channel;
+ current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+
+ /* add quality statistics */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.qual = 0;
+ iwe.u.qual.level = bss_info->RSSI;
+ iwe.u.qual.noise = bss_info->phy_noise;
+ current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+
+ /* send rate information */
+ iwe.cmd = SIOCGIWRATE;
+ current_val = current_ev + IW_EV_LCP_LEN;
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+ for(j = 0 ; j < bss_info->rateset.count ; j++) {
+ iwe.u.bitrate.value = ((bss_info->rateset.rates[j] & 0x7f) * 500000);
+ current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ }
+ if((current_val - current_ev) > IW_EV_LCP_LEN)
+ current_ev = current_val;
+
+ info_ptr += sizeof(wl_bss_info_t);
+ if (bss_info->ie_length % 4)
+ info_ptr += bss_info->ie_length + 4 - (bss_info->ie_length % 4);
+ else
+ info_ptr += bss_info->ie_length;
+ bss_info = (wl_bss_info_t *) info_ptr;
+ }
+
+ wrqu->data.length = (current_ev - extra);
+ wrqu->data.flags = 0;
+
+ return 0;
+}
+
+static int wlcompat_ioctl(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ switch (info->cmd) {
+ case SIOCGIWNAME:
+ strcpy(wrqu->name, "IEEE 802.11-DS");
+ break;
+ case SIOCGIWFREQ:
+ {
+ channel_info_t ci;
+
+ if (wl_ioctl(dev,WLC_GET_CHANNEL, &ci, sizeof(ci)) < 0)
+ return -EINVAL;
+
+ wrqu->freq.m = ci.target_channel;
+ wrqu->freq.e = 0;
+ break;
+ }
+ case SIOCSIWFREQ:
+ {
+ if (wrqu->freq.m == -1) {
+ wrqu->freq.m = 0;
+ if (wl_ioctl(dev, WLC_SET_CHANNEL, &wrqu->freq.m, sizeof(int)) < 0)
+ return -EINVAL;
+ } else {
+ if (wrqu->freq.e == 1) {
+ int channel = 0;
+ int f = wrqu->freq.m / 100000;
+ while ((channel < NUM_CHANNELS + 1) && (f != channel_frequency[channel]))
+ channel++;
+
+ if (channel == NUM_CHANNELS) // channel not found
+ return -EINVAL;
+
+ wrqu->freq.e = 0;
+ wrqu->freq.m = channel + 1;
+ }
+ if ((wrqu->freq.e == 0) && (wrqu->freq.m < 1000)) {
+ if (wl_ioctl(dev, WLC_SET_CHANNEL, &wrqu->freq.m, sizeof(int)) < 0)
+ return -EINVAL;
+ } else {
+ return -EINVAL;
+ }
+ }
+ break;
+ }
+ case SIOCSIWAP:
+ {
+ int ap = 0;
+ int infra = 0;
+ rw_reg_t reg;
+
+ memset(&reg, 0, sizeof(reg));
+
+ if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ if (wl_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)) < 0)
+ return -EINVAL;
+
+ if (wl_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra)) < 0)
+ return -EINVAL;
+
+ if (!infra) {
+ wl_ioctl(dev, WLC_SET_BSSID, wrqu->ap_addr.sa_data, 6);
+
+ reg.size = 4;
+ reg.byteoff = 0x184;
+ reg.val = bss_force << 16 | bss_force;
+ wl_ioctl(dev, WLC_W_REG, &reg, sizeof(reg));
+
+ reg.byteoff = 0x180;
+ wl_ioctl(dev, WLC_R_REG, &reg, sizeof(reg));
+ reg.val = bss_force << 16;
+ wl_ioctl(dev, WLC_W_REG, &reg, sizeof(reg));
+ }
+
+ if (wl_ioctl(dev, ((ap || !infra) ? WLC_SET_BSSID : WLC_REASSOC), wrqu->ap_addr.sa_data, 6) < 0)
+ return -EINVAL;
+
+ break;
+ }
+ case SIOCGIWAP:
+ {
+#ifdef DEBUG
+ rw_reg_t reg;
+ memset(&reg, 0, sizeof(reg));
+
+ reg.size = 4;
+ reg.byteoff = 0x184;
+ wl_ioctl(dev, WLC_R_REG, &reg, sizeof(reg));
+ printk("bss time = 0x%08x", reg.val);
+
+ reg.byteoff = 0x180;
+ wl_ioctl(dev, WLC_R_REG, &reg, sizeof(reg));
+ printk("%08x\n", reg.val);
+#endif
+
+ wrqu->ap_addr.sa_family = ARPHRD_ETHER;
+ if (wl_ioctl(dev,WLC_GET_BSSID,wrqu->ap_addr.sa_data,6) < 0)
+ return -EINVAL;
+ break;
+ }
+ case SIOCGIWESSID:
+ {
+ wlc_ssid_t ssid;
+
+ if (wl_ioctl(dev,WLC_GET_SSID, &ssid, sizeof(wlc_ssid_t)) < 0)
+ return -EINVAL;
+
+ wrqu->essid.flags = wrqu->data.flags = 1;
+ wrqu->essid.length = wrqu->data.length = ssid.SSID_len + 1;
+ memcpy(extra,ssid.SSID,ssid.SSID_len + 1);
+ break;
+ }
+ case SIOCSIWESSID:
+ {
+ wlc_ssid_t ssid;
+ memset(&ssid, 0, sizeof(ssid));
+ ssid.SSID_len = strlen(extra);
+ if (ssid.SSID_len > WLC_ESSID_MAX_SIZE)
+ ssid.SSID_len = WLC_ESSID_MAX_SIZE;
+ memcpy(ssid.SSID, extra, ssid.SSID_len);
+ if (wl_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid)) < 0)
+ return -EINVAL;
+ break;
+ }
+ case SIOCGIWRTS:
+ {
+ if (wl_ioctl(dev,WLC_GET_RTS,&(wrqu->rts.value),sizeof(int)) < 0)
+ return -EINVAL;
+ break;
+ }
+ case SIOCSIWRTS:
+ {
+ if (wl_ioctl(dev,WLC_SET_RTS,&(wrqu->rts.value),sizeof(int)) < 0)
+ return -EINVAL;
+ break;
+ }
+ case SIOCGIWFRAG:
+ {
+ if (wl_ioctl(dev,WLC_GET_FRAG,&(wrqu->frag.value),sizeof(int)) < 0)
+ return -EINVAL;
+ break;
+ }
+ case SIOCSIWFRAG:
+ {
+ if (wl_ioctl(dev,WLC_SET_FRAG,&(wrqu->frag.value),sizeof(int)) < 0)
+ return -EINVAL;
+ break;
+ }
+ case SIOCGIWTXPOW:
+ {
+ int radio, override;
+
+ wl_ioctl(dev, WLC_GET_RADIO, &radio, sizeof(int));
+
+ if (wl_get_val(dev, "qtxpower", &(wrqu->txpower.value), sizeof(int)) < 0)
+ return -EINVAL;
+
+ override = (wrqu->txpower.value & WL_TXPWR_OVERRIDE) == WL_TXPWR_OVERRIDE;
+ wrqu->txpower.value &= ~WL_TXPWR_OVERRIDE;
+ if (!override && (wrqu->txpower.value > 76))
+ wrqu->txpower.value = 76;
+ wrqu->txpower.value /= 4;
+
+ wrqu->txpower.fixed = 0;
+ wrqu->txpower.disabled = radio;
+ wrqu->txpower.flags = IW_TXPOW_DBM;
+ break;
+ }
+ case SIOCSIWTXPOW:
+ {
+ /* This is weird: WLC_SET_RADIO with 1 as argument disables the radio */
+ int radio = wrqu->txpower.disabled;
+
+ wl_ioctl(dev, WLC_SET_RADIO, &radio, sizeof(int));
+
+ if (!wrqu->txpower.disabled && (wrqu->txpower.value > 0)) {
+ int value;
+
+ if (wl_get_val(dev, "qtxpower", &value, sizeof(int)) < 0)
+ return -EINVAL;
+
+ value &= WL_TXPWR_OVERRIDE;
+ wrqu->txpower.value *= 4;
+ wrqu->txpower.value |= value;
+
+ if (wrqu->txpower.flags != IW_TXPOW_DBM)
+ return -EINVAL;
+
+ if (wrqu->txpower.value > 0)
+ if (wl_set_val(dev, "qtxpower", &(wrqu->txpower.value), sizeof(int)) < 0)
+ return -EINVAL;
+ }
+ break;
+ }
+ case SIOCSIWENCODE:
+ {
+ int val = 0, wep = 1, wrestrict = 1;
+ int index = (wrqu->data.flags & IW_ENCODE_INDEX) - 1;
+
+ if (index < 0)
+ index = get_primary_key(dev);
+
+ if (wrqu->data.flags & IW_ENCODE_DISABLED) {
+ wep = 0;
+ if (wl_ioctl(dev, WLC_SET_WSEC, &wep, sizeof(val)) < 0)
+ return -EINVAL;
+ return 0;
+ }
+
+ if (wl_ioctl(dev, WLC_SET_WSEC, &wep, sizeof(val)) < 0)
+ return -EINVAL;
+
+ if (wrqu->data.flags & IW_ENCODE_OPEN)
+ wrestrict = 0;
+
+ if (wrqu->data.pointer && (wrqu->data.length > 0) && (wrqu->data.length <= 16)) {
+ wl_wsec_key_t key;
+ memset(&key, 0, sizeof(key));
+
+ key.flags = WL_PRIMARY_KEY;
+ key.len = wrqu->data.length;
+ key.index = index;
+ memcpy(key.data, wrqu->data.pointer, wrqu->data.length);
+
+ if (wl_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)) < 0)
+ return -EINVAL;
+ }
+
+ if (index >= 0)
+ wl_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, sizeof(index));
+
+ if (wrestrict >= 0)
+ wl_ioctl(dev, WLC_SET_WEP_RESTRICT, &wrestrict, sizeof(wrestrict));
+
+ break;
+ }
+ case SIOCGIWENCODE:
+ {
+ int val;
+
+ if (wl_ioctl(dev, WLC_GET_WEP, &val, sizeof(val)) < 0)
+ return -EINVAL;
+
+
+ if (val > 0) {
+ int key = get_primary_key(dev);
+
+ wrqu->data.flags = IW_ENCODE_ENABLED;
+ if (key-- > 0) {
+ int *info_addr;
+ wkey *wep_key;
+
+ info_addr = (int *) dev->priv;
+ wep_key = (wkey *) ((*info_addr) + 0x2752 + (key * 0x110));
+
+ wrqu->data.flags |= key + 1;
+ wrqu->data.length = wep_key->len;
+
+ memset(extra, 0, 16);
+ memcpy(extra, wep_key->data, 16);
+ } else {
+ wrqu->data.flags |= IW_ENCODE_NOKEY;
+ }
+ } else {
+ wrqu->data.flags = IW_ENCODE_DISABLED;
+ }
+
+ break;
+ }
+ case SIOCGIWRANGE:
+ {
+ return wlcompat_ioctl_getiwrange(dev, extra);
+ break;
+ }
+ case SIOCSIWMODE:
+ {
+ int ap = -1, infra = -1, passive = 0, wet = 0;
+
+ switch (wrqu->mode) {
+ case IW_MODE_MONITOR:
+ passive = 1;
+ break;
+ case IW_MODE_ADHOC:
+ infra = 0;
+ ap = 0;
+ break;
+ case IW_MODE_MASTER:
+ infra = 1;
+ ap = 1;
+ break;
+ case IW_MODE_INFRA:
+ infra = 1;
+ ap = 0;
+ break;
+ case IW_MODE_REPEAT:
+ infra = 1;
+ ap = 0;
+ wet = 1;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ wl_ioctl(dev, WLC_SET_PASSIVE, &passive, sizeof(passive));
+ wl_ioctl(dev, WLC_SET_MONITOR, &passive, sizeof(passive));
+ wl_ioctl(dev, WLC_SET_WET, &wet, sizeof(wet));
+ if (ap >= 0)
+ wl_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap));
+ if (infra >= 0)
+ wl_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra));
+
+ break;
+
+ }
+ case SIOCGIWMODE:
+ {
+ int ap, infra, wet, passive;
+
+ if (wl_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)) < 0)
+ return -EINVAL;
+ if (wl_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra)) < 0)
+ return -EINVAL;
+ if (wl_ioctl(dev, WLC_GET_PASSIVE, &passive, sizeof(passive)) < 0)
+ return -EINVAL;
+ if (wl_ioctl(dev, WLC_GET_WET, &wet, sizeof(wet)) < 0)
+ return -EINVAL;
+
+ if (passive) {
+ wrqu->mode = IW_MODE_MONITOR;
+ } else if (!infra) {
+ wrqu->mode = IW_MODE_ADHOC;
+ } else {
+ if (ap) {
+ wrqu->mode = IW_MODE_MASTER;
+ } else {
+ if (wet) {
+ wrqu->mode = IW_MODE_REPEAT;
+ } else {
+ wrqu->mode = IW_MODE_INFRA;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ if (info->cmd >= SIOCIWFIRSTPRIV)
+ return wlcompat_private_ioctl(dev, info, wrqu, extra);
+
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static const iw_handler wlcompat_handler[] = {
+ NULL, /* SIOCSIWCOMMIT */
+ wlcompat_ioctl, /* SIOCGIWNAME */
+ NULL, /* SIOCSIWNWID */
+ NULL, /* SIOCGIWNWID */
+ wlcompat_ioctl, /* SIOCSIWFREQ */
+ wlcompat_ioctl, /* SIOCGIWFREQ */
+ wlcompat_ioctl, /* SIOCSIWMODE */
+ wlcompat_ioctl, /* SIOCGIWMODE */
+ NULL, /* SIOCSIWSENS */
+ NULL, /* SIOCGIWSENS */
+ NULL, /* SIOCSIWRANGE, unused */
+ wlcompat_ioctl, /* SIOCGIWRANGE */
+ NULL, /* SIOCSIWPRIV */
+ NULL, /* SIOCGIWPRIV */
+ NULL, /* SIOCSIWSTATS */
+ NULL, /* SIOCGIWSTATS */
+ iw_handler_set_spy, /* SIOCSIWSPY */
+ iw_handler_get_spy, /* SIOCGIWSPY */
+ iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
+ iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
+ wlcompat_ioctl, /* SIOCSIWAP */
+ wlcompat_ioctl, /* SIOCGIWAP */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCGIWAPLIST */
+ wlcompat_set_scan, /* SIOCSIWSCAN */
+ wlcompat_get_scan, /* SIOCGIWSCAN */
+ wlcompat_ioctl, /* SIOCSIWESSID */
+ wlcompat_ioctl, /* SIOCGIWESSID */
+ NULL, /* SIOCSIWNICKN */
+ NULL, /* SIOCGIWNICKN */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWRATE */
+ NULL, /* SIOCGIWRATE */
+ wlcompat_ioctl, /* SIOCSIWRTS */
+ wlcompat_ioctl, /* SIOCGIWRTS */
+ wlcompat_ioctl, /* SIOCSIWFRAG */
+ wlcompat_ioctl, /* SIOCGIWFRAG */
+ wlcompat_ioctl, /* SIOCSIWTXPOW */
+ wlcompat_ioctl, /* SIOCGIWTXPOW */
+ NULL, /* SIOCSIWRETRY */
+ NULL, /* SIOCGIWRETRY */
+ wlcompat_ioctl, /* SIOCSIWENCODE */
+ wlcompat_ioctl, /* SIOCGIWENCODE */
+};
+
+
+#define WLCOMPAT_SET_MONITOR SIOCIWFIRSTPRIV + 0
+#define WLCOMPAT_GET_MONITOR SIOCIWFIRSTPRIV + 1
+#define WLCOMPAT_SET_TXPWR_LIMIT SIOCIWFIRSTPRIV + 2
+#define WLCOMPAT_GET_TXPWR_LIMIT SIOCIWFIRSTPRIV + 3
+#define WLCOMPAT_SET_ANTDIV SIOCIWFIRSTPRIV + 4
+#define WLCOMPAT_GET_ANTDIV SIOCIWFIRSTPRIV + 5
+#define WLCOMPAT_SET_TXANT SIOCIWFIRSTPRIV + 6
+#define WLCOMPAT_GET_TXANT SIOCIWFIRSTPRIV + 7
+#define WLCOMPAT_SET_BSS_FORCE SIOCIWFIRSTPRIV + 8
+#define WLCOMPAT_GET_BSS_FORCE SIOCIWFIRSTPRIV + 9
+
+
+static int wlcompat_private_ioctl(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ int *value = (int *) wrqu->name;
+
+ switch (info->cmd) {
+ case WLCOMPAT_SET_MONITOR:
+ {
+ if (wl_ioctl(dev, WLC_SET_MONITOR, value, sizeof(int)) < 0)
+ return -EINVAL;
+
+ break;
+ }
+ case WLCOMPAT_GET_MONITOR:
+ {
+ if (wl_ioctl(dev, WLC_GET_MONITOR, extra, sizeof(int)) < 0)
+ return -EINVAL;
+
+ break;
+ }
+ case WLCOMPAT_SET_TXPWR_LIMIT:
+ {
+ int val;
+
+
+ if (wl_get_val(dev, "qtxpower", &val, sizeof(int)) < 0)
+ return -EINVAL;
+
+ if (*extra > 0)
+ val |= WL_TXPWR_OVERRIDE;
+ else
+ val &= ~WL_TXPWR_OVERRIDE;
+
+ if (wl_set_val(dev, "qtxpower", &val, sizeof(int)) < 0)
+ return -EINVAL;
+
+ break;
+ }
+ case WLCOMPAT_GET_TXPWR_LIMIT:
+ {
+ if (wl_get_val(dev, "qtxpower", value, sizeof(int)) < 0)
+ return -EINVAL;
+
+ *value = ((*value & WL_TXPWR_OVERRIDE) == WL_TXPWR_OVERRIDE ? 1 : 0);
+
+ break;
+ }
+ case WLCOMPAT_SET_ANTDIV:
+ {
+ if (wl_ioctl(dev, WLC_SET_ANTDIV, value, sizeof(int)) < 0)
+ return -EINVAL;
+
+ break;
+ }
+ case WLCOMPAT_GET_ANTDIV:
+ {
+ if (wl_ioctl(dev, WLC_GET_ANTDIV, extra, sizeof(int)) < 0)
+ return -EINVAL;
+
+ break;
+ }
+ case WLCOMPAT_SET_TXANT:
+ {
+ if (wl_ioctl(dev, WLC_SET_TXANT, value, sizeof(int)) < 0)
+ return -EINVAL;
+
+ break;
+ }
+ case WLCOMPAT_GET_TXANT:
+ {
+ if (wl_ioctl(dev, WLC_GET_TXANT, extra, sizeof(int)) < 0)
+ return -EINVAL;
+
+ break;
+ }
+ case WLCOMPAT_SET_BSS_FORCE:
+ {
+ bss_force = (unsigned short) *value;
+ break;
+ }
+ case WLCOMPAT_GET_BSS_FORCE:
+ {
+ *extra = (int) bss_force;
+ break;
+ }
+ default:
+ {
+ return -EINVAL;
+ }
+
+ }
+ return 0;
+}
+
+static const struct iw_priv_args wlcompat_private_args[] =
+{
+ { WLCOMPAT_SET_MONITOR,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_monitor"
+ },
+ { WLCOMPAT_GET_MONITOR,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_monitor"
+ },
+ { WLCOMPAT_SET_TXPWR_LIMIT,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_txpwr_force"
+ },
+ { WLCOMPAT_GET_TXPWR_LIMIT,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_txpwr_force"
+ },
+ { WLCOMPAT_SET_ANTDIV,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_antdiv"
+ },
+ { WLCOMPAT_GET_ANTDIV,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_antdiv"
+ },
+ { WLCOMPAT_SET_TXANT,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_txant"
+ },
+ { WLCOMPAT_GET_TXANT,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_txant"
+ },
+ { WLCOMPAT_SET_BSS_FORCE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_bss_force"
+ },
+ { WLCOMPAT_GET_BSS_FORCE,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_bss_force"
+ },
+};
+
+static const iw_handler wlcompat_private[] =
+{
+ wlcompat_private_ioctl,
+ NULL
+};
+
+
+static const struct iw_handler_def wlcompat_handler_def =
+{
+ .standard = (iw_handler *) wlcompat_handler,
+ .num_standard = sizeof(wlcompat_handler)/sizeof(iw_handler),
+ .private = wlcompat_private,
+ .num_private = 1,
+ .private_args = wlcompat_private_args,
+ .num_private_args = sizeof(wlcompat_private_args) / sizeof(wlcompat_private_args[0])
+};
+
+
+#ifdef DEBUG
+void print_buffer(int len, unsigned char *buf) {
+ int x;
+ if (buf != NULL) {
+ for (x=0;x<len && x<180 ;x++) {
+ if ((x % 4) == 0)
+ printk(" ");
+ printk("%02X",buf[x]);
+ }
+ } else {
+ printk(" NULL");
+ }
+ printk("\n");
+
+}
+#endif
+static int (*old_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
+static int new_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) {
+ int ret = 0;
+ struct iwreq *iwr = (struct iwreq *) ifr;
+ struct iw_request_info info;
+
+#ifdef DEBUG
+ printk("dev: %s ioctl: 0x%04x\n",dev->name,cmd);
+#endif
+
+ if (cmd >= SIOCIWFIRSTPRIV) {
+ info.cmd = cmd;
+ info.flags = 0;
+ ret = wlcompat_private_ioctl(dev, &info, &(iwr->u), (char *) &(iwr->u));
+#ifdef DEBUG
+ } else if (cmd==SIOCDEVPRIVATE) {
+ wl_ioctl_t *ioc = (wl_ioctl_t *)ifr->ifr_data;
+ unsigned char *buf = ioc->buf;
+ printk(" cmd: %d buf: 0x%08x len: %d\n",ioc->cmd,&(ioc->buf),ioc->len);
+ printk(" send: ->");
+ print_buffer(ioc->len, buf);
+ ret = old_ioctl(dev,ifr,cmd);
+ printk(" recv: ->");
+ print_buffer(ioc->len, buf);
+ printk(" ret: %d\n", ret);
+#endif
+ } else {
+ ret = old_ioctl(dev,ifr,cmd);
+ }
+ return ret;
+}
+
+static struct timer_list rng_timer;
+
+static void rng_timer_tick(unsigned long n)
+{
+ struct net_device *dev = (struct net_device *) n;
+ u16 data[4];
+ int i, ret;
+
+ ret = 0;
+ for (i = 0; i < 3; i++) {
+ ret |= wl_get_val(dev, "rand", &data[i], sizeof(u16));
+ }
+ if (!ret)
+ batch_entropy_store(*((u32 *) &data[0]), *((u32 *) &data[2]), (jiffies % 255));
+
+ mod_timer(&rng_timer, jiffies + (HZ/RNG_POLL_FREQ));
+}
+
+
+static int __init wlcompat_init()
+{
+ int found = 0, i;
+ char devname[4] = "wl0";
+ bss_force = 0;
+
+ while (!found && (dev = dev_get_by_name(devname))) {
+ if ((dev->wireless_handlers == NULL) && ((wl_ioctl(dev, WLC_GET_MAGIC, &i, sizeof(i)) == 0) && i == WLC_IOCTL_MAGIC))
+ found = 1;
+ devname[2]++;
+ }
+
+ if (!found) {
+ printk("No Broadcom devices found.\n");
+ return -ENODEV;
+ }
+
+
+ old_ioctl = dev->do_ioctl;
+ dev->do_ioctl = new_ioctl;
+ dev->wireless_handlers = (struct iw_handler_def *)&wlcompat_handler_def;
+ dev->get_wireless_stats = wlcompat_get_wireless_stats;
+
+ if (random) {
+ init_timer(&rng_timer);
+ rng_timer.function = rng_timer_tick;
+ rng_timer.data = (unsigned long) dev;
+ rng_timer_tick((unsigned long) dev);
+ }
+
+#ifdef DEBUG
+ printk("broadcom driver private data: 0x%08x\n", dev->priv);
+#endif
+ return 0;
+}
+
+static void __exit wlcompat_exit()
+{
+ if (random)
+ del_timer(&rng_timer);
+ dev->get_wireless_stats = NULL;
+ dev->wireless_handlers = NULL;
+ dev->do_ioctl = old_ioctl;
+ return;
+}
+
+EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("openwrt.org");
+MODULE_LICENSE("GPL");
+
+module_param(random, int, 0);
+module_init(wlcompat_init);
+module_exit(wlcompat_exit);