Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

383 Commits   1 Branch   1 Tag
Index: Makefile
===================================================================
--- Makefile	(nonexistent)
+++ Makefile	(revision 5)
@@ -0,0 +1,13 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+SOURCE_REQUIRES += ALL_DIRS
+
+
+include ../../build-system/core.mk
+
+
+download_clean:
+	@true
+
+.PHONY: download_clean
Index: drivers/Makefile
===================================================================
--- drivers/Makefile	(nonexistent)
+++ drivers/Makefile	(revision 5)
@@ -0,0 +1,13 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+SOURCE_REQUIRES += ALL_DIRS
+
+
+include ../../../build-system/core.mk
+
+
+download_clean:
+	@true
+
+.PHONY: download_clean
Index: drivers/wireless/Makefile
===================================================================
--- drivers/wireless/Makefile	(nonexistent)
+++ drivers/wireless/Makefile	(revision 5)
@@ -0,0 +1,13 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+SOURCE_REQUIRES += ALL_DIRS
+
+
+include ../../../../build-system/core.mk
+
+
+download_clean:
+	@true
+
+.PHONY: download_clean
Index: drivers/wireless/broadcom-wl/Makefile
===================================================================
--- drivers/wireless/broadcom-wl/Makefile	(nonexistent)
+++ drivers/wireless/broadcom-wl/Makefile	(revision 5)
@@ -0,0 +1,47 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/hal/drivers/wireless/broadcom-wl
+
+versions    = 6.30.223.271
+pkgname     = broadcom-wl
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: drivers/wireless/broadcom-wl
===================================================================
--- drivers/wireless/broadcom-wl	(nonexistent)
+++ drivers/wireless/broadcom-wl	(revision 5)

Property changes on: drivers/wireless/broadcom-wl
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless/broadcom-wl-x86/Makefile
===================================================================
--- drivers/wireless/broadcom-wl-x86/Makefile	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/Makefile	(revision 5)
@@ -0,0 +1,56 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/hal/drivers/wireless/broadcom-wl-x86
+
+versions    = 6.30.223.271
+pkgname     = broadcom-wl-x86
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+patches     = $(CURDIR)/patches/broadcom-wl-x86-6.30.223.271-x86.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-6.30.223.271-x86-patch ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/README.md
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/README.md	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/README.md	(revision 5)
@@ -0,0 +1,78 @@
+# Broadcom Linux hybrid wireless driver (32-bit)
+
+Re-upload from the source code found on the [Broadcom Support and Downloads page][1]
+
+**Patched for Linux >= 4.7**
+
+Tested on a BCM4360-based 802.11ac Wireless Network Adapter (TP-LINK Archer T8E)
+
+[1]: https://www.broadcom.com/support/download-search/?pg=&pf=Wireless+LAN+Infrastructure
+
+## Prerequisites
+
+The following kernel modules are incompatible with this driver and should not be loaded:
+* ssb
+* bcma
+* b43
+* brcmsmac
+
+Make sure to unload (`rmmod` command) and blacklist those modules in order to prevent them from being automatically
+reloaded during the next system startup:
+
+`/etc/modprobe.d/blacklist.conf`
+```
+# wireless drivers (conflict with Broadcom hybrid wireless driver 'wl')
+blacklist ssb
+blacklist bcma
+blacklist b43
+blacklist brcmsmac
+```
+
+## Compile and install
+
+### Manually
+
+Build and install for the running kernel:
+
+```sh
+$ make
+$ make install
+$ depmod -A
+$ modprobe wl
+```
+
+### Automatically
+
+Using [DKMS][2] and the included `dkms.conf` file, one can let the operating system rebuild and install the module
+automatically on every new kernel installation:
+
+```sh
+$ dkms add /path/to/this/repo
+$ dkms status
+broadcom-wl, 6.30.223.271: added
+```
+
+Providing that the `dkms` service is enabled, the module should appear as *installed* in the list of modules managed by
+DKMS after the system boots for the first time on the new kernel:
+
+```sh
+$ dkms status
+broadcom-wl, 6.30.223.271, 4.7.6-200.x86_64, x86_64: installed
+```
+
+[2]: http://linux.dell.com/dkms/manpage.html
+
+## See also
+
+* [Official README file][3] (download)
+* Arch Linux packages: [broadcom-wl][4] / [broadcom-wl-dkms][5]
+* Debian packages: [broadcom-sta][6] ([source repository][7])
+* [kmod-wl][8] package for RPM Fusion ([source repository][9])
+
+[3]: https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/README_6.30.223.271.txt
+[4]: https://www.archlinux.org/packages/community/x86_64/broadcom-wl/
+[5]: https://www.archlinux.org/packages/community/x86_64/broadcom-wl-dkms/
+[6]: https://packages.debian.org/source/sid/broadcom-sta
+[7]: https://salsa.debian.org/broadcom-sta-team/broadcom-sta
+[8]: http://download1.rpmfusion.org/nonfree/fedora/development/rawhide/Everything/x86_64/os/repoview/kmod-wl.html
+[9]: https://pkgs.rpmfusion.org/cgit/nonfree/wl-kmod.git/
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/dkms.conf
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/dkms.conf	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/dkms.conf	(revision 5)
@@ -0,0 +1,7 @@
+PACKAGE_NAME=broadcom-wl
+PACKAGE_VERSION=6.30.223.271
+MAKE="make KBASE=/lib/modules/${kernelver}"
+CLEAN="make KBASE=/lib/modules/${kernelver} clean"
+BUILT_MODULE_NAME=wl
+DEST_MODULE_LOCATION=/kernel/drivers/net/wireless
+AUTOINSTALL=yes
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/shared/linux_osl.c
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/shared/linux_osl.c	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/shared/linux_osl.c	(revision 5)
@@ -0,0 +1,1158 @@
+/*
+ * Linux OS Independent Layer
+ *
+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: linux_osl.c 383331 2013-02-06 10:27:24Z $
+ */
+
+#define LINUX_PORT
+
+#include <typedefs.h>
+#include <bcmendian.h>
+#include <linuxver.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <linux/delay.h>
+#include <pcicfg.h>
+
+#include <linux/fs.h>
+
+#define PCI_CFG_RETRY 		10
+
+#define OS_HANDLE_MAGIC		0x1234abcd	
+#define BCM_MEM_FILENAME_LEN 	24		
+
+typedef struct bcm_mem_link {
+	struct bcm_mem_link *prev;
+	struct bcm_mem_link *next;
+	uint	size;
+	int	line;
+	void 	*osh;
+	char	file[BCM_MEM_FILENAME_LEN];
+} bcm_mem_link_t;
+
+struct osl_info {
+	osl_pubinfo_t pub;
+	uint magic;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+	void *pdev;
+#else
+	struct pci_dev *pdev;
+#endif
+	atomic_t malloced;
+	atomic_t pktalloced; 	
+	uint failed;
+	uint bustype;
+	bcm_mem_link_t *dbgmem_list;
+	spinlock_t dbgmem_lock;
+	spinlock_t pktalloc_lock;
+};
+
+#define OSL_PKTTAG_CLEAR(p) \
+do { \
+	struct sk_buff *s = (struct sk_buff *)(p); \
+	ASSERT(OSL_PKTTAG_SZ == 32); \
+	*(uint32 *)(&s->cb[0]) = 0; *(uint32 *)(&s->cb[4]) = 0; \
+	*(uint32 *)(&s->cb[8]) = 0; *(uint32 *)(&s->cb[12]) = 0; \
+	*(uint32 *)(&s->cb[16]) = 0; *(uint32 *)(&s->cb[20]) = 0; \
+	*(uint32 *)(&s->cb[24]) = 0; *(uint32 *)(&s->cb[28]) = 0; \
+} while (0)
+
+uint32 g_assert_type = FALSE;
+
+static int16 linuxbcmerrormap[] =
+{	0, 			
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL,		
+	-EINVAL, 		
+	-EINVAL, 		
+	-EINVAL, 		
+	-E2BIG,			
+	-E2BIG,			
+	-EBUSY, 		
+	-EINVAL, 		
+	-EINVAL, 		
+	-EINVAL, 		
+	-EINVAL, 		
+	-EFAULT, 		
+	-ENOMEM, 		
+	-EOPNOTSUPP,		
+	-EMSGSIZE,		
+	-EINVAL,		
+	-EPERM,			
+	-ENOMEM, 		
+	-EINVAL, 		
+	-ERANGE, 		
+	-EINVAL, 		
+	-EINVAL, 		
+	-EINVAL, 		
+	-EINVAL, 		
+	-EINVAL,		
+	-EIO,			
+	-ENODEV,		
+	-EINVAL,		
+	-EIO,			
+	-EIO,			
+	-ENODEV,		
+	-EINVAL,		
+	-ENODATA,		
+	-EINVAL,		
+
+#if BCME_LAST != -43
+#error "You need to add a OS error translation in the linuxbcmerrormap \
+	for new error code defined in bcmutils.h"
+#endif
+};
+
+int
+osl_error(int bcmerror)
+{
+	if (bcmerror > 0)
+		bcmerror = 0;
+	else if (bcmerror < BCME_LAST)
+		bcmerror = BCME_ERROR;
+
+	return linuxbcmerrormap[-bcmerror];
+}
+
+extern uint8* dhd_os_prealloc(void *osh, int section, int size);
+
+osl_t *
+osl_attach(void *pdev, uint bustype, bool pkttag)
+{
+	osl_t *osh;
+
+	osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
+	ASSERT(osh);
+
+	bzero(osh, sizeof(osl_t));
+
+	ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1));
+
+	osh->magic = OS_HANDLE_MAGIC;
+	atomic_set(&osh->malloced, 0);
+	osh->failed = 0;
+	osh->dbgmem_list = NULL;
+	spin_lock_init(&(osh->dbgmem_lock));
+	osh->pdev = pdev;
+	osh->pub.pkttag = pkttag;
+	osh->bustype = bustype;
+
+	switch (bustype) {
+		case PCI_BUS:
+		case SI_BUS:
+		case PCMCIA_BUS:
+			osh->pub.mmbus = TRUE;
+			break;
+		case JTAG_BUS:
+		case SDIO_BUS:
+		case USB_BUS:
+		case SPI_BUS:
+		case RPC_BUS:
+			osh->pub.mmbus = FALSE;
+			break;
+		default:
+			ASSERT(FALSE);
+			break;
+	}
+
+	spin_lock_init(&(osh->pktalloc_lock));
+
+#ifdef BCMDBG
+	if (pkttag) {
+		struct sk_buff *skb;
+		BCM_REFERENCE(skb);
+		ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb));
+	}
+#endif
+	return osh;
+}
+
+void
+osl_detach(osl_t *osh)
+{
+	if (osh == NULL)
+		return;
+
+	ASSERT(osh->magic == OS_HANDLE_MAGIC);
+	kfree(osh);
+}
+
+static struct sk_buff *osl_alloc_skb(unsigned int len)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+	gfp_t flags = GFP_ATOMIC;
+	struct sk_buff *skb;
+
+	skb = __dev_alloc_skb(len, flags);
+	return skb;
+#else
+	return dev_alloc_skb(len);
+#endif 
+}
+
+struct sk_buff * BCMFASTPATH
+osl_pkt_tonative(osl_t *osh, void *pkt)
+{
+	struct sk_buff *nskb;
+
+	if (osh->pub.pkttag)
+		OSL_PKTTAG_CLEAR(pkt);
+
+	for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
+		atomic_sub(PKTISCHAINED(nskb) ? PKTCCNT(nskb) : 1, &osh->pktalloced);
+
+	}
+	return (struct sk_buff *)pkt;
+}
+
+void * BCMFASTPATH
+osl_pkt_frmnative(osl_t *osh, void *pkt)
+{
+	struct sk_buff *nskb;
+
+	if (osh->pub.pkttag)
+		OSL_PKTTAG_CLEAR(pkt);
+
+	for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
+		atomic_add(PKTISCHAINED(nskb) ? PKTCCNT(nskb) : 1, &osh->pktalloced);
+
+	}
+	return (void *)pkt;
+}
+
+void * BCMFASTPATH
+osl_pktget(osl_t *osh, uint len)
+{
+	struct sk_buff *skb;
+
+	if ((skb = osl_alloc_skb(len))) {
+#ifdef BCMDBG
+		skb_put(skb, len);
+#else
+		skb->tail += len;
+		skb->len  += len;
+#endif
+		skb->priority = 0;
+
+		atomic_inc(&osh->pktalloced);
+	}
+
+	return ((void*) skb);
+}
+
+void BCMFASTPATH
+osl_pktfree(osl_t *osh, void *p, bool send)
+{
+	struct sk_buff *skb, *nskb;
+
+	skb = (struct sk_buff*) p;
+
+	if (send && osh->pub.tx_fn)
+		osh->pub.tx_fn(osh->pub.tx_ctx, p, 0);
+
+	PKTDBG_TRACE(osh, (void *) skb, PKTLIST_PKTFREE);
+
+	while (skb) {
+		nskb = skb->next;
+		skb->next = NULL;
+
+		{
+			if (skb->destructor)
+
+				dev_kfree_skb_any(skb);
+			else
+
+				dev_kfree_skb(skb);
+		}
+		atomic_dec(&osh->pktalloced);
+		skb = nskb;
+	}
+}
+
+uint32
+osl_pci_read_config(osl_t *osh, uint offset, uint size)
+{
+	uint val = 0;
+	uint retry = PCI_CFG_RETRY;
+
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+	ASSERT(size == 4);
+
+	do {
+		pci_read_config_dword(osh->pdev, offset, &val);
+		if (val != 0xffffffff)
+			break;
+	} while (retry--);
+
+#ifdef BCMDBG
+	if (retry < PCI_CFG_RETRY)
+		printk("PCI CONFIG READ access to %d required %d retries\n", offset,
+		       (PCI_CFG_RETRY - retry));
+#endif 
+
+	return (val);
+}
+
+void
+osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
+{
+	uint retry = PCI_CFG_RETRY;
+
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+	ASSERT(size == 4);
+
+	do {
+		pci_write_config_dword(osh->pdev, offset, val);
+		if (offset != PCI_BAR0_WIN)
+			break;
+		if (osl_pci_read_config(osh, offset, size) == val)
+			break;
+	} while (retry--);
+
+#ifdef BCMDBG
+	if (retry < PCI_CFG_RETRY)
+		printk("PCI CONFIG WRITE access to %d required %d retries\n", offset,
+		       (PCI_CFG_RETRY - retry));
+#endif 
+}
+
+uint
+osl_pci_bus(osl_t *osh)
+{
+	ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+	return ((struct pci_dev *)osh->pdev)->bus->number;
+}
+
+uint
+osl_pci_slot(osl_t *osh)
+{
+	ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+#if defined(__ARM_ARCH_7A__) && LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)
+	return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn) + 1;
+#else
+	return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
+#endif
+}
+
+struct pci_dev *
+osl_pci_device(osl_t *osh)
+{
+	ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+	return osh->pdev;
+}
+
+static void
+osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write)
+{
+}
+
+void
+osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size)
+{
+	osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE);
+}
+
+void
+osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size)
+{
+	osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE);
+}
+
+#ifdef BCMDBG_MEM
+
+static
+#endif
+void *
+osl_malloc(osl_t *osh, uint size)
+{
+	void *addr;
+
+	if (osh)
+		ASSERT(osh->magic == OS_HANDLE_MAGIC);
+
+	if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) {
+		if (osh)
+			osh->failed++;
+		return (NULL);
+	}
+	if (osh)
+		atomic_add(size, &osh->malloced);
+
+	return (addr);
+}
+
+#ifdef BCMDBG_MEM
+
+static
+#endif
+void
+osl_mfree(osl_t *osh, void *addr, uint size)
+{
+	if (osh) {
+		ASSERT(osh->magic == OS_HANDLE_MAGIC);
+		atomic_sub(size, &osh->malloced);
+	}
+	kfree(addr);
+}
+
+uint
+osl_malloced(osl_t *osh)
+{
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+	return (atomic_read(&osh->malloced));
+}
+
+uint
+osl_malloc_failed(osl_t *osh)
+{
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+	return (osh->failed);
+}
+
+#ifdef BCMDBG_MEM
+#define MEMLIST_LOCK(osh, flags)	spin_lock_irqsave(&(osh)->dbgmem_lock, flags)
+#define MEMLIST_UNLOCK(osh, flags)	spin_unlock_irqrestore(&(osh)->dbgmem_lock, flags)
+
+void *
+osl_debug_malloc(osl_t *osh, uint size, int line, const char* file)
+{
+	bcm_mem_link_t *p;
+	const char* basename;
+	unsigned long flags = 0;
+
+	if (!size) {
+		printk("%s: allocating zero sized mem at %s line %d\n", __FUNCTION__, file, line);
+		ASSERT(0);
+	}
+
+	if (osh) {
+		MEMLIST_LOCK(osh, flags);
+	}
+	if ((p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size)) == NULL) {
+		if (osh) {
+			MEMLIST_UNLOCK(osh, flags);
+		}
+		return (NULL);
+	}
+
+	p->size = size;
+	p->line = line;
+	p->osh = (void *)osh;
+
+	basename = strrchr(file, '/');
+
+	if (basename)
+		basename++;
+
+	if (!basename)
+		basename = file;
+
+	strncpy(p->file, basename, BCM_MEM_FILENAME_LEN);
+	p->file[BCM_MEM_FILENAME_LEN - 1] = '\0';
+
+	if (osh) {
+		p->prev = NULL;
+		p->next = osh->dbgmem_list;
+		if (p->next)
+			p->next->prev = p;
+		osh->dbgmem_list = p;
+		MEMLIST_UNLOCK(osh, flags);
+	}
+
+	return p + 1;
+}
+
+void
+osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, const char* file)
+{
+	bcm_mem_link_t *p = (bcm_mem_link_t *)((int8*)addr - sizeof(bcm_mem_link_t));
+	unsigned long flags = 0;
+
+	ASSERT(osh == NULL || osh->magic == OS_HANDLE_MAGIC);
+
+	if (p->size == 0) {
+		printk("osl_debug_mfree: double free on addr %p size %d at line %d file %s\n",
+			addr, size, line, file);
+		ASSERT(p->size);
+		return;
+	}
+
+	if (p->size != size) {
+		printk("%s: dealloca size does not match alloc size\n", __FUNCTION__);
+		printk("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file);
+		printk("Alloc size %d line %d file %s\n", p->size, p->line, p->file);
+		ASSERT(p->size == size);
+		return;
+	}
+
+	if (p->osh != (void *)osh) {
+		printk("osl_debug_mfree: alloc osh %p does not match dealloc osh %p\n",
+			p->osh, osh);
+		printk("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file);
+		printk("Alloc size %d line %d file %s\n", p->size, p->line, p->file);
+		ASSERT(p->osh == (void *)osh);
+		return;
+	}
+
+	if (osh) {
+		MEMLIST_LOCK(osh, flags);
+		if (p->prev)
+			p->prev->next = p->next;
+		if (p->next)
+			p->next->prev = p->prev;
+		if (osh->dbgmem_list == p)
+			osh->dbgmem_list = p->next;
+		p->next = p->prev = NULL;
+	}
+	p->size = 0;
+
+	osl_mfree(osh, p, size + sizeof(bcm_mem_link_t));
+	if (osh) {
+		MEMLIST_UNLOCK(osh, flags);
+	}
+}
+
+int
+osl_debug_memdump(osl_t *osh, struct bcmstrbuf *b)
+{
+	bcm_mem_link_t *p;
+	unsigned long flags = 0;
+
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+	MEMLIST_LOCK(osh, flags);
+	if (osh->dbgmem_list) {
+		if (b != NULL)
+			bcm_bprintf(b, "   Address   Size File:line\n");
+		else
+			printf("   Address   Size File:line\n");
+
+		for (p = osh->dbgmem_list; p; p = p->next) {
+			if (b != NULL)
+				bcm_bprintf(b, "%p %6d %s:%d\n", (char*)p + sizeof(bcm_mem_link_t),
+					p->size, p->file, p->line);
+			else
+				printf("%p %6d %s:%d\n", (char*)p + sizeof(bcm_mem_link_t),
+					p->size, p->file, p->line);
+
+			if (p == p->next) {
+				if (b != NULL)
+					bcm_bprintf(b, "WARNING: loop-to-self "
+						"p %p p->next %p\n", p, p->next);
+				else
+					printf("WARNING: loop-to-self "
+						"p %p p->next %p\n", p, p->next);
+
+				break;
+			}
+		}
+	}
+	MEMLIST_UNLOCK(osh, flags);
+
+	return 0;
+}
+
+#endif	
+
+uint
+osl_dma_consistent_align(void)
+{
+	return (PAGE_SIZE);
+}
+
+void*
+osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, ulong *pap)
+{
+	void *va;
+	uint16 align = (1 << align_bits);
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+	if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align))
+		size += align;
+	*alloced = size;
+
+#ifdef __ARM_ARCH_7A__
+	va = kmalloc(size, GFP_ATOMIC | __GFP_ZERO);
+	if (va)
+		*pap = (ulong)__virt_to_phys(va);
+#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+	va = pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap);
+#else
+	va = dma_alloc_coherent(&osh->pdev->dev, size, (dma_addr_t *)pap, GFP_ATOMIC);
+#endif
+#endif
+	return va;
+}
+
+void
+osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
+{
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+#ifdef __ARM_ARCH_7A__
+	kfree(va);
+#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+	pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
+#else
+	dma_free_coherent(&osh->pdev->dev, size, va, (dma_addr_t)pa);
+#endif
+#endif
+}
+
+uint BCMFASTPATH
+osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *dmah)
+{
+	int dir;
+
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+	dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
+#else
+	dir = (direction == DMA_TX)? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+#endif
+
+#if defined(__ARM_ARCH_7A__) && defined(BCMDMASGLISTOSL)
+	if (dmah != NULL) {
+		int32 nsegs, i, totsegs = 0, totlen = 0;
+		struct scatterlist *sg, _sg[MAX_DMA_SEGS * 2];
+		struct sk_buff *skb;
+		for (skb = (struct sk_buff *)p; skb != NULL; skb = PKTNEXT(osh, skb)) {
+			sg = &_sg[totsegs];
+			if (skb_is_nonlinear(skb)) {
+				nsegs = skb_to_sgvec(skb, sg, 0, PKTLEN(osh, skb));
+				ASSERT((nsegs > 0) && (totsegs + nsegs <= MAX_DMA_SEGS));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+				pci_map_sg(osh->pdev, sg, nsegs, dir);
+#else
+				dma_map_sg(&osh->pdev->dev, sg, nsegs, dir);
+#endif
+			} else {
+				nsegs = 1;
+				ASSERT(totsegs + nsegs <= MAX_DMA_SEGS);
+				sg->page_link = 0;
+				sg_set_buf(sg, PKTDATA(osh, skb), PKTLEN(osh, skb));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+				pci_map_single(osh->pdev, PKTDATA(osh, skb), PKTLEN(osh, skb), dir);
+#else
+				dma_map_single(&osh->pdev->dev, PKTDATA(osh, skb), PKTLEN(osh, skb), dir);
+#endif
+			}
+			totsegs += nsegs;
+			totlen += PKTLEN(osh, skb);
+		}
+		dmah->nsegs = totsegs;
+		dmah->origsize = totlen;
+		for (i = 0, sg = _sg; i < totsegs; i++, sg++) {
+			dmah->segs[i].addr = sg_phys(sg);
+			dmah->segs[i].length = sg->length;
+		}
+		return dmah->segs[0].addr;
+	}
+#endif 
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+	return (pci_map_single(osh->pdev, va, size, dir));
+#else
+	return (dma_map_single(&osh->pdev->dev, va, size, dir));
+#endif
+}
+
+void BCMFASTPATH
+osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction)
+{
+	int dir;
+
+	ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+	dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
+	pci_unmap_single(osh->pdev, (uint32)pa, size, dir);
+#else
+	dir = (direction == DMA_TX)? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+	dma_unmap_single(&osh->pdev->dev, (uint32)pa, size, dir);
+#endif
+}
+
+#if defined(BCMDBG_ASSERT)
+void
+osl_assert(const char *exp, const char *file, int line)
+{
+	char tempbuf[256];
+	const char *basename;
+
+	basename = strrchr(file, '/');
+
+	if (basename)
+		basename++;
+
+	if (!basename)
+		basename = file;
+
+#ifdef BCMDBG_ASSERT
+	snprintf(tempbuf, 256, "assertion \"%s\" failed: file \"%s\", line %d\n",
+		exp, basename, line);
+
+	if (!in_interrupt() && g_assert_type != 1) {
+		const int delay = 3;
+		printk("%s", tempbuf);
+		printk("panic in %d seconds\n", delay);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(delay * HZ);
+	}
+
+	switch (g_assert_type) {
+	case 0:
+		panic("%s", tempbuf);
+		break;
+	case 1:
+		printk("%s", tempbuf);
+		break;
+	case 2:
+		printk("%s", tempbuf);
+		BUG();
+		break;
+	default:
+		break;
+	}
+#endif 
+
+}
+#endif 
+
+void
+osl_delay(uint usec)
+{
+	uint d;
+
+	while (usec > 0) {
+		d = MIN(usec, 1000);
+		udelay(d);
+		usec -= d;
+	}
+}
+
+void *
+osl_pktdup(osl_t *osh, void *skb)
+{
+	void * p;
+
+	ASSERT(!PKTISCHAINED(skb));
+
+	PKTCTFMAP(osh, skb);
+
+	if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL)
+		return NULL;
+
+	PKTSETCLINK(p, NULL);
+	PKTCCLRFLAGS(p);
+	PKTCSETCNT(p, 1);
+	PKTCSETLEN(p, PKTLEN(osh, skb));
+
+	if (osh->pub.pkttag)
+		OSL_PKTTAG_CLEAR(p);
+
+	atomic_inc(&osh->pktalloced);
+	return (p);
+}
+
+uint32
+osl_sysuptime(void)
+{
+	return ((uint32)jiffies * (1000 / HZ));
+}
+
+int
+osl_printf(const char *format, ...)
+{
+	va_list args;
+	static char printbuf[1024];
+	int len;
+
+	va_start(args, format);
+	len = vsnprintf(printbuf, 1024, format, args);
+	va_end(args);
+
+	if (len > sizeof(printbuf)) {
+		printk("osl_printf: buffer overrun\n");
+		return (0);
+	}
+
+	return (printk("%s", printbuf));
+}
+
+int
+osl_sprintf(char *buf, const char *format, ...)
+{
+	va_list args;
+	int rc;
+
+	va_start(args, format);
+	rc = vsprintf(buf, format, args);
+	va_end(args);
+	return (rc);
+}
+
+int
+osl_snprintf(char *buf, size_t n, const char *format, ...)
+{
+	va_list args;
+	int rc;
+
+	va_start(args, format);
+	rc = vsnprintf(buf, n, format, args);
+	va_end(args);
+	return (rc);
+}
+
+int
+osl_vsprintf(char *buf, const char *format, va_list ap)
+{
+	return (vsprintf(buf, format, ap));
+}
+
+int
+osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap)
+{
+	return (vsnprintf(buf, n, format, ap));
+}
+
+int
+osl_strcmp(const char *s1, const char *s2)
+{
+	return (strcmp(s1, s2));
+}
+
+int
+osl_strncmp(const char *s1, const char *s2, uint n)
+{
+	return (strncmp(s1, s2, n));
+}
+
+int
+osl_strlen(const char *s)
+{
+	return (strlen(s));
+}
+
+char*
+osl_strcpy(char *d, const char *s)
+{
+	return (strcpy(d, s));
+}
+
+char*
+osl_strncpy(char *d, const char *s, uint n)
+{
+	return (strncpy(d, s, n));
+}
+
+char*
+osl_strchr(const char *s, int c)
+{
+	return (strchr(s, c));
+}
+
+char*
+osl_strrchr(const char *s, int c)
+{
+	return (strrchr(s, c));
+}
+
+void*
+osl_memset(void *d, int c, size_t n)
+{
+	return memset(d, c, n);
+}
+
+void*
+osl_memcpy(void *d, const void *s, size_t n)
+{
+	return memcpy(d, s, n);
+}
+
+void*
+osl_memmove(void *d, const void *s, size_t n)
+{
+	return memmove(d, s, n);
+}
+
+int
+osl_memcmp(const void *s1, const void *s2, size_t n)
+{
+	return memcmp(s1, s2, n);
+}
+
+uint32
+osl_readl(volatile uint32 *r)
+{
+	return (readl(r));
+}
+
+uint16
+osl_readw(volatile uint16 *r)
+{
+	return (readw(r));
+}
+
+uint8
+osl_readb(volatile uint8 *r)
+{
+	return (readb(r));
+}
+
+void
+osl_writel(uint32 v, volatile uint32 *r)
+{
+	writel(v, r);
+}
+
+void
+osl_writew(uint16 v, volatile uint16 *r)
+{
+	writew(v, r);
+}
+
+void
+osl_writeb(uint8 v, volatile uint8 *r)
+{
+	writeb(v, r);
+}
+
+void *
+osl_uncached(void *va)
+{
+	return ((void*)va);
+}
+
+void *
+osl_cached(void *va)
+{
+	return ((void*)va);
+}
+
+uint
+osl_getcycles(void)
+{
+	uint cycles;
+
+#if defined(__i386__)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
+	cycles = (u32)rdtsc();
+#else
+	rdtscl(cycles);
+#endif
+#else
+	cycles = 0;
+#endif 
+	return cycles;
+}
+
+void *
+osl_reg_map(uint32 pa, uint size)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
+	return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
+#else
+	return (ioremap((unsigned long)pa, (unsigned long)size));
+#endif
+}
+
+void
+osl_reg_unmap(void *va)
+{
+	iounmap(va);
+}
+
+int
+osl_busprobe(uint32 *val, uint32 addr)
+{
+	*val = readl((uint32 *)(uintptr)addr);
+	return 0;
+}
+
+bool
+osl_pktshared(void *skb)
+{
+	return (((struct sk_buff*)skb)->cloned);
+}
+
+uchar*
+osl_pktdata(osl_t *osh, void *skb)
+{
+	return (((struct sk_buff*)skb)->data);
+}
+
+uint
+osl_pktlen(osl_t *osh, void *skb)
+{
+	return (((struct sk_buff*)skb)->len);
+}
+
+uint
+osl_pktheadroom(osl_t *osh, void *skb)
+{
+	return (uint) skb_headroom((struct sk_buff *) skb);
+}
+
+uint
+osl_pkttailroom(osl_t *osh, void *skb)
+{
+	return (uint) skb_tailroom((struct sk_buff *) skb);
+}
+
+void*
+osl_pktnext(osl_t *osh, void *skb)
+{
+	return (((struct sk_buff*)skb)->next);
+}
+
+void
+osl_pktsetnext(void *skb, void *x)
+{
+	((struct sk_buff*)skb)->next = (struct sk_buff*)x;
+}
+
+void
+osl_pktsetlen(osl_t *osh, void *skb, uint len)
+{
+	__skb_trim((struct sk_buff*)skb, len);
+}
+
+uchar*
+osl_pktpush(osl_t *osh, void *skb, int bytes)
+{
+	return (skb_push((struct sk_buff*)skb, bytes));
+}
+
+uchar*
+osl_pktpull(osl_t *osh, void *skb, int bytes)
+{
+	return (skb_pull((struct sk_buff*)skb, bytes));
+}
+
+void*
+osl_pkttag(void *skb)
+{
+	return ((void*)(((struct sk_buff*)skb)->cb));
+}
+
+void*
+osl_pktlink(void *skb)
+{
+	return (((struct sk_buff*)skb)->prev);
+}
+
+void
+osl_pktsetlink(void *skb, void *x)
+{
+	((struct sk_buff*)skb)->prev = (struct sk_buff*)x;
+}
+
+uint
+osl_pktprio(void *skb)
+{
+	return (((struct sk_buff*)skb)->priority);
+}
+
+void
+osl_pktsetprio(void *skb, uint x)
+{
+	((struct sk_buff*)skb)->priority = x;
+}
+
+uint
+osl_pktalloced(osl_t *osh)
+{
+	return (atomic_read(&osh->pktalloced));
+}
+
+void *
+osl_os_open_image(char *filename)
+{
+	struct file *fp;
+
+	fp = filp_open(filename, O_RDONLY, 0);
+
+	 if (IS_ERR(fp))
+		 fp = NULL;
+
+	 return fp;
+}
+
+int
+osl_os_get_image_block(char *buf, int len, void *image)
+{
+	struct file *fp = (struct file *)image;
+	int rdlen;
+	loff_t pos;
+
+	if (!image)
+		return 0;
+
+	pos = fp->f_pos;
+	rdlen = kernel_read(fp,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
+			pos,
+#endif
+			buf, len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
+			,&pos
+#endif
+	);
+	if (rdlen > 0)
+		fp->f_pos += rdlen;
+
+	return rdlen;
+}
+
+void
+osl_os_close_image(void *image)
+{
+	if (image)
+		filp_close((struct file *)image, NULL);
+}
+
+int
+osl_os_image_size(void *image)
+{
+	int len = 0, curroffset;
+
+	if (image) {
+
+		curroffset = generic_file_llseek(image, 0, 1);
+
+		len = generic_file_llseek(image, 0, 2);
+
+		generic_file_llseek(image, curroffset, 0);
+	}
+	return len;
+}
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/shared
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/shared	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/shared	(revision 5)

Property changes on: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/shared
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_cfg80211_hybrid.c
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_cfg80211_hybrid.c	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_cfg80211_hybrid.c	(revision 5)
@@ -0,0 +1,3127 @@
+/*
+ * Linux-specific portion of Broadcom 802.11abg Networking Device Driver
+ * cfg80211 interface
+ *
+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: wl_cfg80211.c,v 1.1.6.4 2011-02-11 00:22:09 $
+ */
+
+#if defined(USE_CFG80211)
+
+#define LINUX_PORT
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/netdevice.h>
+#include <linux/ieee80211.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
+#include <linux/sched/signal.h>
+#endif
+#include <net/cfg80211.h>
+#include <linux/nl80211.h>
+#include <net/rtnetlink.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <wlioctl.h>
+#include <proto/802.11.h>
+#include <wl_cfg80211_hybrid.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
+#include <wl_linux.h>
+#endif
+
+#define EVENT_TYPE(e) dtoh32((e)->event_type)
+#define EVENT_FLAGS(e) dtoh16((e)->flags)
+#define EVENT_STATUS(e) dtoh32((e)->status)
+
+#ifdef BCMDBG
+u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
+#else
+u32 wl_dbg_level = WL_DBG_ERR;
+#endif
+
+static s32 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
+           enum nl80211_iftype type,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+           u32 *flags,
+#endif
+	   struct vif_params *params);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+static s32
+wl_cfg80211_scan(struct wiphy *wiphy,
+                 struct cfg80211_scan_request *request);
+#else
+static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+           struct cfg80211_scan_request *request);
+#endif
+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
+static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+           struct cfg80211_ibss_params *params);
+static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
+static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
+           struct net_device *dev, u8 *mac, struct station_info *sinfo);
+#else
+static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
+           struct net_device *dev, const u8 *mac, struct station_info *sinfo);
+#endif
+
+static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+           struct net_device *dev, bool enabled, s32 timeout);
+static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+           struct cfg80211_connect_params *sme);
+static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+static s32
+wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+                         enum nl80211_tx_power_setting type, s32 dbm);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
+           enum nl80211_tx_power_setting type, s32 dbm);
+#else
+static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
+           enum tx_power_setting type, s32 dbm);
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, s32 *dbm);
+#else
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
+#endif
+
+static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+           struct net_device *dev, int link_id, u8 key_idx, bool unicast, bool multicast);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+           struct net_device *dev, u8 key_idx, bool unicast, bool multicast);
+#else
+           struct net_device *dev, u8 key_idx);
+#endif
+static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+           int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+           u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params);
+#else
+           u8 key_idx, const u8 *mac_addr, struct key_params *params);
+#endif
+static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+           int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+           u8 key_idx, bool pairwise, const u8 *mac_addr);
+#else
+           u8 key_idx, const u8 *mac_addr);
+#endif
+static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+           int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr,
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+           u8 key_idx, bool pairwise, const u8 *mac_addr,
+#else
+           u8 key_idx, const u8 *mac_addr,
+#endif 
+           void *cookie, void (*callback) (void *cookie, struct key_params *params));
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
+           struct cfg80211_pmksa *pmksa);
+static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
+           struct cfg80211_pmksa *pmksa);
+static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev);
+#endif
+
+static s32 wl_create_event_handler(struct wl_cfg80211_priv *wl);
+static void wl_destroy_event_handler(struct wl_cfg80211_priv *wl);
+static s32 wl_event_handler(void *data);
+static void wl_init_eq(struct wl_cfg80211_priv *wl);
+static void wl_flush_eq(struct wl_cfg80211_priv *wl);
+static void wl_lock_eq(struct wl_cfg80211_priv *wl);
+static void wl_unlock_eq(struct wl_cfg80211_priv *wl);
+static void wl_init_eq_lock(struct wl_cfg80211_priv *wl);
+static void wl_init_eloop_handler(struct wl_cfg80211_event_loop *el);
+static struct wl_cfg80211_event_q *wl_deq_event(struct wl_cfg80211_priv *wl);
+static s32 wl_enq_event(struct wl_cfg80211_priv *wl, u32 type,
+	const wl_event_msg_t *msg, void *data);
+static void wl_put_event(struct wl_cfg80211_event_q *e);
+static void wl_wakeup_event(struct wl_cfg80211_priv *wl);
+
+static s32 wl_notify_connect_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+           const wl_event_msg_t *e, void *data);
+static s32 wl_notify_roaming_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+           const wl_event_msg_t *e, void *data);
+static s32 wl_notify_scan_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+           const wl_event_msg_t *e, void *data);
+static s32 wl_bss_connect_done(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+           const wl_event_msg_t *e, void *data, bool completed);
+static s32 wl_bss_roaming_done(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+           const wl_event_msg_t *e, void *data);
+static s32 wl_notify_mic_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+           const wl_event_msg_t *e, void *data);
+
+static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, s32 buf_len);
+static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len);
+static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
+static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval);
+static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len);
+
+static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
+static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
+static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
+
+static void wl_init_prof(struct wl_cfg80211_profile *prof);
+
+static s32 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme);
+static s32 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme);
+static s32 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme);
+static s32 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme);
+static s32 wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme);
+static s32 wl_get_assoc_ies(struct wl_cfg80211_priv *wl);
+static void wl_ch_to_chanspec(struct ieee80211_channel *chan,
+            struct wl_join_params *join_params, size_t *join_params_size);
+
+static void wl_rst_ie(struct wl_cfg80211_priv *wl);
+static __used s32 wl_add_ie(struct wl_cfg80211_priv *wl, u8 t, u8 l, u8 *v);
+static s32 wl_mrg_ie(struct wl_cfg80211_priv *wl, u8 *ie_stream, u16 ie_size);
+static s32 wl_cp_ie(struct wl_cfg80211_priv *wl, u8 *dst, u16 dst_size);
+static u32 wl_get_ielen(struct wl_cfg80211_priv *wl);
+
+static s32 wl_mode_to_nl80211_iftype(s32 mode);
+
+static s32 wl_alloc_wdev(struct device *dev, struct wireless_dev **rwdev);
+static void wl_free_wdev(struct wl_cfg80211_priv *wl);
+
+static s32 wl_inform_bss(struct wl_cfg80211_priv *wl, struct wl_scan_results *bss_list);
+static s32 wl_inform_single_bss(struct wl_cfg80211_priv *wl, struct wl_bss_info *bi);
+static s32 wl_update_bss_info(struct wl_cfg80211_priv *wl);
+
+static void key_endian_to_device(struct wl_wsec_key *key);
+static void key_endian_to_host(struct wl_wsec_key *key);
+
+static s32 wl_init_priv_mem(struct wl_cfg80211_priv *wl);
+static void wl_deinit_priv_mem(struct wl_cfg80211_priv *wl);
+
+static bool wl_is_ibssmode(struct wl_cfg80211_priv *wl);
+
+static void wl_link_up(struct wl_cfg80211_priv *wl);
+static void wl_link_down(struct wl_cfg80211_priv *wl);
+static s32 wl_set_mode(struct net_device *ndev, s32 iftype);
+
+static void wl_init_conf(struct wl_cfg80211_conf *conf);
+
+static s32 wl_update_wiphybands(struct wl_cfg80211_priv *wl);
+
+static __used s32 wl_update_pmklist(struct net_device *dev,
+                  struct wl_cfg80211_pmk_list *pmk_list, s32 err);
+
+#if defined(WL_DBGMSG_ENABLE)
+#define WL_DBG_ESTR_MAX	32
+static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
+	"SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
+	"DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
+	"REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
+	"BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
+	"TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
+	"EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
+	"BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
+	"PFN_NET_LOST",
+	"RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
+	"IBSS_ASSOC",
+	"RADIO", "PSM_WATCHDOG",
+	"PROBREQ_MSG",
+	"SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
+	"EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
+	"UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
+	"IF",
+	"RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
+};
+#endif				
+
+#define CHAN2G(_channel, _freq, _flags) {			\
+	.band			= IEEE80211_BAND_2GHZ,		\
+	.center_freq		= (_freq),			\
+	.hw_value		= (_channel),			\
+	.flags			= (_flags),			\
+	.max_antenna_gain	= 0,				\
+	.max_power		= 30,				\
+}
+
+#define CHAN5G(_channel, _flags) {				\
+	.band			= IEEE80211_BAND_5GHZ,		\
+	.center_freq		= 5000 + (5 * (_channel)),	\
+	.hw_value		= (_channel),			\
+	.flags			= (_flags),			\
+	.max_antenna_gain	= 0,				\
+	.max_power		= 30,				\
+}
+
+#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
+#define RATETAB_ENT(_rateid, _flags) \
+	{                                                               \
+		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
+		.hw_value       = (_rateid),                            \
+		.flags          = (_flags),                             \
+	}
+
+static struct ieee80211_rate __wl_rates[] = {
+	RATETAB_ENT(DOT11_RATE_1M, 0),
+	RATETAB_ENT(DOT11_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATETAB_ENT(DOT11_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATETAB_ENT(DOT11_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATETAB_ENT(DOT11_RATE_6M, 0),
+	RATETAB_ENT(DOT11_RATE_9M, 0),
+	RATETAB_ENT(DOT11_RATE_12M, 0),
+	RATETAB_ENT(DOT11_RATE_18M, 0),
+	RATETAB_ENT(DOT11_RATE_24M, 0),
+	RATETAB_ENT(DOT11_RATE_36M, 0),
+	RATETAB_ENT(DOT11_RATE_48M, 0),
+	RATETAB_ENT(DOT11_RATE_54M, 0),
+};
+
+#define wl_a_rates		(__wl_rates + 4)
+#define wl_a_rates_size	8
+#define wl_g_rates		(__wl_rates + 0)
+#define wl_g_rates_size	12
+
+static struct ieee80211_channel __wl_2ghz_channels[] = {
+	CHAN2G(1, 2412, 0),
+	CHAN2G(2, 2417, 0),
+	CHAN2G(3, 2422, 0),
+	CHAN2G(4, 2427, 0),
+	CHAN2G(5, 2432, 0),
+	CHAN2G(6, 2437, 0),
+	CHAN2G(7, 2442, 0),
+	CHAN2G(8, 2447, 0),
+	CHAN2G(9, 2452, 0),
+	CHAN2G(10, 2457, 0),
+	CHAN2G(11, 2462, 0),
+	CHAN2G(12, 2467, 0),
+	CHAN2G(13, 2472, 0),
+	CHAN2G(14, 2484, 0),
+};
+
+static struct ieee80211_channel __wl_5ghz_a_channels[] = {
+	CHAN5G(34, 0), CHAN5G(36, 0),
+	CHAN5G(38, 0), CHAN5G(40, 0),
+	CHAN5G(42, 0), CHAN5G(44, 0),
+	CHAN5G(46, 0), CHAN5G(48, 0),
+	CHAN5G(52, 0), CHAN5G(56, 0),
+	CHAN5G(60, 0), CHAN5G(64, 0),
+	CHAN5G(100, 0), CHAN5G(104, 0),
+	CHAN5G(108, 0), CHAN5G(112, 0),
+	CHAN5G(116, 0), CHAN5G(120, 0),
+	CHAN5G(124, 0), CHAN5G(128, 0),
+	CHAN5G(132, 0), CHAN5G(136, 0),
+	CHAN5G(140, 0), CHAN5G(149, 0),
+	CHAN5G(153, 0), CHAN5G(157, 0),
+	CHAN5G(161, 0), CHAN5G(165, 0),
+	CHAN5G(184, 0), CHAN5G(188, 0),
+	CHAN5G(192, 0), CHAN5G(196, 0),
+	CHAN5G(200, 0), CHAN5G(204, 0),
+	CHAN5G(208, 0), CHAN5G(212, 0),
+	CHAN5G(216, 0),
+};
+
+static struct ieee80211_channel __wl_5ghz_n_channels[] = {
+	CHAN5G(32, 0), CHAN5G(34, 0),
+	CHAN5G(36, 0), CHAN5G(38, 0),
+	CHAN5G(40, 0), CHAN5G(42, 0),
+	CHAN5G(44, 0), CHAN5G(46, 0),
+	CHAN5G(48, 0), CHAN5G(50, 0),
+	CHAN5G(52, 0), CHAN5G(54, 0),
+	CHAN5G(56, 0), CHAN5G(58, 0),
+	CHAN5G(60, 0), CHAN5G(62, 0),
+	CHAN5G(64, 0), CHAN5G(66, 0),
+	CHAN5G(68, 0), CHAN5G(70, 0),
+	CHAN5G(72, 0), CHAN5G(74, 0),
+	CHAN5G(76, 0), CHAN5G(78, 0),
+	CHAN5G(80, 0), CHAN5G(82, 0),
+	CHAN5G(84, 0), CHAN5G(86, 0),
+	CHAN5G(88, 0), CHAN5G(90, 0),
+	CHAN5G(92, 0), CHAN5G(94, 0),
+	CHAN5G(96, 0), CHAN5G(98, 0),
+	CHAN5G(100, 0), CHAN5G(102, 0),
+	CHAN5G(104, 0), CHAN5G(106, 0),
+	CHAN5G(108, 0), CHAN5G(110, 0),
+	CHAN5G(112, 0), CHAN5G(114, 0),
+	CHAN5G(116, 0), CHAN5G(118, 0),
+	CHAN5G(120, 0), CHAN5G(122, 0),
+	CHAN5G(124, 0), CHAN5G(126, 0),
+	CHAN5G(128, 0), CHAN5G(130, 0),
+	CHAN5G(132, 0), CHAN5G(134, 0),
+	CHAN5G(136, 0), CHAN5G(138, 0),
+	CHAN5G(140, 0), CHAN5G(142, 0),
+	CHAN5G(144, 0), CHAN5G(145, 0),
+	CHAN5G(146, 0), CHAN5G(147, 0),
+	CHAN5G(148, 0), CHAN5G(149, 0),
+	CHAN5G(150, 0), CHAN5G(151, 0),
+	CHAN5G(152, 0), CHAN5G(153, 0),
+	CHAN5G(154, 0), CHAN5G(155, 0),
+	CHAN5G(156, 0), CHAN5G(157, 0),
+	CHAN5G(158, 0), CHAN5G(159, 0),
+	CHAN5G(160, 0), CHAN5G(161, 0),
+	CHAN5G(162, 0), CHAN5G(163, 0),
+	CHAN5G(164, 0), CHAN5G(165, 0),
+	CHAN5G(166, 0), CHAN5G(168, 0),
+	CHAN5G(170, 0), CHAN5G(172, 0),
+	CHAN5G(174, 0), CHAN5G(176, 0),
+	CHAN5G(178, 0), CHAN5G(180, 0),
+	CHAN5G(182, 0), CHAN5G(184, 0),
+	CHAN5G(186, 0), CHAN5G(188, 0),
+	CHAN5G(190, 0), CHAN5G(192, 0),
+	CHAN5G(194, 0), CHAN5G(196, 0),
+	CHAN5G(198, 0), CHAN5G(200, 0),
+	CHAN5G(202, 0), CHAN5G(204, 0),
+	CHAN5G(206, 0), CHAN5G(208, 0),
+	CHAN5G(210, 0), CHAN5G(212, 0),
+	CHAN5G(214, 0), CHAN5G(216, 0),
+	CHAN5G(218, 0), CHAN5G(220, 0),
+	CHAN5G(222, 0), CHAN5G(224, 0),
+	CHAN5G(226, 0), CHAN5G(228, 0),
+};
+
+static struct ieee80211_supported_band __wl_band_2ghz = {
+	.band = IEEE80211_BAND_2GHZ,
+	.channels = __wl_2ghz_channels,
+	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
+	.bitrates = wl_g_rates,
+	.n_bitrates = wl_g_rates_size,
+};
+
+static struct ieee80211_supported_band __wl_band_5ghz_a = {
+	.band = IEEE80211_BAND_5GHZ,
+	.channels = __wl_5ghz_a_channels,
+	.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
+	.bitrates = wl_a_rates,
+	.n_bitrates = wl_a_rates_size,
+};
+
+static struct ieee80211_supported_band __wl_band_5ghz_n = {
+	.band = IEEE80211_BAND_5GHZ,
+	.channels = __wl_5ghz_n_channels,
+	.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
+	.bitrates = wl_a_rates,
+	.n_bitrates = wl_a_rates_size,
+};
+
+static const u32 __wl_cipher_suites[] = {
+	WLAN_CIPHER_SUITE_WEP40,
+	WLAN_CIPHER_SUITE_WEP104,
+	WLAN_CIPHER_SUITE_TKIP,
+	WLAN_CIPHER_SUITE_CCMP,
+	WLAN_CIPHER_SUITE_AES_CMAC,
+};
+
+static void key_endian_to_device(struct wl_wsec_key *key)
+{
+	key->index = htod32(key->index);
+	key->len = htod32(key->len);
+	key->algo = htod32(key->algo);
+	key->flags = htod32(key->flags);
+	key->rxiv.hi = htod32(key->rxiv.hi);
+	key->rxiv.lo = htod16(key->rxiv.lo);
+	key->iv_initialized = htod32(key->iv_initialized);
+}
+
+static void key_endian_to_host(struct wl_wsec_key *key)
+{
+	key->index = dtoh32(key->index);
+	key->len = dtoh32(key->len);
+	key->algo = dtoh32(key->algo);
+	key->flags = dtoh32(key->flags);
+	key->rxiv.hi = dtoh32(key->rxiv.hi);
+	key->rxiv.lo = dtoh16(key->rxiv.lo);
+	key->iv_initialized = dtoh32(key->iv_initialized);
+}
+
+static s32
+wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
+	struct ifreq ifr;
+	struct wl_ioctl ioc;
+	mm_segment_t fs;
+	s32 err = 0;
+#endif
+
+	BUG_ON(len < sizeof(int));
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
+	memset(&ioc, 0, sizeof(ioc));
+	ioc.cmd = cmd;
+	ioc.buf = arg;
+	ioc.len = len;
+	strcpy(ifr.ifr_name, dev->name);
+	ifr.ifr_data = (caddr_t)&ioc;
+
+	fs = get_fs();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
+	set_fs(KERNEL_DS);
+#else
+	set_fs(get_ds());
+#endif
+#if defined(WL_USE_NETDEV_OPS)
+	err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+#else
+	err = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+#endif
+	set_fs(fs);
+
+	return err;
+#else
+	return wlc_ioctl_internal(dev, cmd, arg, len);
+#endif
+}
+
+static s32
+wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
+                         enum nl80211_iftype type,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+                         u32 *flags,
+#endif
+   struct vif_params *params)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	struct wireless_dev *wdev;
+	s32 infra = 0;
+	s32 ap = 0;
+	s32 err = 0;
+
+	switch (type) {
+	case NL80211_IFTYPE_MONITOR:
+	case NL80211_IFTYPE_WDS:
+		WL_ERR(("type (%d) : currently we do not support this type\n",
+			type));
+		return -EOPNOTSUPP;
+	case NL80211_IFTYPE_ADHOC:
+		wl->conf->mode = WL_MODE_IBSS;
+		break;
+	case NL80211_IFTYPE_STATION:
+		wl->conf->mode = WL_MODE_BSS;
+		infra = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	infra = htod32(infra);
+	ap = htod32(ap);
+	wdev = ndev->ieee80211_ptr;
+	wdev->iftype = type;
+	WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
+	err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
+	if (err) {
+		WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
+		return err;
+	}
+	err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
+	if (err) {
+		WL_ERR(("WLC_SET_AP error (%d)\n", err));
+		return err;
+	}
+
+	return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+static s32
+wl_cfg80211_scan(struct wiphy *wiphy,
+                 struct cfg80211_scan_request *request)
+#else
+static s32
+wl_cfg80211_scan(struct wiphy *wiphy,
+                 struct net_device *ndev,
+                 struct cfg80211_scan_request *request)
+#endif
+
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+	struct net_device *ndev = request->wdev->netdev;
+#endif
+	struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
+	struct cfg80211_ssid *ssids;
+	struct wl_cfg80211_scan_req *sr = wl_to_sr(wl);
+	s32 passive_scan;
+	s32 err = 0;
+
+	if (request) {		
+		ssids = request->ssids;
+	}
+	else {		
+
+		ssids = NULL;
+	}
+	wl->scan_request = request;
+
+	memset(&sr->ssid, 0, sizeof(sr->ssid));
+
+	if (ssids) {
+		WL_DBG(("ssid \"%s\", ssid_len (%d)\n", ssids->ssid, ssids->ssid_len));
+		sr->ssid.SSID_len = min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
+	}
+
+	if (sr->ssid.SSID_len) {
+		memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
+		sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
+		WL_DBG(("Specific scan ssid=\"%s\" len=%d\n", sr->ssid.SSID, sr->ssid.SSID_len));
+	} else {
+		WL_DBG(("Broadcast scan\n"));
+	}
+	WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
+	passive_scan = wl->active_scan ? 0 : 1;
+	err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, &passive_scan, sizeof(passive_scan));
+	if (err) {
+		WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
+		goto scan_out;
+	}
+	err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid, sizeof(sr->ssid));
+	if (err) {
+		if (err == -EBUSY) {
+			WL_INF(("system busy : scan for \"%s\" "
+				"canceled\n", sr->ssid.SSID));
+		} else {
+			WL_ERR(("WLC_SCAN error (%d)\n", err));
+		}
+		goto scan_out;
+	}
+
+	return 0;
+
+scan_out:
+	wl->scan_request = NULL;
+	return err;
+}
+
+static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
+{
+	s8 buf[WLC_IOCTL_SMLEN];
+	u32 len;
+	s32 err = 0;
+
+	val = htod32(val);
+	len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
+	BUG_ON(!len);
+
+	err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
+	if (err) {
+		WL_ERR(("error (%d)\n", err));
+	}
+
+	return err;
+}
+
+static s32
+wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
+{
+	union {
+		s8 buf[WLC_IOCTL_SMLEN];
+		s32 val;
+	} var;
+	u32 len;
+	u32 data_null;
+	s32 err = 0;
+
+	len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf));
+	BUG_ON(!len);
+	err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
+	if (err) {
+		WL_ERR(("error (%d)\n", err));
+	}
+	*retval = dtoh32(var.val);
+
+	return err;
+}
+
+static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
+{
+	s32 err = 0;
+
+	err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
+	if (err) {
+		WL_ERR(("Error (%d)\n", err));
+		return err;
+	}
+	return err;
+}
+
+static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
+{
+	s32 err = 0;
+
+	err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
+	if (err) {
+		WL_ERR(("Error (%d)\n", err));
+		return err;
+	}
+	return err;
+}
+
+static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
+{
+	s32 err = 0;
+	u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
+
+	retry = htod32(retry);
+	err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
+	if (err) {
+		WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
+		return err;
+	}
+	return err;
+}
+
+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	struct net_device *ndev = wl_to_ndev(wl);
+	s32 err = 0;
+
+	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
+	    (wl->conf->rts_threshold != wiphy->rts_threshold)) {
+		wl->conf->rts_threshold = wiphy->rts_threshold;
+		err = wl_set_rts(ndev, wl->conf->rts_threshold);
+		if (!err)
+			return err;
+	}
+	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
+	    (wl->conf->frag_threshold != wiphy->frag_threshold)) {
+		wl->conf->frag_threshold = wiphy->frag_threshold;
+		err = wl_set_frag(ndev, wl->conf->frag_threshold);
+		if (!err)
+			return err;
+	}
+	if (changed & WIPHY_PARAM_RETRY_LONG && (wl->conf->retry_long != wiphy->retry_long)) {
+		wl->conf->retry_long = wiphy->retry_long;
+		err = wl_set_retry(ndev, wl->conf->retry_long, true);
+		if (!err)
+			return err;
+	}
+	if (changed & WIPHY_PARAM_RETRY_SHORT && (wl->conf->retry_short != wiphy->retry_short)) {
+		wl->conf->retry_short = wiphy->retry_short;
+		err = wl_set_retry(ndev, wl->conf->retry_short, false);
+		if (!err) {
+			return err;
+		}
+	}
+
+	return err;
+}
+
+static s32
+wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+                      struct cfg80211_ibss_params *params)
+{
+	struct wl_join_params join_params;
+	size_t join_params_size;
+	s32 val;
+	s32 err = 0;
+
+	WL_DBG(("\n"));
+
+	if (params->bssid) {
+		WL_ERR(("Invalid bssid\n"));
+		return -EOPNOTSUPP;
+	}
+
+	if ((err = wl_dev_intvar_set(dev, "auth", 0))) {
+		return err;
+	}
+	if ((err = wl_dev_intvar_set(dev, "wpa_auth", WPA_AUTH_NONE))) {
+		return err;
+	}
+	if ((err = wl_dev_intvar_get(dev, "wsec", &val))) {
+		return err;
+	}
+	val &= ~(WEP_ENABLED | TKIP_ENABLED | AES_ENABLED);
+	if ((err = wl_dev_intvar_set(dev, "wsec", val))) {
+		return err;
+	}
+
+	memset(&join_params, 0, sizeof(join_params));
+	join_params_size = sizeof(join_params.ssid);
+
+	memcpy((void *)join_params.ssid.SSID, (void *)params->ssid, params->ssid_len);
+	join_params.ssid.SSID_len = htod32(params->ssid_len);
+	if (params->bssid)
+		memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN);
+	else
+		memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+	wl_ch_to_chanspec(params->chandef.chan, &join_params, &join_params_size);
+#else
+	wl_ch_to_chanspec(params->channel, &join_params, &join_params_size);
+#endif
+	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
+	if (err) {
+		WL_ERR(("Error (%d)\n", err));
+		return err;
+	}
+	return err;
+}
+
+static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	s32 err = 0;
+
+	WL_DBG(("\n"));
+
+	wl_link_down(wl);
+
+	return err;
+}
+
+static s32
+wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
+	s32 val = 0;
+	s32 err = 0;
+
+	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
+		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
+	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
+		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+	else
+		val = WPA_AUTH_DISABLED;
+	WL_DBG(("setting wpa_auth to 0x%0x\n", val));
+	err = wl_dev_intvar_set(dev, "wpa_auth", val);
+	if (err) {
+		WL_ERR(("set wpa_auth failed (%d)\n", err));
+		return err;
+	}
+	wl->profile->sec.wpa_versions = sme->crypto.wpa_versions;
+	return err;
+}
+
+static s32
+wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
+	s32 val = 0;
+	s32 err = 0;
+
+	switch (sme->auth_type) {
+	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+		val = 0;
+		WL_DBG(("open system\n"));
+		break;
+	case NL80211_AUTHTYPE_SHARED_KEY:
+		val = 1;
+		WL_DBG(("shared key\n"));
+		break;
+	case NL80211_AUTHTYPE_AUTOMATIC:
+		val = 2;
+		WL_DBG(("automatic\n"));
+		break;
+	case NL80211_AUTHTYPE_NETWORK_EAP:
+		WL_DBG(("network eap\n"));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+		fallthrough;
+#endif
+	default:
+		val = 2;
+		WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
+		break;
+	}
+
+	err = wl_dev_intvar_set(dev, "auth", val);
+	if (err) {
+		WL_ERR(("set auth failed (%d)\n", err));
+		return err;
+	}
+
+	wl->profile->sec.auth_type = sme->auth_type;
+	return err;
+}
+
+static s32
+wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
+	s32 pval = 0;
+	s32 gval = 0;
+	s32 val = 0;
+	s32 err = 0;
+
+	if (sme->crypto.n_ciphers_pairwise) {
+		switch (sme->crypto.ciphers_pairwise[0]) {
+		case WLAN_CIPHER_SUITE_WEP40:
+		case WLAN_CIPHER_SUITE_WEP104:
+			pval = WEP_ENABLED;
+			break;
+		case WLAN_CIPHER_SUITE_TKIP:
+			pval = TKIP_ENABLED;
+			break;
+		case WLAN_CIPHER_SUITE_CCMP:
+			pval = AES_ENABLED;
+			break;
+		case WLAN_CIPHER_SUITE_AES_CMAC:
+			pval = AES_ENABLED;
+			break;
+		default:
+			WL_ERR(("invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]));
+			return -EINVAL;
+		}
+	}
+	if (sme->crypto.cipher_group) {
+		switch (sme->crypto.cipher_group) {
+		case WLAN_CIPHER_SUITE_WEP40:
+		case WLAN_CIPHER_SUITE_WEP104:
+			gval = WEP_ENABLED;
+			break;
+		case WLAN_CIPHER_SUITE_TKIP:
+			gval = TKIP_ENABLED;
+			break;
+		case WLAN_CIPHER_SUITE_CCMP:
+			gval = AES_ENABLED;
+			break;
+		case WLAN_CIPHER_SUITE_AES_CMAC:
+			gval = AES_ENABLED;
+			break;
+		default:
+			WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group));
+			return -EINVAL;
+		}
+	}
+
+	if ((err = wl_dev_intvar_get(dev, "wsec", &val))) {
+		return err;
+	}
+	val &= ~(WEP_ENABLED | TKIP_ENABLED | AES_ENABLED);
+	val |= pval | gval;
+	WL_DBG(("set wsec to %d\n", val));
+	err = wl_dev_intvar_set(dev, "wsec", val);
+	if (err) {
+		WL_ERR(("error (%d)\n", err));
+		return err;
+	}
+
+	wl->profile->sec.cipher_pairwise = sme->crypto.ciphers_pairwise[0];
+	wl->profile->sec.cipher_group = sme->crypto.cipher_group;
+
+	return err;
+}
+
+static s32
+wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
+	s32 val = 0;
+	s32 err = 0;
+
+	if (sme->crypto.n_akm_suites) {
+		err = wl_dev_intvar_get(dev, "wpa_auth", &val);
+		if (err) {
+			WL_ERR(("could not get wpa_auth (%d)\n", err));
+			return err;
+		}
+		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
+			switch (sme->crypto.akm_suites[0]) {
+			case WLAN_AKM_SUITE_8021X:
+				val = WPA_AUTH_UNSPECIFIED;
+				break;
+			case WLAN_AKM_SUITE_PSK:
+				val = WPA_AUTH_PSK;
+				break;
+			default:
+				WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group));
+				return -EINVAL;
+			}
+		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
+			switch (sme->crypto.akm_suites[0]) {
+			case WLAN_AKM_SUITE_8021X:
+				val = WPA2_AUTH_UNSPECIFIED;
+				break;
+			case WLAN_AKM_SUITE_PSK:
+				val = WPA2_AUTH_PSK;
+				break;
+			default:
+				WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group));
+				return -EINVAL;
+			}
+		}
+
+		WL_DBG(("setting wpa_auth to %d\n", val));
+		err = wl_dev_intvar_set(dev, "wpa_auth", val);
+		if (err) {
+			WL_ERR(("could not set wpa_auth (%d)\n", err));
+			return err;
+		}
+	}
+
+	wl->profile->sec.wpa_auth = sme->crypto.akm_suites[0];
+
+	return err;
+}
+
+static s32
+wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
+	struct wl_cfg80211_security *sec;
+	struct wl_wsec_key key;
+	s32 err = 0;
+
+	WL_DBG(("key len (%d)\n", sme->key_len));
+	if (sme->key_len) {
+		sec = &wl->profile->sec;
+		WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
+		         sec->wpa_versions, sec->cipher_pairwise));
+		if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) &&
+		     (sec->cipher_pairwise &
+		     (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104))) {
+			memset(&key, 0, sizeof(key));
+			key.len = (u32) sme->key_len;
+			key.index = (u32) sme->key_idx;
+			if (key.len > sizeof(key.data)) {
+				WL_ERR(("Too long key length (%u)\n", key.len));
+				return -EINVAL;
+			}
+			memcpy(key.data, sme->key, key.len);
+			key.flags = WL_PRIMARY_KEY;
+			switch (sec->cipher_pairwise) {
+			case WLAN_CIPHER_SUITE_WEP40:
+				key.algo = CRYPTO_ALGO_WEP1;
+				break;
+			case WLAN_CIPHER_SUITE_WEP104:
+				key.algo = CRYPTO_ALGO_WEP128;
+				break;
+			default:
+				WL_ERR(("Invalid algorithm (%d)\n",
+				        sme->crypto.ciphers_pairwise[0]));
+				return -EINVAL;
+			}
+
+			WL_DBG(("key length (%d) key index (%d) algo (%d)\n", key.len,
+				key.index, key.algo));
+			WL_DBG(("key \"%s\"\n", key.data));
+			key_endian_to_device(&key);
+			err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+			if (err) {
+				WL_ERR(("WLC_SET_KEY error (%d)\n", err));
+				return err;
+			}
+		}
+	}
+	return err;
+}
+
+static s32
+wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+                    struct cfg80211_connect_params *sme)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	struct wl_join_params join_params;
+	size_t join_params_size;
+	char valc;
+	s32 err = 0;
+
+	if (!sme->ssid) {
+		WL_ERR(("Invalid ssid\n"));
+		return -EOPNOTSUPP;
+	}
+
+	WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
+
+	err = wl_set_auth_type(dev, sme);
+	if (err)
+		return err;
+
+	err = wl_set_wpa_version(dev, sme);
+	if (err)
+		return err;
+
+	err = wl_set_set_cipher(dev, sme);
+	if (err)
+		return err;
+
+	err = wl_set_key_mgmt(dev, sme);
+	if (err)
+		return err;
+
+	err = wl_set_set_sharedkey(dev, sme);
+	if (err)
+		return err;
+
+	valc = 1;
+	wl_dev_bufvar_set(dev, "wsec_restrict", &valc, 1);
+
+	if (sme->bssid) {
+		memcpy(wl->profile->bssid, sme->bssid, ETHER_ADDR_LEN);
+	}
+	else {
+		memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
+	}
+
+	memset(&join_params, 0, sizeof(join_params));
+	join_params_size = sizeof(join_params.ssid);
+
+	join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
+	memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
+	join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
+	memcpy(&join_params.params.bssid, &ether_bcast, ETHER_ADDR_LEN);
+
+	memcpy(wl->profile->ssid.SSID, &join_params.ssid.SSID, join_params.ssid.SSID_len);
+	wl->profile->ssid.SSID_len = join_params.ssid.SSID_len;
+
+	wl_ch_to_chanspec(sme->channel, &join_params, &join_params_size);
+	WL_DBG(("join_param_size %u\n", (unsigned int)join_params_size));
+
+	if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
+		WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
+		        join_params.ssid.SSID_len));
+	}
+	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
+	if (err) {
+		WL_ERR(("error (%d)\n", err));
+		return err;
+	}
+
+	set_bit(WL_STATUS_CONNECTING, &wl->status);
+
+	return err;
+}
+
+static s32
+wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	scb_val_t scbval;
+	s32 err = 0;
+
+	WL_DBG(("Reason %d\n", reason_code));
+
+	if (wl->profile->active) {
+		scbval.val = reason_code;
+		memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
+		scbval.val = htod32(scbval.val);
+		err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t));
+		if (err) {
+			WL_ERR(("error (%d)\n", err));
+			return err;
+		}
+	}
+
+	return err;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+static s32
+wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+                         enum nl80211_tx_power_setting type, s32 dbm)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+static s32
+wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, s32 dbm)
+#else
+#define NL80211_TX_POWER_AUTOMATIC TX_POWER_AUTOMATIC
+#define NL80211_TX_POWER_LIMITED TX_POWER_LIMITED
+#define NL80211_TX_POWER_FIXED TX_POWER_FIXED
+static s32
+wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, s32 dbm)
+#endif
+{
+
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	struct net_device *ndev = wl_to_ndev(wl);
+	u16 txpwrmw;
+	s32 err = 0;
+	s32 disable = 0;
+
+	switch (type) {
+	case NL80211_TX_POWER_AUTOMATIC:
+		break;
+	case NL80211_TX_POWER_LIMITED:
+		if (dbm < 0) {
+			WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
+			return -EINVAL;
+		}
+		break;
+	case NL80211_TX_POWER_FIXED:
+		if (dbm < 0) {
+			WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
+			return -EINVAL;
+		}
+		break;
+	}
+
+	disable = WL_RADIO_SW_DISABLE << 16;
+	disable = htod32(disable);
+	err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
+	if (err) {
+		WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
+		return err;
+	}
+
+	if (dbm > 0xffff)
+		txpwrmw = 0xffff;
+	else
+		txpwrmw = (u16) dbm;
+	err = wl_dev_intvar_set(ndev, "qtxpower", (s32) (bcm_mw_to_qdbm(txpwrmw)));
+	if (err) {
+		WL_ERR(("qtxpower error (%d)\n", err));
+		return err;
+	}
+	wl->conf->tx_power = dbm;
+
+	return err;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, s32 *dbm)
+#else
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
+#endif
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	struct net_device *ndev = wl_to_ndev(wl);
+	s32 txpwrdbm;
+	u8 result;
+	s32 err = 0;
+
+	err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
+	if (err) {
+		WL_ERR(("error (%d)\n", err));
+		return err;
+	}
+	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
+	*dbm = (s32) bcm_qdbm_to_mw(result);
+
+	return err;
+}
+
+static s32
+wl_cfg80211_config_default_key(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+	struct net_device *dev, int link_id, u8 key_idx, bool unicast, bool multicast)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+	struct net_device *dev, u8 key_idx, bool unicast, bool multicast)
+#else
+	struct net_device *dev, u8 key_idx)
+#endif
+{
+	u32 index;
+	s32 err = 0;
+
+	WL_DBG(("key index (%d)\n", key_idx));
+
+	index = (u32) key_idx;
+	index = htod32(index);
+	err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, sizeof(index));
+	if (err) {
+		WL_DBG(("error (%d)\n", err));
+	}
+
+	return 0;
+}
+
+static s32
+wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+                    int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+                    u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params)
+#else
+                    u8 key_idx, const u8 *mac_addr, struct key_params *params)
+#endif
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
+	struct wl_wsec_key key;
+	s32 secval, secnew = 0;
+	s32 err = 0;
+
+	WL_DBG(("key index %u    len %u\n", (unsigned)key_idx, params->key_len));
+
+	memset(&key, 0, sizeof(key));
+
+	key.index = (u32) key_idx;
+
+	switch (params->cipher) {
+	case WLAN_CIPHER_SUITE_WEP40:
+		key.algo = CRYPTO_ALGO_WEP1;
+		secnew = WEP_ENABLED;
+		WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
+		break;
+	case WLAN_CIPHER_SUITE_WEP104:
+		key.algo = CRYPTO_ALGO_WEP128;
+		secnew = WEP_ENABLED;
+		WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+		key.algo = CRYPTO_ALGO_TKIP;
+		secnew = TKIP_ENABLED;
+		WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
+		break;
+	case WLAN_CIPHER_SUITE_AES_CMAC:
+		key.algo = CRYPTO_ALGO_AES_CCM;
+		secnew = AES_ENABLED;
+		WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
+		break;
+	case WLAN_CIPHER_SUITE_CCMP:
+		key.algo = CRYPTO_ALGO_AES_CCM;
+		secnew = AES_ENABLED;
+		WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
+		break;
+	default:
+		WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
+		return -EINVAL;
+	}
+
+	if (mac_addr) {
+		if (!ETHER_ISMULTI(mac_addr)) {
+			memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
+		}
+	}
+
+	key.len = (u32) params->key_len;
+	if (key.len > sizeof(key.data)) {
+		WL_ERR(("Too long key length (%u)\n", key.len));
+		return -EINVAL;
+	}
+	memcpy(key.data, params->key, key.len);
+
+	if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
+		u8 keybuf[8];
+		memcpy(keybuf, &key.data[24], sizeof(keybuf));
+		memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+		memcpy(&key.data[16], keybuf, sizeof(keybuf));
+	}
+
+	if (params->seq_len) { 
+		u8 *ivptr;
+		if (params->seq_len != 6) {
+			WL_ERR(("seq_len %d is unexpected, check implementation.\n",
+				params->seq_len));
+		}
+		ivptr = (u8 *) params->seq;
+		key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | (ivptr[3] << 8) | ivptr[2];
+		key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
+		key.iv_initialized = true;
+	}
+
+	key_endian_to_device(&key);
+	if (wl->passive) {
+		schedule();
+	}
+	err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+	if (err) {
+		WL_ERR(("WLC_SET_KEY error (%d)\n", err));
+		return err;
+	}
+
+	if ((err = wl_dev_intvar_get(dev, "wsec", &secval))) {
+		return err;
+	}
+	if (secnew == WEP_ENABLED) {
+		secval &= ~(TKIP_ENABLED | AES_ENABLED);
+	}
+	else {
+		secval &= ~(WEP_ENABLED);
+	}
+	secval |= secnew;
+	WL_DBG(("set wsec to %d\n", secval));
+	err = wl_dev_intvar_set(dev, "wsec", secval);
+	if (err) {
+		WL_ERR(("error (%d)\n", err));
+		return err;
+	}
+
+	if (mac_addr) {
+		wl->profile->sec.cipher_pairwise = params->cipher;
+	}
+	else {
+		wl->profile->sec.cipher_group = params->cipher;
+	}
+
+	return err;
+}
+static s32
+wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+                    int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+                    u8 key_idx, bool pairwise, const u8 *mac_addr)
+#else
+                    u8 key_idx, const u8 *mac_addr)
+#endif
+{
+	struct wl_wsec_key key;
+	s32 err = 0;
+
+	WL_DBG(("key index (%d)\n", key_idx));
+
+	memset(&key, 0, sizeof(key));
+
+	key.index = (u32) key_idx;
+	key.len = 0;
+	if (mac_addr) {
+		if (!ETHER_ISMULTI(mac_addr)) {
+			memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
+		}
+	}
+	key.algo = CRYPTO_ALGO_OFF;
+
+	key_endian_to_device(&key);
+	err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+	if (err) {
+		if (err == -EINVAL) {
+			if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
+
+				WL_DBG(("invalid key index (%d)\n", key_idx));
+			}
+		} else {
+			WL_ERR(("WLC_SET_KEY error (%d)\n", err));
+		}
+		return err;
+	}
+
+	return err;
+}
+
+static s32
+wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+                    int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+                    u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
+#else
+                    u8 key_idx, const u8 *mac_addr, void *cookie,
+#endif
+                    void (*callback) (void *cookie, struct key_params * params))
+{
+	struct key_params params;
+	struct wl_wsec_key key;
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	struct wl_cfg80211_security *sec;
+	s32 wsec;
+	s32 err = 0;
+
+	WL_DBG(("key index (%d)\n", key_idx));
+
+	memset(&params, 0, sizeof(params));
+
+	memset(&key, 0, sizeof(key));
+	key.index = key_idx;
+	key_endian_to_device(&key);
+
+	if ((err = wl_dev_ioctl(dev, WLC_GET_KEY, &key, sizeof(key)))) {
+		return err;
+	}
+	key_endian_to_host(&key);
+
+	params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
+	memcpy((char *)params.key, key.data, params.key_len);
+
+	if ((err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
+		return err;
+	}
+	wsec = dtoh32(wsec);
+	switch (wsec) {
+	case WEP_ENABLED:
+		sec = &wl->profile->sec;
+		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
+			params.cipher = WLAN_CIPHER_SUITE_WEP40;
+			WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
+		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
+			params.cipher = WLAN_CIPHER_SUITE_WEP104;
+			WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
+		}
+		break;
+	case TKIP_ENABLED:
+		params.cipher = WLAN_CIPHER_SUITE_TKIP;
+		WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
+		break;
+	case AES_ENABLED:
+		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+		WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
+		break;
+	default:
+		WL_ERR(("Invalid algo (0x%x)\n", wsec));
+		return -EINVAL;
+	}
+
+	callback(cookie, &params);
+	return err;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
+static s32
+wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+                        u8 *mac, struct station_info *sinfo)
+#else
+static s32
+wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+                        const u8 *mac, struct station_info *sinfo)
+#endif
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	scb_val_t scb_val;
+	int rssi;
+	s32 rate;
+	s32 err = 0;
+
+	if (memcmp(mac, wl->profile->bssid, ETHER_ADDR_LEN)) {
+		WL_ERR(("Wrong Mac address, mac = %pM   profile =%pM\n", mac, wl->profile->bssid));
+		return -ENOENT;
+	}
+
+	err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
+	if (err) {
+		WL_DBG(("Could not get rate (%d)\n", err));
+	} else {
+		rate = dtoh32(rate);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
+		sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
+#else
+		sinfo->filled |= STATION_INFO_TX_BITRATE;
+#endif
+		sinfo->txrate.legacy = rate * 5;
+		WL_DBG(("Rate %d Mbps\n", (rate / 2)));
+	}
+
+	if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
+		memset(&scb_val, 0, sizeof(scb_val));
+		err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t));
+		if (err) {
+			WL_DBG(("Could not get rssi (%d)\n", err));
+			return err;
+		}
+		rssi = dtoh32(scb_val.val);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
+		sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+#else
+		sinfo->filled |= STATION_INFO_SIGNAL;
+#endif
+		sinfo->signal = rssi;
+		WL_DBG(("RSSI %d dBm\n", rssi));
+	}
+
+	return err;
+}
+
+static s32
+wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+                           bool enabled, s32 timeout)
+{
+	s32 pm;
+	s32 err = 0;
+
+	pm = enabled ? PM_FAST : PM_OFF;
+	pm = htod32(pm);
+	WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
+	err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+	if (err) {
+		if (err == -ENODEV)
+			WL_DBG(("net_device is not ready yet\n"));
+		else
+			WL_ERR(("error (%d)\n", err));
+		return err;
+	}
+	return err;
+}
+
+static __used s32
+wl_update_pmklist(struct net_device *dev, struct wl_cfg80211_pmk_list *pmk_list, s32 err)
+{
+	int i, j;
+
+	WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
+	for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
+		WL_DBG(("PMKID[%d]: %pM =\n", i,
+			&pmk_list->pmkids.pmkid[i].BSSID));
+		for (j = 0; j < WPA2_PMKID_LEN; j++) {
+			WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
+		}
+	}
+	if (!err) {
+		err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list, sizeof(*pmk_list));
+	}
+
+	return err;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+
+static s32
+wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
+                      struct cfg80211_pmksa *pmksa)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	s32 err = 0;
+	int i;
+
+	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
+		if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN))
+			break;
+	if (i < WL_NUM_PMKIDS_MAX) {
+		memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
+		memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
+		if (i == wl->pmk_list->pmkids.npmkid)
+			wl->pmk_list->pmkids.npmkid++;
+	} else {
+		err = -EINVAL;
+	}
+	WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
+		&wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
+	for (i = 0; i < WPA2_PMKID_LEN; i++) {
+		WL_DBG(("%02x\n",
+			wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].PMKID[i]));
+	}
+
+	err = wl_update_pmklist(dev, wl->pmk_list, err);
+
+	return err;
+}
+
+static s32
+wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
+                      struct cfg80211_pmksa *pmksa)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	struct _pmkid_list pmkid;
+	s32 err = 0;
+	int i;
+
+	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
+	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
+
+	WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
+		&pmkid.pmkid[0].BSSID));
+	for (i = 0; i < WPA2_PMKID_LEN; i++) {
+		WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
+	}
+
+	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
+		if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN))
+			break;
+
+	if ((wl->pmk_list->pmkids.npmkid > 0) && (i < wl->pmk_list->pmkids.npmkid)) {
+		memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
+		for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
+			memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
+			       &wl->pmk_list->pmkids.pmkid[i + 1].BSSID, ETHER_ADDR_LEN);
+			memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
+			       &wl->pmk_list->pmkids.pmkid[i + 1].PMKID, WPA2_PMKID_LEN);
+		}
+		wl->pmk_list->pmkids.npmkid--;
+	} else {
+		err = -EINVAL;
+	}
+
+	err = wl_update_pmklist(dev, wl->pmk_list, err);
+
+	return err;
+
+}
+
+static s32
+wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	s32 err = 0;
+
+	memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
+	err = wl_update_pmklist(dev, wl->pmk_list, err);
+	return err;
+
+}
+
+#endif  
+
+#ifdef CONFIG_PM
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+
+static int
+wl_wowl_ind_wake_reason(struct wl_cfg80211_priv *wl, struct cfg80211_wowlan_wakeup *wakeup)
+{
+	wl_wowl_wakeind_t wowl_ind;
+	s32 err;
+
+	err = wl_dev_bufvar_get(wl_to_ndev(wl), "wowl_wakeind",
+		(s8 *)&wowl_ind, sizeof(wowl_ind));
+	if (err != 0) {
+		WL_ERR(("Unable to get wake reason, err = %d\n", err));
+		return -1;
+	}
+
+	if (wowl_ind.ucode_wakeind == 0) {
+		WL_DBG(("System woke, but not by us\n"));
+		return 0;
+	}
+	WL_DBG(("wake reason is 0x%x\n", wowl_ind.ucode_wakeind));
+
+	if (wowl_ind.ucode_wakeind & WL_WOWL_MAGIC) {
+		WL_ERR(("WOWLAN Woke for: Magic Pkt\n"));
+		wakeup->magic_pkt = true;
+	}
+	if (wowl_ind.ucode_wakeind & WL_WOWL_DIS) {
+		WL_ERR(("WOWLAN Woke for: Disconnect\n"));
+		wakeup->disconnect = true;
+	}
+	if (wowl_ind.ucode_wakeind & WL_WOWL_BCN) {
+		WL_ERR(("WOWLAN Woke for: Beacon Loss\n"));
+		wakeup->disconnect = true;
+	}
+	if (wowl_ind.ucode_wakeind & WL_WOWL_GTK_FAILURE) {
+		WL_ERR(("WOWLAN Woke for: GTK failure\n"));
+		wakeup->gtk_rekey_failure = true;
+	}
+	if (wowl_ind.ucode_wakeind & WL_WOWL_EAPID) {
+		WL_ERR(("WOWLAN Woke for: EAP identify request\n"));
+		wakeup->eap_identity_req = true;
+	}
+	if (wowl_ind.ucode_wakeind & WL_WOWL_M1) {
+		WL_ERR(("WOWLAN Woke for: 4-way handshake request\n"));
+		wakeup->four_way_handshake = true;
+	}
+	return 1;
+}
+#endif 
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
+static int
+wl_cfg80211_rekey(struct wiphy *wiphy, struct net_device *ndev,
+        struct cfg80211_gtk_rekey_data *data)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	wlc_rekey_info_t rekey;
+	s32 err;
+
+	if (!wl->offloads) {
+		return 0;
+	}
+
+	memset(&rekey, 0, sizeof(rekey));
+	memcpy(&rekey.kek, data->kek, WLC_KEK_LEN);
+	memcpy(&rekey.kck, data->kck, WLC_KCK_LEN);
+	memcpy(&rekey.replay_counter, data->replay_ctr, WLC_REPLAY_CTR_LEN);
+	WL_INF(("Send down replay counter %x%x%x%x%x%x%x%x\n",
+		rekey.replay_counter[0], rekey.replay_counter[1], rekey.replay_counter[2],
+		rekey.replay_counter[3], rekey.replay_counter[4], rekey.replay_counter[5],
+		rekey.replay_counter[6], rekey.replay_counter[7]));
+
+	err = wl_dev_bufvar_set(wl_to_ndev(wl), "wowl_replay", (s8 *)&rekey, sizeof(rekey));
+	if (err) {
+		WL_ERR(("Error calling wowl_set_key\n"));
+		return err;
+	}
+	return err;
+}
+#endif 
+
+static int wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wowlan)
+{
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	uint wowl = 0;
+	s32 err;
+
+	if (!wowlan) {
+		WL_DBG(("No wowlan requested\n"));
+		return 0;
+	}
+	if (!test_bit(WL_STATUS_CONNECTED, &wl->status)) {
+		WL_INF(("No wowl when not associated.\n"));
+		return 0;
+	}
+
+	err = wl_dev_intvar_get(wl_to_ndev(wl), "wowl", &wowl);
+	if (err) {
+		WL_ERR(("Error fetching WOWL %d\n", err));
+	}
+	if (wowlan->disconnect) {
+		WL_INF(("Requesting wake on Disconnect\n"));
+		wowl |= WL_WOWL_DIS | WL_WOWL_BCN;
+	}
+	if (wowlan->magic_pkt) {
+		WL_INF(("Requesting wake on Magic Pkt\n"));
+		wowl |= WL_WOWL_MAGIC;
+	}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
+	if (wowlan->gtk_rekey_failure) {
+		WL_INF(("Requesting wake GTK rekey failure Pkt\n"));
+		wowl |= WL_WOWL_GTK_FAILURE;
+	}
+	if (wowlan->four_way_handshake) {
+		WL_INF(("Requesting wake on 4way handshake request\n"));
+		wowl |= WL_WOWL_M1;
+	}
+#endif 
+
+	wowl |= WL_WOWL_KEYROT;
+
+	err = wl_dev_intvar_set(wl_to_ndev(wl), "wowl", wowl);
+	if (err) {
+		WL_ERR(("Error enabling WOWL %d\n", err));
+	}
+
+	return err;
+}
+#else 
+static int wl_cfg80211_suspend(struct wiphy *wiphy)
+{
+	return 0;
+}
+#endif 
+
+static int wl_cfg80211_resume(struct wiphy *wiphy)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
+	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+	wlc_rekey_info_t *rekey = (wlc_rekey_info_t *)wl->extra_buf;
+	s32 err;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+	struct cfg80211_wowlan_wakeup wakeup;
+	int result;
+
+	memset(&wakeup, 0, sizeof(wakeup));
+	wakeup.pattern_idx = -1;
+
+	result = wl_wowl_ind_wake_reason(wl, &wakeup);
+	switch (result) {
+		case -1: 
+			break;
+		case 0:	
+			cfg80211_report_wowlan_wakeup(wl_to_wdev(wl), NULL, GFP_KERNEL);
+			break;
+		case 1: 
+			cfg80211_report_wowlan_wakeup(wl_to_wdev(wl), &wakeup, GFP_KERNEL);
+			break;
+	}
+#endif 
+
+	err = wl_dev_bufvar_get(wl_to_ndev(wl), "wowl_replay", (s8 *)rekey,
+		sizeof(wlc_rekey_info_t));
+	if (!err) {
+		WL_INF(("Send up replay counter %x%x%x%x%x%x%x%x\n",
+			rekey->replay_counter[0], rekey->replay_counter[1],
+			rekey->replay_counter[2], rekey->replay_counter[3],
+			rekey->replay_counter[4], rekey->replay_counter[5],
+			rekey->replay_counter[6], rekey->replay_counter[7]));
+		cfg80211_gtk_rekey_notify(wl_to_ndev(wl), (u8 *)&wl->bssid.octet,
+			rekey->replay_counter, GFP_KERNEL);
+	}
+#endif 
+	return 0;
+}
+#endif 
+
+static struct cfg80211_ops wl_cfg80211_ops = {
+	.change_virtual_intf = wl_cfg80211_change_iface,
+	.scan = wl_cfg80211_scan,
+	.set_wiphy_params = wl_cfg80211_set_wiphy_params,
+	.join_ibss = wl_cfg80211_join_ibss,
+	.leave_ibss = wl_cfg80211_leave_ibss,
+	.get_station = wl_cfg80211_get_station,
+	.set_tx_power = wl_cfg80211_set_tx_power,
+	.get_tx_power = wl_cfg80211_get_tx_power,
+	.add_key = wl_cfg80211_add_key,
+	.del_key = wl_cfg80211_del_key,
+	.get_key = wl_cfg80211_get_key,
+	.set_default_key = wl_cfg80211_config_default_key,
+	.set_power_mgmt = wl_cfg80211_set_power_mgmt,
+	.connect = wl_cfg80211_connect,
+	.disconnect = wl_cfg80211_disconnect,
+#ifdef CONFIG_PM
+	.suspend = wl_cfg80211_suspend,
+	.resume = wl_cfg80211_resume,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
+	.set_rekey_data = wl_cfg80211_rekey,
+#endif 
+#endif 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+	.set_pmksa = wl_cfg80211_set_pmksa,
+	.del_pmksa = wl_cfg80211_del_pmksa,
+	.flush_pmksa = wl_cfg80211_flush_pmksa
+#endif
+};
+
+#ifdef CONFIG_PM
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+static const struct wiphy_wowlan_support wl_wowlan_support = {
+#else
+static struct wiphy_wowlan_support wl_wowlan_support = {
+#endif 
+	.flags = WIPHY_WOWLAN_MAGIC_PKT
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
+	| WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_GTK_REKEY_FAILURE |
+	WIPHY_WOWLAN_EAP_IDENTITY_REQ
+#endif
+	| WIPHY_WOWLAN_DISCONNECT,
+};
+#endif 
+#endif 
+
+static s32 wl_mode_to_nl80211_iftype(s32 mode)
+{
+	s32 err = 0;
+
+	switch (mode) {
+	case WL_MODE_BSS:
+		return NL80211_IFTYPE_STATION;
+	case WL_MODE_IBSS:
+		return NL80211_IFTYPE_ADHOC;
+	default:
+		return NL80211_IFTYPE_UNSPECIFIED;
+	}
+
+	return err;
+}
+
+static s32 wl_alloc_wdev(struct device *dev, struct wireless_dev **rwdev)
+{
+	struct wireless_dev *wdev;
+	s32 err = 0;
+
+	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+	if (!wdev) {
+		WL_ERR(("Could not allocate wireless device\n"));
+		err = -ENOMEM;
+		goto early_out;
+	}
+	wdev->wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_cfg80211_priv));
+	if (!wdev->wiphy) {
+		WL_ERR(("Couldn not allocate wiphy device\n"));
+		err = -ENOMEM;
+		goto wiphy_new_out;
+	}
+	set_wiphy_dev(wdev->wiphy, dev);
+	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
+#endif
+	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
+	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; 
+	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+	wdev->wiphy->cipher_suites = __wl_cipher_suites;
+	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+
+	wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+#endif
+
+#ifdef CONFIG_PM
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+	wdev->wiphy->wowlan = &wl_wowlan_support;
+#else
+	wdev->wiphy->wowlan = wl_wowlan_support;
+#endif 
+#endif 
+#endif 
+
+	err = wiphy_register(wdev->wiphy);
+	if (err < 0) {
+		WL_ERR(("Couldn not register wiphy device (%d)\n", err));
+		goto wiphy_register_out;
+	}
+
+	*rwdev = wdev;
+	return err;
+
+wiphy_register_out:
+	wiphy_free(wdev->wiphy);
+
+wiphy_new_out:
+	kfree(wdev);
+
+early_out:
+	*rwdev = wdev;
+	return err;
+}
+
+static void wl_free_wdev(struct wl_cfg80211_priv *wl)
+{
+	struct wireless_dev *wdev = wl_to_wdev(wl);
+
+	if (!wdev) {
+		WL_ERR(("wdev is invalid\n"));
+		return;
+	}
+	wiphy_unregister(wdev->wiphy);
+	wiphy_free(wdev->wiphy);
+	kfree(wdev);
+	wl_to_wdev(wl) = NULL;
+}
+
+static s32 wl_inform_bss(struct wl_cfg80211_priv *wl, struct wl_scan_results *bss_list)
+{
+	struct wl_bss_info *bi = NULL;	
+	s32 err = 0;
+	int i;
+
+	if (bss_list->version != WL_BSS_INFO_VERSION) {
+		WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n", bss_list->version));
+		return -EOPNOTSUPP;
+	}
+	WL_DBG(("scanned AP count (%d)\n", bss_list->count));
+	bi = next_bss(bss_list, bi);
+	for_each_bss(bss_list, bi, i) {
+		err = wl_inform_single_bss(wl, bi);
+		if (err)
+			break;
+	}
+	return err;
+}
+
+static s32 wl_inform_single_bss(struct wl_cfg80211_priv *wl, struct wl_bss_info *bi)
+{
+	struct wiphy *wiphy = wl_to_wiphy(wl);
+	struct ieee80211_mgmt *mgmt;
+	struct ieee80211_channel *channel;
+	struct wl_cfg80211_bss_info *notif_bss_info;
+	struct wl_cfg80211_scan_req *sr = wl_to_sr(wl);
+	struct beacon_proberesp *beacon_proberesp;
+	struct cfg80211_bss *cbss = NULL;
+	s32 mgmt_type;
+	u32 signal;
+	u32 freq;
+	s32 err = 0;
+	u8 *notify_ie;
+	size_t notify_ielen;
+
+	if (dtoh32(bi->length) > WL_BSS_INFO_MAX) {
+		WL_DBG(("Beacon is larger than buffer. Discarding\n"));
+		return -E2BIG;
+	}
+	notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
+	                         WL_BSS_INFO_MAX, GFP_KERNEL);
+	if (!notif_bss_info) {
+		WL_ERR(("notif_bss_info alloc failed\n"));
+		return -ENOMEM;
+	}
+	mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
+	notif_bss_info->channel = bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
+
+	notif_bss_info->rssi = bi->RSSI;
+	memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
+	mgmt_type = wl->active_scan ?	IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
+	if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
+		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type);
+	}
+	beacon_proberesp = wl->active_scan ? (struct beacon_proberesp *)&mgmt->u.probe_resp :
+	                   (struct beacon_proberesp *)&mgmt->u.beacon;
+	beacon_proberesp->timestamp = 0;
+	beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
+	beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
+	wl_rst_ie(wl);
+
+	err = wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
+	if (err)
+		goto inform_single_bss_out;
+
+	err = wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
+	         offsetof(struct wl_cfg80211_bss_info, frame_buf));
+	if (err)
+		goto inform_single_bss_out;
+
+	notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.beacon.variable) +
+	                            wl_get_ielen(wl);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+	freq = ieee80211_channel_to_frequency(notif_bss_info->channel,
+		(notif_bss_info->channel <= CH_MAX_2G_CHANNEL) ?
+		IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
+#else
+	freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
+#endif
+	if (freq == 0) {
+		WL_ERR(("Invalid channel, fail to chcnage channel to freq\n"));
+		err = -EINVAL;
+		goto inform_single_bss_out;
+	}
+	channel = ieee80211_get_channel(wiphy, freq);
+	if (unlikely(!channel)) {
+		WL_ERR(("ieee80211_get_channel error\n"));
+		err = -EINVAL;
+		goto inform_single_bss_out;
+	}
+
+	WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
+		bi->SSID, notif_bss_info->rssi, notif_bss_info->channel,
+		mgmt->u.beacon.capab_info, &bi->BSSID));
+
+	signal = notif_bss_info->rssi * 100;
+
+	if (!wl->scan_request) {
+	cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+	    le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
+	if (unlikely(!cbss)) {
+		WL_ERR(("cfg80211_inform_bss_frame error\n"));
+			err = -ENOMEM;
+			goto inform_single_bss_out;
+	}
+	} else {
+	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+	notify_ielen = le32_to_cpu(bi->ie_length);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
+	cbss = cfg80211_inform_bss(wiphy, channel, (const u8 *)(bi->BSSID.octet),
+		0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int,
+		(const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
+#else
+		cbss = cfg80211_inform_bss(wiphy, channel,
+				wl->active_scan ?
+				CFG80211_BSS_FTYPE_PRESP : CFG80211_BSS_FTYPE_BEACON,
+				(const u8 *)(bi->BSSID.octet), 0,
+				beacon_proberesp->capab_info,
+				beacon_proberesp->beacon_int,
+		(const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
+#endif
+		if (unlikely(!cbss)) {
+			WL_ERR(("cfg80211_inform_bss error\n"));
+			err = -ENOMEM;
+			goto inform_single_bss_out;
+		}
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+	cfg80211_put_bss(wiphy, cbss);
+#else
+	cfg80211_put_bss(cbss);
+#endif
+
+inform_single_bss_out:
+	kfree(notif_bss_info);
+
+	return err;
+}
+
+static s32
+wl_notify_connect_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+                         const wl_event_msg_t *e, void *data)
+{
+	s32 err = 0;
+	u32 event = EVENT_TYPE(e);
+	u16 flags = EVENT_FLAGS(e);
+	u32 status = EVENT_STATUS(e);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
+	struct ieee80211_channel *channel = NULL;
+	struct wiphy *wiphy;
+	u32 chanspec, chan;
+	u32 freq, band;
+#endif 
+
+	WL_DBG(("\n"));
+
+	if (!wl_is_ibssmode(wl)) {
+		if (event == WLC_E_LINK && (flags & WLC_EVENT_MSG_LINK)) {
+			wl_link_up(wl);
+			wl_bss_connect_done(wl, ndev, e, data, true);
+			wl->profile->active = true;
+		}
+		else if ((event == WLC_E_LINK && ~(flags & WLC_EVENT_MSG_LINK)) ||
+			event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0)
+			cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
+#else
+			cfg80211_disconnected(ndev, 0, NULL, 0, false, GFP_KERNEL);
+#endif
+			clear_bit(WL_STATUS_CONNECTED, &wl->status);
+			wl_link_down(wl);
+			wl_init_prof(wl->profile);
+		}
+		else if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_NO_NETWORKS) {
+			wl_bss_connect_done(wl, ndev, e, data, false);
+		}
+		else {
+			WL_DBG(("no action (BSS mode)\n"));
+		}
+	}
+	else {
+		if (event == WLC_E_JOIN) {
+			WL_DBG(("joined in IBSS network\n"));
+		}
+		if (event == WLC_E_START) {
+			WL_DBG(("started IBSS network\n"));
+		}
+		if (event == WLC_E_JOIN || event == WLC_E_START) {
+			wl_link_up(wl);
+			wl_get_assoc_ies(wl);
+			memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
+			wl_update_bss_info(wl);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
+			wiphy = wl_to_wiphy(wl);
+			err = wl_dev_intvar_get(ndev, "chanspec", &chanspec);
+			if (err) {
+				WL_ERR(("Could not get chanspec, err %d\n", err));
+				return err;
+			}
+			chan = wf_chspec_ctlchan(chanspec);
+			band = (chan <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+			freq = ieee80211_channel_to_frequency(chan, band);
+			channel = ieee80211_get_channel(wiphy, freq);
+			cfg80211_ibss_joined(ndev, (u8 *)&wl->bssid, channel, GFP_KERNEL);
+#else
+			cfg80211_ibss_joined(ndev, (u8 *)&wl->bssid, GFP_KERNEL);
+#endif
+			set_bit(WL_STATUS_CONNECTED, &wl->status);
+			wl->profile->active = true;
+		}
+		else if ((event == WLC_E_LINK && ~(flags & WLC_EVENT_MSG_LINK)) ||
+			event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
+			clear_bit(WL_STATUS_CONNECTED, &wl->status);
+			wl_link_down(wl);
+			wl_init_prof(wl->profile);
+		}
+		else if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_NO_NETWORKS) {
+			WL_DBG(("no action - join fail (IBSS mode)\n"));
+		}
+		else {
+			WL_DBG(("no action (IBSS mode)\n"));
+		}
+	}
+
+	return err;
+}
+
+static s32
+wl_notify_roaming_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+                         const wl_event_msg_t *e, void *data)
+{
+	s32 err = 0;
+	u32 status = EVENT_STATUS(e);
+
+	WL_DBG(("\n"));
+
+	if (status == WLC_E_STATUS_SUCCESS) {
+		err = wl_bss_roaming_done(wl, ndev, e, data);
+		wl->profile->active = true;
+	}
+
+	return err;
+}
+
+static __used s32
+wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
+	u32 buflen;
+
+	buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
+	BUG_ON(!buflen);
+
+	return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
+}
+
+static s32
+wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, s32 buf_len)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
+	u32 len;
+	s32 err = 0;
+
+	len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
+	BUG_ON(!len);
+	err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf, WL_IOCTL_LEN_MAX);
+	if (err) {
+		WL_INF(("error (%d)\n", err));
+		return err;
+	}
+	memcpy(buf, wl->ioctl_buf, buf_len);
+
+	return err;
+}
+
+static s32 wl_get_assoc_ies(struct wl_cfg80211_priv *wl)
+{
+	struct net_device *ndev = wl_to_ndev(wl);
+	struct wl_cfg80211_assoc_ielen *assoc_info;
+	struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
+	u32 req_len;
+	u32 resp_len;
+	s32 err = 0;
+
+	err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf, WL_ASSOC_INFO_MAX);
+	if (err) {
+		WL_ERR(("could not get assoc info (%d)\n", err));
+		return err;
+	}
+	assoc_info = (struct wl_cfg80211_assoc_ielen *)wl->extra_buf;
+	req_len = assoc_info->req_len;
+	resp_len = assoc_info->resp_len;
+	if (req_len) {
+		err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf, WL_ASSOC_INFO_MAX);
+		if (err) {
+			WL_ERR(("could not get assoc req (%d)\n", err));
+			return err;
+		}
+		conn_info->req_ie_len = req_len;
+		conn_info->req_ie =
+		    kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
+	} else {
+		conn_info->req_ie_len = 0;
+		conn_info->req_ie = NULL;
+	}
+	if (resp_len) {
+		err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf, WL_ASSOC_INFO_MAX);
+		if (err) {
+			WL_ERR(("could not get assoc resp (%d)\n", err));
+			return err;
+		}
+		conn_info->resp_ie_len = resp_len;
+		conn_info->resp_ie =
+		    kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
+	} else {
+		conn_info->resp_ie_len = 0;
+		conn_info->resp_ie = NULL;
+	}
+	WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
+		conn_info->resp_ie_len));
+
+	return err;
+}
+
+static void wl_ch_to_chanspec(struct ieee80211_channel *chan, struct wl_join_params *join_params,
+	size_t *join_params_size)
+{
+	chanspec_t chanspec = 0;
+
+	if (chan) {
+		join_params->params.chanspec_num = 1;
+		join_params->params.chanspec_list[0] =
+		    ieee80211_frequency_to_channel(chan->center_freq);
+
+		if (chan->band == IEEE80211_BAND_2GHZ) {
+			chanspec |= WL_CHANSPEC_BAND_2G;
+		}
+		else if (chan->band == IEEE80211_BAND_5GHZ) {
+			chanspec |= WL_CHANSPEC_BAND_5G;
+		}
+		else {
+			WL_ERR(("Unknown band\n"));
+			BUG();
+		}
+
+		chanspec |= WL_CHANSPEC_BW_20;
+
+		*join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
+			join_params->params.chanspec_num * sizeof(chanspec_t);
+
+		join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
+		join_params->params.chanspec_list[0] |= chanspec;
+		join_params->params.chanspec_list[0] =
+		    htodchanspec(join_params->params.chanspec_list[0]);
+
+		join_params->params.chanspec_num = htod32(join_params->params.chanspec_num);
+
+		WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
+		        join_params->params.chanspec_list[0],
+		        join_params->params.chanspec_list[0], chanspec));
+	}
+}
+
+static s32 wl_update_bss_info(struct wl_cfg80211_priv *wl)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+	struct wiphy *wiphy = wl_to_wiphy(wl);
+#endif
+	struct cfg80211_bss *bss;
+	struct wl_bss_info *bi;
+	struct wlc_ssid *ssid;
+	struct bcm_tlv *tim;
+	s32 dtim_period;
+	size_t ie_len;
+	u8 *ie;
+	s32 err = 0;
+
+	ssid = &wl->profile->ssid;
+	bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
+	      ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+
+	rtnl_lock();
+	if (!bss) {
+		WL_DBG(("Could not find the AP\n"));
+		*(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
+		err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, wl->extra_buf,
+		                   WL_EXTRA_BUF_MAX);
+		if (err) {
+			WL_ERR(("Could not get bss info %d\n", err));
+			goto update_bss_info_out;
+		}
+		bi = (struct wl_bss_info *)(wl->extra_buf + 4);
+		if (memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN)) {
+			err = -EIO;
+			goto update_bss_info_out;
+		}
+		err = wl_inform_single_bss(wl, bi);
+		if (err)
+			goto update_bss_info_out;
+
+		bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
+		      ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+
+		ie = ((u8 *)bi) + bi->ie_offset;
+		ie_len = bi->ie_length;
+	} else {
+		WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+		ie = (u8 *)(bss->ies->data);
+		ie_len = bss->ies->len;
+#else
+		ie = bss->information_elements;
+		ie_len = bss->len_information_elements;
+#endif
+		wl->conf->channel = *bss->channel;
+	}
+
+	if (bss) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+		cfg80211_put_bss(wiphy, bss);
+#else
+		cfg80211_put_bss(bss);
+#endif
+	} else {
+		WL_DBG(("Could not update BSS\n"));
+		err = -EINVAL;
+		goto update_bss_info_out;
+	}
+
+	tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
+	if (tim) {
+		dtim_period = tim->data[1];
+	} else {
+
+		err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD,
+			&dtim_period, sizeof(dtim_period));
+		if (err) {
+			WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
+			goto update_bss_info_out;
+		}
+	}
+
+update_bss_info_out:
+	rtnl_unlock();
+	return err;
+}
+
+static s32
+wl_bss_roaming_done(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+                    const wl_event_msg_t *e, void *data)
+{
+	struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+	struct cfg80211_roam_info roam_info = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 0, 0)
+		.bssid = wl->profile->bssid,
+#else
+		.links[0].bssid = wl->profile->bssid,
+#endif
+		.req_ie = conn_info->req_ie,
+		.req_ie_len = conn_info->req_ie_len,
+		.resp_ie = conn_info->resp_ie,
+		.resp_ie_len = conn_info->resp_ie_len,
+	};
+#endif
+	s32 err = 0;
+
+	err = wl_get_assoc_ies(wl);
+	if (err)
+		return err;
+
+	memcpy(wl->profile->bssid, &e->addr, ETHER_ADDR_LEN);
+	memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
+
+	err = wl_update_bss_info(wl);
+	if (err)
+		return err;
+
+	cfg80211_roamed(ndev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+			&roam_info,
+#else
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
+			&wl->conf->channel,	 
+#endif
+			(u8 *)&wl->bssid,
+			conn_info->req_ie, conn_info->req_ie_len,
+			conn_info->resp_ie, conn_info->resp_ie_len,
+#endif
+			GFP_KERNEL);
+	WL_DBG(("Report roaming result\n"));
+
+	set_bit(WL_STATUS_CONNECTED, &wl->status);
+
+	return err;
+}
+
+static s32
+wl_bss_connect_done(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+                    const wl_event_msg_t *e, void *data, bool completed)
+{
+	struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
+	s32 err = 0;
+
+	if (wl->scan_request) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
+		struct cfg80211_scan_info info = {
+			.aborted = true
+		};
+		WL_DBG(("%s: Aborting scan\n", __FUNCTION__));
+		cfg80211_scan_done(wl->scan_request, &info);
+#else
+		cfg80211_scan_done(wl->scan_request, true);     
+#endif
+		wl->scan_request = NULL;
+	}
+
+	if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
+		if (completed) {
+			wl_get_assoc_ies(wl);
+			memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
+			memcpy(wl->profile->bssid, &e->addr, ETHER_ADDR_LEN);
+			wl_update_bss_info(wl);
+			set_bit(WL_STATUS_CONNECTED, &wl->status);
+		}
+
+		WL_DBG(("Reporting BSS network join result \"%s\"\n",
+			wl->profile->ssid.SSID));
+		cfg80211_connect_result(ndev, (u8 *)&wl->bssid,	conn_info->req_ie,
+		    conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len,
+		    completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,	GFP_KERNEL);
+		WL_DBG(("Connection %s\n", completed ? "Succeeded" : "FAILed"));
+	}
+
+	return err;
+}
+
+static s32
+wl_notify_mic_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+                     const wl_event_msg_t *e, void *data)
+{
+	u16 flags = EVENT_FLAGS(e);
+	enum nl80211_key_type key_type;
+
+	WL_DBG(("\n"));
+
+	rtnl_lock();
+	if (flags & WLC_EVENT_MSG_GROUP)
+		key_type = NL80211_KEYTYPE_GROUP;
+	else
+		key_type = NL80211_KEYTYPE_PAIRWISE;
+
+	cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, NULL, GFP_KERNEL);
+	rtnl_unlock();
+
+	return 0;
+}
+
+static s32
+wl_notify_scan_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
+                      const wl_event_msg_t *e, void *data)
+{
+	struct channel_info channel_inform;
+	struct wl_scan_results *bss_list;
+	u32 buflen;
+	s32 err = 0;
+
+	WL_DBG(("\n"));
+
+	rtnl_lock();
+	err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, sizeof(channel_inform));
+	if (err) {
+		WL_ERR(("scan busy (%d)\n", err));
+		goto scan_done_out;
+	}
+	channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
+	if (channel_inform.scan_channel) {
+
+		WL_DBG(("channel_inform.scan_channel (%d)\n",	channel_inform.scan_channel));
+	}
+
+	for (buflen = WL_SCAN_BUF_BASE; ; ) {
+		bss_list = (struct wl_scan_results *) kmalloc(buflen, GFP_KERNEL);
+		if (!bss_list) {
+			WL_ERR(("%s Out of memory for scan results, (%d)\n", ndev->name, err));
+			goto scan_done_out;
+		}
+		memset(bss_list, 0, buflen);
+		bss_list->buflen = htod32(buflen);
+		err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, buflen);
+		if (!err) {
+			break;
+		}
+		else if (err == -E2BIG) {
+			kfree(bss_list);
+			buflen *= 2;
+		}
+		else {
+			WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
+			kfree(bss_list);
+			err = -EINVAL;
+			goto scan_done_out;
+		}
+	}
+
+	bss_list->buflen = dtoh32(bss_list->buflen);
+	bss_list->version = dtoh32(bss_list->version);
+	bss_list->count = dtoh32(bss_list->count);
+
+	err = wl_inform_bss(wl, bss_list);
+	kfree(bss_list);
+
+scan_done_out:
+	if (wl->scan_request) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
+		struct cfg80211_scan_info info = {
+			.aborted = false
+		};
+		cfg80211_scan_done(wl->scan_request, &info);
+#else
+		cfg80211_scan_done(wl->scan_request, false);
+#endif
+		wl->scan_request = NULL;
+	}
+	rtnl_unlock();
+	return err;
+}
+
+static void wl_init_conf(struct wl_cfg80211_conf *conf)
+{
+	conf->mode = (u32)-1;
+	conf->frag_threshold = (u32)-1;
+	conf->rts_threshold = (u32)-1;
+	conf->retry_short = (u32)-1;
+	conf->retry_long = (u32)-1;
+	conf->tx_power = -1;
+}
+
+static void wl_init_prof(struct wl_cfg80211_profile *prof)
+{
+	memset(prof, 0, sizeof(*prof));
+}
+
+static void wl_init_eloop_handler(struct wl_cfg80211_event_loop *el)
+{
+	memset(el, 0, sizeof(*el));
+	el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
+	el->handler[WLC_E_JOIN] = wl_notify_connect_status;
+	el->handler[WLC_E_START] = wl_notify_connect_status;
+	el->handler[WLC_E_LINK] = wl_notify_connect_status;
+	el->handler[WLC_E_NDIS_LINK] = wl_notify_connect_status;
+	el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
+	el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
+	el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
+	el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
+	el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
+}
+
+static s32 wl_init_priv_mem(struct wl_cfg80211_priv *wl)
+{
+	wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
+	if (!wl->conf) {
+		WL_ERR(("wl_cfg80211_conf alloc failed\n"));
+		goto init_priv_mem_out;
+	}
+	wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
+	if (!wl->profile) {
+		WL_ERR(("wl_cfg80211_profile alloc failed\n"));
+		goto init_priv_mem_out;
+	}
+	wl->scan_req_int = (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
+	if (!wl->scan_req_int) {
+		WL_ERR(("Scan req alloc failed\n"));
+		goto init_priv_mem_out;
+	}
+	wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
+	if (!wl->ioctl_buf) {
+		WL_ERR(("Ioctl buf alloc failed\n"));
+		goto init_priv_mem_out;
+	}
+	wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
+	if (!wl->extra_buf) {
+		WL_ERR(("Extra buf alloc failed\n"));
+		goto init_priv_mem_out;
+	}
+
+	wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
+	if (!wl->pmk_list) {
+		WL_ERR(("pmk list alloc failed\n"));
+		goto init_priv_mem_out;
+	}
+
+	return 0;
+
+init_priv_mem_out:
+	wl_deinit_priv_mem(wl);
+
+	return -ENOMEM;
+}
+
+static void wl_deinit_priv_mem(struct wl_cfg80211_priv *wl)
+{
+	kfree(wl->conf);
+	wl->conf = NULL;
+	kfree(wl->profile);
+	wl->profile = NULL;
+	kfree(wl->scan_req_int);
+	wl->scan_req_int = NULL;
+	kfree(wl->ioctl_buf);
+	wl->ioctl_buf = NULL;
+	kfree(wl->extra_buf);
+	wl->extra_buf = NULL;
+	kfree(wl->pmk_list);
+	wl->pmk_list = NULL;
+}
+
+static s32 wl_create_event_handler(struct wl_cfg80211_priv *wl)
+{
+	sema_init(&wl->event_sync, 0);
+	wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
+	if (IS_ERR(wl->event_tsk)) {
+		wl->event_tsk = NULL;
+		WL_ERR(("failed to create event thread\n"));
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void wl_destroy_event_handler(struct wl_cfg80211_priv *wl)
+{
+	if (wl->event_tsk) {
+		send_sig(SIGTERM, wl->event_tsk, 1);
+		kthread_stop(wl->event_tsk);
+		wl->event_tsk = NULL;
+	}
+}
+
+static s32 wl_init_cfg80211_priv(struct wl_cfg80211_priv *wl, struct wireless_dev *wdev)
+{
+	s32 err = 0;
+
+	wl->wdev = wdev;
+
+	wl->scan_request = NULL;
+	wl->active_scan = true;
+	wl_init_eq(wl);
+	err = wl_init_priv_mem(wl);
+	if (err)
+		return err;
+
+	if (wl_create_event_handler(wl))
+		return -ENOMEM;
+
+	wl_init_eloop_handler(&wl->el);
+
+	if (err)
+		return err;
+
+	wl_init_conf(wl->conf);
+	wl_init_prof(wl->profile);
+	wl_link_down(wl);
+
+	return err;
+}
+
+static void wl_deinit_cfg80211_priv(struct wl_cfg80211_priv *wl)
+{
+	wl_destroy_event_handler(wl);
+	wl_flush_eq(wl);
+	wl_link_down(wl);
+	wl_deinit_priv_mem(wl);
+}
+
+s32 wl_cfg80211_attach(struct net_device *ndev, struct device *dev, int passive)
+{
+	struct wireless_dev *wdev;
+	struct wl_cfg80211_priv *wl;
+	s32 err = 0;
+
+	if (!ndev) {
+		WL_ERR(("ndev is invaild\n"));
+		return -ENODEV;
+	}
+
+	err = wl_alloc_wdev(dev, &wdev);
+	if (err < 0) {
+		return err;
+	}
+
+	wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
+	wl = wdev_to_wl(wdev);
+	ndev->ieee80211_ptr = wdev;
+	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
+	wdev->netdev = ndev;
+	err = wl_init_cfg80211_priv(wl, wdev);
+	if (err) {
+		WL_ERR(("Failed to init iwm_priv (%d)\n", err));
+		goto cfg80211_attach_out;
+	}
+	wl->passive = !!passive;
+
+	if (!err) {
+		WL_INF(("Registered CFG80211 phy\n"));
+	}
+	return err;
+
+cfg80211_attach_out:
+	wl_free_wdev(wl);
+	return err;
+}
+
+void wl_cfg80211_detach(struct net_device *ndev)
+{
+	struct wl_cfg80211_priv *wl;
+
+	if (ndev->ieee80211_ptr == NULL) {
+                WL_ERR(( "NULL ndev->ieee80211ptr, unable to deref wl\n"));
+                return;
+        }
+	wl = ndev_to_wl(ndev);
+
+	wl_deinit_cfg80211_priv(wl);
+	wl_free_wdev(wl);
+}
+
+static void wl_wakeup_event(struct wl_cfg80211_priv *wl)
+{
+	up(&wl->event_sync);
+}
+
+static s32 wl_event_handler(void *data)
+{
+	struct wl_cfg80211_priv *wl = (struct wl_cfg80211_priv *)data;
+	struct wl_cfg80211_event_q *e;
+
+	allow_signal(SIGTERM);
+	while (!down_interruptible(&wl->event_sync)) {
+		if (kthread_should_stop())
+			break;
+		e = wl_deq_event(wl);
+		if (!e) {
+			WL_ERR(("eqeue empty..\n"));
+			BUG();
+		}
+		if (wl->el.handler[e->etype]) {
+			WL_DBG(("event type (%d)\n", e->etype));
+			wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg, e->edata);
+		} else {
+			WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
+		}
+		wl_put_event(e);
+	}
+	WL_DBG(("%s was terminated\n", __func__));
+	return 0;
+}
+
+void
+wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
+{
+
+	u32 event_type = EVENT_TYPE(e);
+
+	struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
+#if defined(WL_DBGMSG_ENABLE)
+	s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
+	    wl_dbg_estr[event_type] : (s8 *) "Unknown";
+	WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
+#endif				
+	if (!wl_enq_event(wl, event_type, e, data))
+		wl_wakeup_event(wl);
+}
+
+static void wl_init_eq(struct wl_cfg80211_priv *wl)
+{
+	wl_init_eq_lock(wl);
+	INIT_LIST_HEAD(&wl->eq_list);
+}
+
+static void wl_flush_eq(struct wl_cfg80211_priv *wl)
+{
+	struct wl_cfg80211_event_q *e;
+
+	wl_lock_eq(wl);
+	while (!list_empty(&wl->eq_list)) {
+		e = list_first_entry(&wl->eq_list, struct wl_cfg80211_event_q, eq_list);
+		list_del(&e->eq_list);
+		kfree(e);
+	}
+	wl_unlock_eq(wl);
+}
+
+static struct wl_cfg80211_event_q *wl_deq_event(struct wl_cfg80211_priv *wl)
+{
+	struct wl_cfg80211_event_q *e = NULL;
+
+	wl_lock_eq(wl);
+	if (!list_empty(&wl->eq_list)) {
+		e = list_first_entry(&wl->eq_list, struct wl_cfg80211_event_q, eq_list);
+		list_del(&e->eq_list);
+	}
+	wl_unlock_eq(wl);
+
+	return e;
+}
+
+static s32
+wl_enq_event(struct wl_cfg80211_priv *wl, u32 event, const wl_event_msg_t *msg, void *data)
+{
+	struct wl_cfg80211_event_q *e;
+	s32 err = 0;
+
+	e = kzalloc(sizeof(struct wl_cfg80211_event_q), GFP_ATOMIC);
+	if (!e) {
+		WL_ERR(("event alloc failed\n"));
+		return -ENOMEM;
+	}
+
+	e->etype = event;
+	memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
+	if (data) {
+	}
+
+	spin_lock(&wl->eq_lock);
+	list_add_tail(&e->eq_list, &wl->eq_list);
+	spin_unlock(&wl->eq_lock);
+
+	return err;
+}
+
+static void wl_put_event(struct wl_cfg80211_event_q *e)
+{
+	kfree(e);
+}
+
+static s32 wl_set_mode(struct net_device *ndev, s32 iftype)
+{
+	s32 infra = 0;
+	s32 ap = 0;
+	s32 err = 0;
+
+	switch (iftype) {
+	case NL80211_IFTYPE_MONITOR:
+	case NL80211_IFTYPE_WDS:
+		WL_ERR(("type (%d) : currently we do not support this mode\n",
+			iftype));
+		err = -EINVAL;
+		return err;
+	case NL80211_IFTYPE_ADHOC:
+		break;
+	case NL80211_IFTYPE_STATION:
+		infra = 1;
+		break;
+	default:
+		err = -EINVAL;
+		WL_ERR(("invalid type (%d)\n", iftype));
+		return err;
+	}
+	infra = htod32(infra);
+	ap = htod32(ap);
+	WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
+	err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
+	if (err) {
+		WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
+		return err;
+	}
+	err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
+	if (err) {
+		WL_ERR(("WLC_SET_AP error (%d)\n", err));
+		return err;
+	}
+
+	return 0;
+}
+
+static void wl_update_wowl(struct net_device *ndev)
+{
+#ifdef CONFIG_PM
+	struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
+	struct wireless_dev *wdev = ndev->ieee80211_ptr;
+	s32 offloads = 0;
+	s32 err = 0;
+	err = wl_dev_bufvar_get(wl_to_ndev(wl), "offloads",
+		(s8 *)&offloads, sizeof(offloads));
+	if (err == 0 && offloads == 1) {
+		WL_INF(("Supports offloads\n"));
+		wl->offloads = true;
+	} else {
+		WL_INF(("No offloads supported\n"));
+		wl->offloads = false;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+		wdev->wiphy->wowlan = NULL;
+#else
+		memset(&wdev->wiphy->wowlan, 0, sizeof(struct wiphy_wowlan_support));
+#endif 
+#endif 
+	}
+#endif 
+}
+
+static s32 wl_update_wiphybands(struct wl_cfg80211_priv *wl)
+{
+	struct wiphy *wiphy;
+	s32 phy_list;
+	s8 phy;
+	s32 err = 0;
+
+	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list, sizeof(phy_list));
+	if (err) {
+		WL_ERR(("error (%d)\n", err));
+		return err;
+	}
+
+	phy = ((char *)&phy_list)[0];
+	WL_DBG(("%c phy\n", phy));
+
+	if (phy == 'n' || phy == 'a' || phy == 'v') {
+		wiphy = wl_to_wiphy(wl);
+		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
+	}
+
+	return err;
+}
+
+s32 wl_cfg80211_up(struct net_device *ndev)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
+	s32 err = 0;
+	struct wireless_dev *wdev = ndev->ieee80211_ptr;
+
+	wl_set_mode(ndev, wdev->iftype);
+	err = wl_update_wiphybands(wl);
+	if (err) {
+		return err;
+	} 
+
+	wl_update_wowl(ndev);
+	return 0;
+}
+
+s32 wl_cfg80211_down(struct net_device *ndev)
+{
+	struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
+	s32 err = 0;
+
+	if (wl->scan_request) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
+		struct cfg80211_scan_info info = {
+			.aborted = true
+		};
+		cfg80211_scan_done(wl->scan_request, &info);
+#else
+		cfg80211_scan_done(wl->scan_request, true);	
+#endif
+		wl->scan_request = NULL;
+	}
+
+	return err;
+}
+
+static bool wl_is_ibssmode(struct wl_cfg80211_priv *wl)
+{
+	return wl->conf->mode == WL_MODE_IBSS;
+}
+
+static void wl_rst_ie(struct wl_cfg80211_priv *wl)
+{
+	struct wl_cfg80211_ie *ie = wl_to_ie(wl);
+
+	ie->offset = 0;
+}
+
+static __used s32 wl_add_ie(struct wl_cfg80211_priv *wl, u8 t, u8 l, u8 *v)
+{
+	struct wl_cfg80211_ie *ie = wl_to_ie(wl);
+	s32 err = 0;
+
+	if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
+		WL_ERR(("ei crosses buffer boundary\n"));
+		return -ENOSPC;
+	}
+	ie->buf[ie->offset] = t;
+	ie->buf[ie->offset + 1] = l;
+	memcpy(&ie->buf[ie->offset + 2], v, l);
+	ie->offset += l + 2;
+
+	return err;
+}
+
+static s32 wl_mrg_ie(struct wl_cfg80211_priv *wl, u8 *ie_stream, u16 ie_size)
+{
+	struct wl_cfg80211_ie *ie = wl_to_ie(wl);
+	s32 err = 0;
+
+	if (ie->offset + ie_size > WL_TLV_INFO_MAX) {
+		WL_ERR(("ei_stream crosses buffer boundary\n"));
+		return -ENOSPC;
+	}
+	memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
+	ie->offset += ie_size;
+
+	return err;
+}
+
+static s32 wl_cp_ie(struct wl_cfg80211_priv *wl, u8 *dst, u16 dst_size)
+{
+	struct wl_cfg80211_ie *ie = wl_to_ie(wl);
+	s32 err = 0;
+
+	if (ie->offset > dst_size) {
+		WL_ERR(("dst_size is not enough\n"));
+		return -ENOSPC;
+	}
+	memcpy(dst, &ie->buf[0], ie->offset);
+
+	return err;
+}
+
+static u32 wl_get_ielen(struct wl_cfg80211_priv *wl)
+{
+	struct wl_cfg80211_ie *ie = wl_to_ie(wl);
+
+	return ie->offset;
+}
+
+static void wl_link_up(struct wl_cfg80211_priv *wl)
+{
+	WL_DBG(("\n"));
+}
+
+static void wl_link_down(struct wl_cfg80211_priv *wl)
+{
+	struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
+
+	WL_DBG(("\n"));
+
+	kfree(conn_info->req_ie);
+	conn_info->req_ie = NULL;
+	conn_info->req_ie_len = 0;
+	kfree(conn_info->resp_ie);
+	conn_info->resp_ie = NULL;
+	conn_info->resp_ie_len = 0;
+}
+
+static void wl_lock_eq(struct wl_cfg80211_priv *wl)
+{
+	spin_lock_irq(&wl->eq_lock);
+}
+
+static void wl_unlock_eq(struct wl_cfg80211_priv *wl)
+{
+	spin_unlock_irq(&wl->eq_lock);
+}
+
+static void wl_init_eq_lock(struct wl_cfg80211_priv *wl)
+{
+	spin_lock_init(&wl->eq_lock);
+}
+
+#endif 
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_cfg80211_hybrid.h
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_cfg80211_hybrid.h	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_cfg80211_hybrid.h	(revision 5)
@@ -0,0 +1,236 @@
+/*
+ * Linux-specific portion of Broadcom 802.11abg Networking Device Driver
+ * cfg80211 interface
+ *
+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: wl_cfg80211.h,v 1.1.8.1 2011-01-26 00:57:46 $
+ */
+
+#ifndef _wl_cfg80211_h_
+#define _wl_cfg80211_h_
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+#define IEEE80211_BAND_2GHZ NL80211_BAND_2GHZ
+#define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ
+#endif
+
+#include <net/cfg80211.h>
+#include <wlioctl.h>
+
+struct wl_cfg80211_conf;
+struct wl_cfg80211_priv;
+struct wl_cfg80211_security;
+
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+
+#define WL_DBGMSG_ENABLE
+
+#define WL_DBG_NONE	0
+#define WL_DBG_DBG 	(1 << 2)
+#define WL_DBG_INFO	(1 << 1)
+#define WL_DBG_ERR	(1 << 0)
+#define WL_DBG_MASK ((WL_DBG_DBG | WL_DBG_INFO | WL_DBG_ERR) << 1)
+
+#if defined(WL_DBGMSG_ENABLE)
+#define	WL_DBG(args)								\
+do {									\
+	if (wl_dbg_level & WL_DBG_DBG) {			\
+		printk(KERN_ERR "DEBUG @%s :", __func__);	\
+		printk args;							\
+	}									\
+} while (0)
+#else				
+#define	WL_DBG(args)
+#endif				
+
+#define	WL_ERR(args)									\
+do {										\
+	if (wl_dbg_level & WL_DBG_ERR) {				\
+		if (net_ratelimit()) {						\
+			printk(KERN_ERR "ERROR @%s : ", __func__);	\
+			printk args;						\
+		} 								\
+	}									\
+} while (0)
+
+#define	WL_INF(args)									\
+do {										\
+	if (wl_dbg_level & WL_DBG_INFO) {				\
+		if (net_ratelimit()) {						\
+			printk(KERN_ERR "INFO @%s : ", __func__);	\
+			printk args;						\
+		}								\
+	}									\
+} while (0)
+
+#define WL_NUM_SCAN_MAX		1
+#define WL_NUM_PMKIDS_MAX	MAXPMKID	
+#define WL_SCAN_BUF_BASE 		(16*1024)
+#define WL_TLV_INFO_MAX 		1024
+#define WL_BSS_INFO_MAX			2048
+#define WL_ASSOC_INFO_MAX	512
+#define WL_IOCTL_LEN_MAX	2048
+#define WL_EXTRA_BUF_MAX	2048
+#define WL_AP_MAX	256	
+
+enum wl_cfg80211_status {
+	WL_STATUS_CONNECTING,
+	WL_STATUS_CONNECTED
+};
+
+enum wl_cfg80211_mode {
+	WL_MODE_BSS,
+	WL_MODE_IBSS,
+	WL_MODE_AP
+};
+
+struct beacon_proberesp {
+	__le64 timestamp;
+	__le16 beacon_int;
+	__le16 capab_info;
+	u8 variable[0];
+} __attribute__ ((packed));
+
+struct wl_cfg80211_conf {
+	u32 mode;		
+	u32 frag_threshold;
+	u32 rts_threshold;
+	u32 retry_short;
+	u32 retry_long;
+	s32 tx_power;
+	struct ieee80211_channel channel;
+};
+
+struct wl_cfg80211_event_loop {
+	s32(*handler[WLC_E_LAST]) (struct wl_cfg80211_priv *wl, struct net_device *ndev,
+	                           const wl_event_msg_t *e, void *data);
+};
+
+struct wl_cfg80211_bss_info {
+	u16 band;
+	u16 channel;
+	s16 rssi;
+	u16 frame_len;
+	u8 frame_buf[1];
+};
+
+struct wl_cfg80211_scan_req {
+	struct wlc_ssid ssid;
+};
+
+struct wl_cfg80211_ie {
+	u16 offset;
+	u8 buf[WL_TLV_INFO_MAX];
+};
+
+struct wl_cfg80211_event_q {
+	struct list_head eq_list;
+	u32 etype;
+	wl_event_msg_t emsg;
+	s8 edata[1];
+};
+
+struct wl_cfg80211_security {
+	u32 wpa_versions;
+	u32 auth_type;
+	u32 cipher_pairwise;
+	u32 cipher_group;
+	u32 wpa_auth;
+};
+
+struct wl_cfg80211_profile {
+	struct wlc_ssid ssid;
+	u8 bssid[ETHER_ADDR_LEN];
+	struct wl_cfg80211_security sec;
+	bool active;
+};
+
+struct wl_cfg80211_connect_info {
+	u8 *req_ie;
+	s32 req_ie_len;
+	u8 *resp_ie;
+	s32 resp_ie_len;
+};
+
+struct wl_cfg80211_assoc_ielen {
+	u32 req_len;
+	u32 resp_len;
+};
+
+struct wl_cfg80211_pmk_list {
+	pmkid_list_t pmkids;
+	pmkid_t foo[MAXPMKID - 1];
+};
+
+struct wl_cfg80211_priv {
+	struct wireless_dev *wdev;	
+	struct wl_cfg80211_conf *conf;	
+	struct cfg80211_scan_request *scan_request;	
+	struct wl_cfg80211_event_loop el;	
+	struct list_head eq_list;	
+	spinlock_t eq_lock;	
+	struct wl_cfg80211_scan_req *scan_req_int;  
+	struct wl_cfg80211_ie ie;	 
+	struct ether_addr bssid;	
+	struct semaphore event_sync;	
+	struct wl_cfg80211_profile *profile;	
+	struct wl_cfg80211_connect_info conn_info;	
+	struct wl_cfg80211_pmk_list *pmk_list;	
+	struct task_struct *event_tsk;	
+	unsigned long status;		
+	bool active_scan;	
+	bool passive;	
+	bool offloads;	
+	u8 *ioctl_buf;	
+	u8 *extra_buf;	
+	u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
+};
+
+#define wl_to_dev(w) (wiphy_dev(wl->wdev->wiphy))
+#define wl_to_wiphy(w) (w->wdev->wiphy)
+#define wiphy_to_wl(w) ((struct wl_cfg80211_priv *)(wiphy_priv(w)))
+#define wl_to_wdev(w) (w->wdev)
+#define wdev_to_wl(w) ((struct wl_cfg80211_priv *)(wdev_priv(w)))
+#define wl_to_ndev(w) (w->wdev->netdev)
+#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
+#define wl_to_sr(w) (w->scan_req_int)
+#define wl_to_ie(w) (&w->ie)
+#define wl_to_conn(w) (&w->conn_info)
+
+static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
+{
+	return bss = bss ? (struct wl_bss_info *)((unsigned long)bss +
+	             dtoh32(bss->length)) : list->bss_info;
+}
+
+#define for_each_bss(list, bss, __i)	\
+	for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
+
+extern s32 wl_cfg80211_attach(struct net_device *ndev, struct device *dev, int flags);
+extern void wl_cfg80211_detach(struct net_device *ndev);
+
+extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e, void *data);
+extern s32 wl_cfg80211_up(struct net_device *ndev);
+extern s32 wl_cfg80211_down(struct net_device *ndev);
+
+#endif 
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_iw.c
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_iw.c	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_iw.c	(revision 5)
@@ -0,0 +1,2837 @@
+/*
+ * Linux Wireless Extensions support
+ *
+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: wl_iw.c 458427 2014-02-26 23:12:38Z $
+ */
+
+#if defined(USE_IW)
+#define LINUX_PORT
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <proto/ethernet.h>
+
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+
+typedef const struct si_pub	si_t;
+#include <wlioctl.h>
+
+#include <wl_dbg.h>
+#include <wl_iw.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
+#include <wl_linux.h>
+#endif
+
+extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status,
+	uint32 reason, char* stringBuf, uint buflen);
+
+#define MAX_WLIW_IOCTL_LEN 1024
+
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+
+extern struct iw_statistics *wl_get_wireless_stats(struct net_device *dev);
+
+#if WIRELESS_EXT < 19
+#define IW_IOCTL_IDX(cmd)	((cmd) - SIOCIWFIRST)
+#define IW_EVENT_IDX(cmd)	((cmd) - IWEVFIRST)
+#endif 
+
+typedef struct priv_link {
+	wl_iw_t *wliw;
+} priv_link_t;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
+#define WL_DEV_LINK(dev)       (priv_link_t*)(dev->priv)
+#else
+#define WL_DEV_LINK(dev)       (priv_link_t*)netdev_priv(dev)
+#endif
+
+#define IW_DEV_IF(dev)          ((wl_iw_t*)(WL_DEV_LINK(dev))->wliw)
+
+static void swap_key_from_BE(
+	        wl_wsec_key_t *key
+)
+{
+	key->index = htod32(key->index);
+	key->len = htod32(key->len);
+	key->algo = htod32(key->algo);
+	key->flags = htod32(key->flags);
+	key->rxiv.hi = htod32(key->rxiv.hi);
+	key->rxiv.lo = htod16(key->rxiv.lo);
+	key->iv_initialized = htod32(key->iv_initialized);
+}
+
+static void swap_key_to_BE(
+	        wl_wsec_key_t *key
+)
+{
+	key->index = dtoh32(key->index);
+	key->len = dtoh32(key->len);
+	key->algo = dtoh32(key->algo);
+	key->flags = dtoh32(key->flags);
+	key->rxiv.hi = dtoh32(key->rxiv.hi);
+	key->rxiv.lo = dtoh16(key->rxiv.lo);
+	key->iv_initialized = dtoh32(key->iv_initialized);
+}
+
+static int
+dev_wlc_ioctl(
+	struct net_device *dev,
+	int cmd,
+	void *arg,
+	int len
+)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
+	struct ifreq ifr;
+	wl_ioctl_t ioc;
+	mm_segment_t fs;
+	int ret;
+
+	memset(&ioc, 0, sizeof(ioc));
+	ioc.cmd = cmd;
+	ioc.buf = arg;
+	ioc.len = len;
+
+	strcpy(ifr.ifr_name, dev->name);
+	ifr.ifr_data = (caddr_t) &ioc;
+
+	fs = get_fs();
+	set_fs(get_ds());
+#if defined(WL_USE_NETDEV_OPS)
+	ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+#else
+	ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+#endif
+	set_fs(fs);
+
+	return ret;
+#else
+	return wlc_ioctl_internal(dev, cmd, arg, len);
+#endif
+}
+
+static int
+dev_wlc_intvar_set(
+	struct net_device *dev,
+	char *name,
+	int val)
+{
+	char buf[WLC_IOCTL_SMLEN];
+	uint len;
+
+	val = htod32(val);
+	len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
+	ASSERT(len);
+
+	return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len));
+}
+
+#if WIRELESS_EXT > 17
+static int
+dev_wlc_bufvar_set(
+	struct net_device *dev,
+	char *name,
+	char *buf, int len)
+{
+	char *ioctlbuf;
+	uint buflen;
+	int error;
+
+	ioctlbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL);
+	if (!ioctlbuf)
+		return -ENOMEM;
+
+	buflen = bcm_mkiovar(name, buf, len, ioctlbuf, MAX_WLIW_IOCTL_LEN);
+	ASSERT(buflen);
+	error = dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen);
+
+	kfree(ioctlbuf);
+	return error;
+}
+#endif 
+
+static int
+dev_wlc_bufvar_get(
+	struct net_device *dev,
+	char *name,
+	char *buf, int buflen)
+{
+	char *ioctlbuf;
+	int error;
+
+	uint len;
+
+	ioctlbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL);
+	if (!ioctlbuf)
+		return -ENOMEM;
+	len = bcm_mkiovar(name, NULL, 0, ioctlbuf, MAX_WLIW_IOCTL_LEN);
+	ASSERT(len);
+	BCM_REFERENCE(len);
+	error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN);
+	if (!error)
+		bcopy(ioctlbuf, buf, buflen);
+
+	kfree(ioctlbuf);
+	return (error);
+}
+
+static int
+dev_wlc_intvar_get(
+	struct net_device *dev,
+	char *name,
+	int *retval)
+{
+	union {
+		char buf[WLC_IOCTL_SMLEN];
+		int val;
+	} var;
+	int error;
+
+	uint len;
+	uint data_null;
+
+	len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf));
+	ASSERT(len);
+	error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len);
+
+	*retval = dtoh32(var.val);
+
+	return (error);
+}
+
+#if WIRELESS_EXT < 13
+struct iw_request_info
+{
+	__u16		cmd;		
+	__u16		flags;		
+};
+
+typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
+	void *wrqu, char *extra);
+#endif 
+
+#if WIRELESS_EXT > 12
+static int
+wl_iw_set_leddc(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	union iwreq_data *wrqu,
+	char *extra
+)
+{
+	int dc = *(int *)extra;
+	int error;
+
+	error = dev_wlc_intvar_set(dev, "leddc", dc);
+	return error;
+}
+
+static int
+wl_iw_set_vlanmode(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	union iwreq_data *wrqu,
+	char *extra
+)
+{
+	int mode = *(int *)extra;
+	int error;
+
+	mode = htod32(mode);
+	error = dev_wlc_intvar_set(dev, "vlan_mode", mode);
+	return error;
+}
+
+static int
+wl_iw_set_pm(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	union iwreq_data *wrqu,
+	char *extra
+)
+{
+	int pm = *(int *)extra;
+	int error;
+
+	pm = htod32(pm);
+	error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+	return error;
+}
+#endif 
+
+int
+wl_iw_send_priv_event(
+	struct net_device *dev,
+	char *flag
+)
+{
+	union iwreq_data wrqu;
+	char extra[IW_CUSTOM_MAX + 1];
+	int cmd;
+
+	cmd = IWEVCUSTOM;
+	memset(&wrqu, 0, sizeof(wrqu));
+	if (strlen(flag) > sizeof(extra))
+		return -1;
+
+	strcpy(extra, flag);
+	wrqu.data.length = strlen(extra);
+	wireless_send_event(dev, cmd, &wrqu, extra);
+	WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra));
+
+	return 0;
+}
+
+static int
+wl_iw_config_commit(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	void *zwrq,
+	char *extra
+)
+{
+	wlc_ssid_t ssid;
+	int error;
+	struct sockaddr bssid;
+
+	WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name));
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid))))
+		return error;
+
+	ssid.SSID_len = dtoh32(ssid.SSID_len);
+
+	if (!ssid.SSID_len)
+		return 0;
+
+	bzero(&bssid, sizeof(struct sockaddr));
+	if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) {
+		WL_ERROR(("%s: WLC_REASSOC failed (%d)\n", __FUNCTION__, error));
+		return error;
+	}
+
+	return 0;
+}
+
+static int
+wl_iw_get_name(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	union iwreq_data *cwrq,
+	char *extra
+)
+{
+	int phytype, err;
+	uint band[3];
+	char cap[5];
+
+	WL_TRACE(("%s: SIOCGIWNAME\n", dev->name));
+
+	cap[0] = 0;
+	if ((err = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype))) < 0)
+		goto done;
+	if ((err = dev_wlc_ioctl(dev, WLC_GET_BANDLIST, band, sizeof(band))) < 0)
+		goto done;
+
+	band[0] = dtoh32(band[0]);
+	switch (phytype) {
+		case WLC_PHY_TYPE_A:
+			strcpy(cap, "a");
+			break;
+		case WLC_PHY_TYPE_B:
+			strcpy(cap, "b");
+			break;
+		case WLC_PHY_TYPE_LP:
+		case WLC_PHY_TYPE_G:
+			if (band[0] >= 2)
+				strcpy(cap, "abg");
+			else
+				strcpy(cap, "bg");
+			break;
+		case WLC_PHY_TYPE_N:
+			if (band[0] >= 2)
+				strcpy(cap, "abgn");
+			else
+				strcpy(cap, "bgn");
+			break;
+	}
+done:
+	snprintf(cwrq->name, IFNAMSIZ, "IEEE 802.11%s", cap);
+	return 0;
+}
+
+static int
+wl_iw_set_freq(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_freq *fwrq,
+	char *extra
+)
+{
+	int error, chan;
+	uint sf = 0;
+
+	WL_TRACE(("%s: SIOCSIWFREQ\n", dev->name));
+
+	if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) {
+		chan = fwrq->m;
+	}
+
+	else {
+
+		if (fwrq->e >= 6) {
+			fwrq->e -= 6;
+			while (fwrq->e--)
+				fwrq->m *= 10;
+		} else if (fwrq->e < 6) {
+			while (fwrq->e++ < 6)
+				fwrq->m /= 10;
+		}
+
+	if (fwrq->m > 4000 && fwrq->m < 5000)
+		sf = WF_CHAN_FACTOR_4_G; 
+
+		chan = wf_mhz2channel(fwrq->m, sf);
+	}
+	chan = htod32(chan);
+	if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan))))
+		return error;
+
+	return -EINPROGRESS;
+}
+
+static int
+wl_iw_get_freq(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_freq *fwrq,
+	char *extra
+)
+{
+	channel_info_t ci;
+	int error;
+
+	WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name));
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci))))
+		return error;
+
+	fwrq->m = dtoh32(ci.hw_channel);
+	fwrq->e = dtoh32(0);
+	return 0;
+}
+
+static int
+wl_iw_set_mode(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	__u32 *uwrq,
+	char *extra
+)
+{
+	int infra = 0, ap = 0, error = 0;
+
+	WL_TRACE(("%s: SIOCSIWMODE\n", dev->name));
+
+	switch (*uwrq) {
+	case IW_MODE_MASTER:
+		infra = ap = 1;
+		break;
+	case IW_MODE_ADHOC:
+	case IW_MODE_AUTO:
+		break;
+	case IW_MODE_INFRA:
+		infra = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	infra = htod32(infra);
+	ap = htod32(ap);
+
+	if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) ||
+	    (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap))))
+		return error;
+
+	return -EINPROGRESS;
+}
+
+static int
+wl_iw_get_mode(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	__u32 *uwrq,
+	char *extra
+)
+{
+	int error, infra = 0, ap = 0;
+
+	WL_TRACE(("%s: SIOCGIWMODE\n", dev->name));
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) ||
+	    (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap))))
+		return error;
+
+	infra = dtoh32(infra);
+	ap = dtoh32(ap);
+	*uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC;
+
+	return 0;
+}
+
+static int
+wl_iw_get_range(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	struct iw_range *range = (struct iw_range *) extra;
+	static int channels[MAXCHANNEL+1];
+	wl_uint32_list_t *list = (wl_uint32_list_t *) channels;
+	wl_rateset_t rateset;
+	int error, i, k;
+	uint sf, ch;
+
+	int phytype;
+	int bw_cap = 0, sgi_tx = 0, nmode = 0;
+	channel_info_t ci;
+	uint8 nrate_list2copy = 0;
+	uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130},
+		{14, 29, 43, 58, 87, 116, 130, 144},
+		{27, 54, 81, 108, 162, 216, 243, 270},
+		{30, 60, 90, 120, 180, 240, 270, 300}};
+
+	WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name));
+
+	if (!extra)
+		return -EINVAL;
+
+	dwrq->length = sizeof(struct iw_range);
+	memset(range, 0, sizeof(*range));
+
+	range->min_nwid = range->max_nwid = 0;
+
+	list->count = htod32(MAXCHANNEL);
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, sizeof(channels))))
+		return error;
+	for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) {
+		range->freq[i].i = dtoh32(list->element[i]);
+
+		ch = dtoh32(list->element[i]);
+		if (ch <= CH_MAX_2G_CHANNEL)
+			sf = WF_CHAN_FACTOR_2_4_G;
+		else
+			sf = WF_CHAN_FACTOR_5_G;
+
+		range->freq[i].m = wf_channel2mhz(ch, sf);
+		range->freq[i].e = 6;
+	}
+	range->num_frequency = range->num_channels = i;
+
+	range->max_qual.qual = 5;
+
+	range->max_qual.level = 0x100 - 200;	
+
+	range->max_qual.noise = 0x100 - 200;	
+
+	range->sensitivity = 65535;
+
+#if WIRELESS_EXT > 11
+
+	range->avg_qual.qual = 3;
+
+	range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD;
+
+	range->avg_qual.noise = 0x100 - 75;	
+#endif 
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset))))
+		return error;
+	rateset.count = dtoh32(rateset.count);
+	range->num_bitrates = rateset.count;
+	for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++)
+		range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; 
+	dev_wlc_intvar_get(dev, "nmode", &nmode);
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype))))
+		return error;
+
+	if (nmode == 1 && ((phytype == WLC_PHY_TYPE_SSN) || (phytype == WLC_PHY_TYPE_LCN) ||
+		(phytype == WLC_PHY_TYPE_LCN40))) {
+		dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap);
+		dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx);
+		dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t));
+		ci.hw_channel = dtoh32(ci.hw_channel);
+
+		if (bw_cap == 0 ||
+			(bw_cap == 2 && ci.hw_channel <= 14)) {
+			if (sgi_tx == 0)
+				nrate_list2copy = 0;
+			else
+				nrate_list2copy = 1;
+		}
+		if (bw_cap == 1 ||
+			(bw_cap == 2 && ci.hw_channel >= 36)) {
+			if (sgi_tx == 0)
+				nrate_list2copy = 2;
+			else
+				nrate_list2copy = 3;
+		}
+		range->num_bitrates += 8;
+		for (k = 0; i < range->num_bitrates; k++, i++) {
+
+			range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000;
+		}
+	}
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i))))
+		return error;
+	i = dtoh32(i);
+	if (i == WLC_PHY_TYPE_A)
+		range->throughput = 24000000;	
+	else
+		range->throughput = 1500000;	
+
+	range->min_rts = 0;
+	range->max_rts = 2347;
+	range->min_frag = 256;
+	range->max_frag = 2346;
+
+	range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS;
+	range->num_encoding_sizes = 4;
+	range->encoding_size[0] = WEP1_KEY_SIZE;
+	range->encoding_size[1] = WEP128_KEY_SIZE;
+#if WIRELESS_EXT > 17
+	range->encoding_size[2] = TKIP_KEY_SIZE;
+#else
+	range->encoding_size[2] = 0;
+#endif
+	range->encoding_size[3] = AES_KEY_SIZE;
+
+	range->min_pmp = 0;
+	range->max_pmp = 0;
+	range->min_pmt = 0;
+	range->max_pmt = 0;
+	range->pmp_flags = 0;
+	range->pm_capa = 0;
+
+	range->num_txpower = 2;
+	range->txpower[0] = 1;
+	range->txpower[1] = 255;
+	range->txpower_capa = IW_TXPOW_MWATT;
+
+#if WIRELESS_EXT > 10
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 19;
+
+	range->retry_capa = IW_RETRY_LIMIT;
+	range->retry_flags = IW_RETRY_LIMIT;
+	range->r_time_flags = 0;
+
+	range->min_retry = 1;
+	range->max_retry = 255;
+
+	range->min_r_time = 0;
+	range->max_r_time = 0;
+#endif 
+
+#if WIRELESS_EXT > 17
+	range->enc_capa = IW_ENC_CAPA_WPA;
+	range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;
+	range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
+	range->enc_capa |= IW_ENC_CAPA_WPA2;
+
+	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+
+	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+	IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE);
+	IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCREQIE);
+	IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCRESPIE);
+	IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND);
+
+#if WIRELESS_EXT >= 22 && defined(IW_SCAN_CAPA_ESSID)
+
+	range->scan_capa = IW_SCAN_CAPA_ESSID;
+#endif
+#endif 
+
+	return 0;
+}
+
+static int
+rssi_to_qual(int rssi)
+{
+	if (rssi <= WL_IW_RSSI_NO_SIGNAL)
+		return 0;
+	else if (rssi <= WL_IW_RSSI_VERY_LOW)
+		return 1;
+	else if (rssi <= WL_IW_RSSI_LOW)
+		return 2;
+	else if (rssi <= WL_IW_RSSI_GOOD)
+		return 3;
+	else if (rssi <= WL_IW_RSSI_VERY_GOOD)
+		return 4;
+	else
+		return 5;
+}
+
+static int
+wl_iw_set_spy(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wl_iw_t *iw = IW_DEV_IF(dev);
+	struct sockaddr *addr = (struct sockaddr *) extra;
+	int i;
+
+	WL_TRACE(("%s: SIOCSIWSPY\n", dev->name));
+
+	if (!extra)
+		return -EINVAL;
+
+	iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length);
+	for (i = 0; i < iw->spy_num; i++)
+		memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN);
+	memset(iw->spy_qual, 0, sizeof(iw->spy_qual));
+
+	return 0;
+}
+
+static int
+wl_iw_get_spy(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wl_iw_t *iw = IW_DEV_IF(dev);
+	struct sockaddr *addr = (struct sockaddr *) extra;
+	struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num];
+	int i;
+
+	WL_TRACE(("%s: SIOCGIWSPY\n", dev->name));
+
+	if (!extra)
+		return -EINVAL;
+
+	dwrq->length = iw->spy_num;
+	for (i = 0; i < iw->spy_num; i++) {
+		memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN);
+		addr[i].sa_family = AF_UNIX;
+		memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality));
+		iw->spy_qual[i].updated = 0;
+	}
+
+	return 0;
+}
+
+static int
+wl_iw_set_wap(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct sockaddr *awrq,
+	char *extra
+)
+{
+	int error = -EINVAL;
+#ifdef BCMDBG
+
+#endif
+
+	WL_TRACE(("%s: SIOCSIWAP\n", dev->name));
+
+	if (awrq->sa_family != ARPHRD_ETHER) {
+		WL_ERROR(("%s: Invalid Header...sa_family\n", __FUNCTION__));
+		return -EINVAL;
+	}
+
+	if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) {
+		scb_val_t scbval;
+		bzero(&scbval, sizeof(scb_val_t));
+		if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) {
+			WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
+		}
+		return 0;
+	}
+
+	if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, awrq->sa_data, ETHER_ADDR_LEN))) {
+		WL_ERROR(("%s: WLC_REASSOC failed (%d).\n", __FUNCTION__, error));
+		return error;
+	}
+
+	return 0;
+}
+
+static int
+wl_iw_get_wap(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct sockaddr *awrq,
+	char *extra
+)
+{
+	WL_TRACE(("%s: SIOCGIWAP\n", dev->name));
+
+	awrq->sa_family = ARPHRD_ETHER;
+	memset(awrq->sa_data, 0, ETHER_ADDR_LEN);
+
+	(void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN);
+
+	return 0;
+}
+
+#if WIRELESS_EXT > 17
+static int
+wl_iw_mlme(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct sockaddr *awrq,
+	char *extra
+)
+{
+	struct iw_mlme *mlme;
+	scb_val_t scbval;
+	int error  = -EINVAL;
+
+	WL_TRACE(("%s: SIOCSIWMLME\n", dev->name));
+
+	mlme = (struct iw_mlme *)extra;
+	if (mlme == NULL) {
+		WL_ERROR(("Invalid ioctl data.\n"));
+		return error;
+	}
+
+	scbval.val = mlme->reason_code;
+	bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN);
+
+	if (mlme->cmd == IW_MLME_DISASSOC) {
+		scbval.val = htod32(scbval.val);
+		error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t));
+	}
+	else if (mlme->cmd == IW_MLME_DEAUTH) {
+		scbval.val = htod32(scbval.val);
+		error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval,
+			sizeof(scb_val_t));
+	}
+	else {
+		WL_ERROR(("%s: Invalid ioctl data.\n", __FUNCTION__));
+		return error;
+	}
+
+	return error;
+}
+#endif 
+
+static int
+wl_iw_get_aplist(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wl_scan_results_t *list;
+	struct sockaddr *addr = (struct sockaddr *) extra;
+	struct iw_quality qual[IW_MAX_AP];
+	wl_bss_info_t *bi = NULL;
+	int error, i;
+	uint buflen = dwrq->length;
+
+	WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name));
+
+	if (!extra)
+		return -EINVAL;
+
+	list = kmalloc(buflen, GFP_KERNEL);
+	if (!list)
+		return -ENOMEM;
+	memset(list, 0, buflen);
+	list->buflen = htod32(buflen);
+	if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) {
+		WL_ERROR(("%d: Scan results error %d\n", __LINE__, error));
+		kfree(list);
+		return error;
+	}
+	list->buflen = dtoh32(list->buflen);
+	list->version = dtoh32(list->version);
+	list->count = dtoh32(list->count);
+	ASSERT(list->version == WL_BSS_INFO_VERSION);
+
+	for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) {
+		bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info;
+		ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
+			buflen));
+
+		if (!(dtoh16(bi->capability) & DOT11_CAP_ESS))
+			continue;
+
+		memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN);
+		addr[dwrq->length].sa_family = ARPHRD_ETHER;
+		qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI));
+		qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI);
+		qual[dwrq->length].noise = 0x100 + bi->phy_noise;
+
+#if WIRELESS_EXT > 18
+		qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+#else
+		qual[dwrq->length].updated = 7;
+#endif 
+
+		dwrq->length++;
+	}
+
+	kfree(list);
+
+	if (dwrq->length) {
+		memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length);
+
+		dwrq->flags = 1;
+	}
+
+	return 0;
+}
+
+#if WIRELESS_EXT > 13
+static int
+wl_iw_set_scan(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	union iwreq_data *wrqu,
+	char *extra
+)
+{
+	wlc_ssid_t ssid;
+
+	WL_TRACE(("%s: SIOCSIWSCAN\n", dev->name));
+
+	memset(&ssid, 0, sizeof(ssid));
+
+#if WIRELESS_EXT > 17
+
+	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
+		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+			struct iw_scan_req *req = (struct iw_scan_req *)extra;
+			ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len);
+			memcpy(ssid.SSID, req->essid, ssid.SSID_len);
+			ssid.SSID_len = htod32(ssid.SSID_len);
+		}
+	}
+#endif
+
+	(void) dev_wlc_ioctl(dev, WLC_SCAN, &ssid, sizeof(ssid));
+
+	return 0;
+}
+
+#if WIRELESS_EXT > 17
+static bool
+ie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len)
+{
+
+	uint8 *ie = *wpaie;
+
+	if ((ie[1] >= 6) &&
+		!bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) {
+		return TRUE;
+	}
+
+	ie += ie[1] + 2;
+
+	*tlvs_len -= (int)(ie - *tlvs);
+
+	*tlvs = ie;
+	return FALSE;
+}
+
+static bool
+ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len)
+{
+
+	uint8 *ie = *wpsie;
+
+	if ((ie[1] >= 4) &&
+		!bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) {
+		return TRUE;
+	}
+
+	ie += ie[1] + 2;
+
+	*tlvs_len -= (int)(ie - *tlvs);
+
+	*tlvs = ie;
+	return FALSE;
+}
+#endif 
+
+static int
+wl_iw_handle_scanresults_ies(char **event_p, char *end,
+	struct iw_request_info *info, wl_bss_info_t *bi)
+{
+#if WIRELESS_EXT > 17
+	struct iw_event	iwe;
+	char *event;
+
+	event = *event_p;
+	if (bi->ie_length) {
+
+		bcm_tlv_t *ie;
+		uint8 *ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t);
+		int ptr_len = bi->ie_length;
+
+		if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) {
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.length = ie->len + 2;
+			event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie);
+		}
+		ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t);
+
+		while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {
+
+			if (ie_is_wps_ie(((uint8 **)&ie), &ptr, &ptr_len)) {
+				iwe.cmd = IWEVGENIE;
+				iwe.u.data.length = ie->len + 2;
+				event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie);
+				break;
+			}
+		}
+
+		ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t);
+		ptr_len = bi->ie_length;
+		while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {
+			if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) {
+				iwe.cmd = IWEVGENIE;
+				iwe.u.data.length = ie->len + 2;
+				event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie);
+				break;
+			}
+		}
+
+	*event_p = event;
+	}
+
+#endif 
+	return 0;
+}
+static int
+wl_iw_get_scan(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	channel_info_t ci;
+	wl_scan_results_t *list;
+	struct iw_event	iwe;
+	wl_bss_info_t *bi = NULL;
+	int error, i, j;
+	char *event = extra, *end = extra + dwrq->length, *value;
+	uint buflen = dwrq->length;
+
+	WL_TRACE(("%s: SIOCGIWSCAN\n", dev->name));
+
+	if (!extra)
+		return -EINVAL;
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci))))
+		return error;
+	ci.scan_channel = dtoh32(ci.scan_channel);
+	if (ci.scan_channel)
+		return -EAGAIN;
+
+	list = kmalloc(buflen, GFP_KERNEL);
+	if (!list)
+		return -ENOMEM;
+	memset(list, 0, buflen);
+	list->buflen = htod32(buflen);
+	if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) {
+		kfree(list);
+		return error;
+	}
+	list->buflen = dtoh32(list->buflen);
+	list->version = dtoh32(list->version);
+	list->count = dtoh32(list->count);
+
+	ASSERT(list->version == WL_BSS_INFO_VERSION);
+
+	for (i = 0; i < list->count && i < IW_MAX_AP; i++) {
+		bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info;
+		ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
+			buflen));
+
+		iwe.cmd = SIOCGIWAP;
+		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+		memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN);
+		event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN);
+
+		iwe.u.data.length = dtoh32(bi->SSID_len);
+		iwe.cmd = SIOCGIWESSID;
+		iwe.u.data.flags = 1;
+		event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
+
+		if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) {
+			iwe.cmd = SIOCGIWMODE;
+			if (dtoh16(bi->capability) & DOT11_CAP_ESS)
+				iwe.u.mode = IW_MODE_INFRA;
+			else
+				iwe.u.mode = IW_MODE_ADHOC;
+			event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN);
+		}
+
+		iwe.cmd = SIOCGIWFREQ;
+		iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec),
+			CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ?
+			WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
+		iwe.u.freq.e = 6;
+		event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
+
+		iwe.cmd = IWEVQUAL;
+		iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI));
+		iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI);
+		iwe.u.qual.noise = 0x100 + bi->phy_noise;
+		event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN);
+
+		 wl_iw_handle_scanresults_ies(&event, end, info, bi);
+
+		iwe.cmd = SIOCGIWENCODE;
+		if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY)
+			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+		else
+			iwe.u.data.flags = IW_ENCODE_DISABLED;
+		iwe.u.data.length = 0;
+		event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
+
+		if (bi->rateset.count) {
+			value = event + IW_EV_LCP_LEN;
+			iwe.cmd = SIOCGIWRATE;
+
+			iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+			for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
+				iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
+				value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
+					IW_EV_PARAM_LEN);
+			}
+			event = value;
+		}
+	}
+
+	kfree(list);
+
+	dwrq->length = event - extra;
+	dwrq->flags = 0;	
+
+	return 0;
+}
+
+#endif 
+
+static int
+wl_iw_set_essid(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wlc_ssid_t ssid;
+	int error;
+
+	WL_TRACE(("%s: SIOCSIWESSID\n", dev->name));
+
+	memset(&ssid, 0, sizeof(ssid));
+	if (dwrq->length && extra) {
+#if WIRELESS_EXT > 20
+		ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length);
+#else
+		ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length-1);
+#endif
+		memcpy(ssid.SSID, extra, ssid.SSID_len);
+		ssid.SSID_len = htod32(ssid.SSID_len);
+
+		if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid))))
+			return error;
+	}
+
+	else {
+		scb_val_t scbval;
+		bzero(&scbval, sizeof(scb_val_t));
+		if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t))))
+			return error;
+	}
+	return 0;
+}
+
+static int
+wl_iw_get_essid(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wlc_ssid_t ssid;
+	int error;
+
+	WL_TRACE(("%s: SIOCGIWESSID\n", dev->name));
+
+	if (!extra)
+		return -EINVAL;
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) {
+		WL_ERROR(("Error getting the SSID\n"));
+		return error;
+	}
+
+	ssid.SSID_len = dtoh32(ssid.SSID_len);
+
+	memcpy(extra, ssid.SSID, ssid.SSID_len);
+
+	dwrq->length = ssid.SSID_len;
+
+	dwrq->flags = 1; 
+
+	return 0;
+}
+
+static int
+wl_iw_set_nick(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wl_iw_t *iw = IW_DEV_IF(dev);
+	WL_TRACE(("%s: SIOCSIWNICKN\n", dev->name));
+
+	if (!extra)
+		return -EINVAL;
+
+	if (dwrq->length > sizeof(iw->nickname))
+		return -E2BIG;
+
+	memcpy(iw->nickname, extra, dwrq->length);
+	iw->nickname[dwrq->length - 1] = '\0';
+
+	return 0;
+}
+
+static int
+wl_iw_get_nick(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wl_iw_t *iw = IW_DEV_IF(dev);
+	WL_TRACE(("%s: SIOCGIWNICKN\n", dev->name));
+
+	if (!extra)
+		return -EINVAL;
+
+	strcpy(extra, iw->nickname);
+	dwrq->length = strlen(extra) + 1;
+
+	return 0;
+}
+
+static int wl_iw_set_rate(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	wl_rateset_t rateset;
+	int error, rate, i, error_bg, error_a;
+
+	WL_TRACE(("%s: SIOCSIWRATE\n", dev->name));
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset))))
+		return error;
+
+	rateset.count = dtoh32(rateset.count);
+
+	if (vwrq->value < 0) {
+
+		rate = rateset.rates[rateset.count - 1] & 0x7f;
+	} else if (vwrq->value < rateset.count) {
+
+		rate = rateset.rates[vwrq->value] & 0x7f;
+	} else {
+
+		rate = vwrq->value / 500000;
+	}
+
+	if (vwrq->fixed) {
+
+		error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate);
+		error_a = dev_wlc_intvar_set(dev, "a_rate", rate);
+
+		if (error_bg && error_a)
+			return (error_bg | error_a);
+	} else {
+
+		error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0);
+
+		error_a = dev_wlc_intvar_set(dev, "a_rate", 0);
+
+		if (error_bg && error_a)
+			return (error_bg | error_a);
+
+		for (i = 0; i < rateset.count; i++)
+			if ((rateset.rates[i] & 0x7f) > rate)
+				break;
+		rateset.count = htod32(i);
+
+		if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset))))
+			return error;
+	}
+
+	return 0;
+}
+
+static int wl_iw_get_rate(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, rate;
+
+	WL_TRACE(("%s: SIOCGIWRATE\n", dev->name));
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate))))
+		return error;
+	rate = dtoh32(rate);
+	vwrq->value = rate * 500000;
+
+	return 0;
+}
+
+static int
+wl_iw_set_rts(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, rts;
+
+	WL_TRACE(("%s: SIOCSIWRTS\n", dev->name));
+
+	if (vwrq->disabled)
+		rts = DOT11_DEFAULT_RTS_LEN;
+	else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN)
+		return -EINVAL;
+	else
+		rts = vwrq->value;
+
+	if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts)))
+		return error;
+
+	return 0;
+}
+
+static int
+wl_iw_get_rts(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, rts;
+
+	WL_TRACE(("%s: SIOCGIWRTS\n", dev->name));
+
+	if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts)))
+		return error;
+
+	vwrq->value = rts;
+	vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN);
+	vwrq->fixed = 1;
+
+	return 0;
+}
+
+static int
+wl_iw_set_frag(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, frag;
+
+	WL_TRACE(("%s: SIOCSIWFRAG\n", dev->name));
+
+	if (vwrq->disabled)
+		frag = DOT11_DEFAULT_FRAG_LEN;
+	else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN)
+		return -EINVAL;
+	else
+		frag = vwrq->value;
+
+	if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag)))
+		return error;
+
+	return 0;
+}
+
+static int
+wl_iw_get_frag(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, fragthreshold;
+
+	WL_TRACE(("%s: SIOCGIWFRAG\n", dev->name));
+
+	if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold)))
+		return error;
+
+	vwrq->value = fragthreshold;
+	vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN);
+	vwrq->fixed = 1;
+
+	return 0;
+}
+
+static int
+wl_iw_set_txpow(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, disable;
+	uint16 txpwrmw;
+	WL_TRACE(("%s: SIOCSIWTXPOW\n", dev->name));
+
+	disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0;
+	disable += WL_RADIO_SW_DISABLE << 16;
+
+	disable = htod32(disable);
+	if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable))))
+		return error;
+
+	if (disable & WL_RADIO_SW_DISABLE)
+		return 0;
+
+	if (!(vwrq->flags & IW_TXPOW_MWATT))
+		return -EINVAL;
+
+	if (vwrq->value < 0)
+		return 0;
+
+	if (vwrq->value > 0xffff) txpwrmw = 0xffff;
+	else txpwrmw = (uint16)vwrq->value;
+
+	error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw)));
+	return error;
+}
+
+static int
+wl_iw_get_txpow(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, disable, txpwrdbm;
+	uint8 result;
+
+	WL_TRACE(("%s: SIOCGIWTXPOW\n", dev->name));
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) ||
+	    (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm)))
+		return error;
+
+	disable = dtoh32(disable);
+	result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE);
+	vwrq->value = (int32)bcm_qdbm_to_mw(result);
+	vwrq->fixed = 0;
+	vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0;
+	vwrq->flags = IW_TXPOW_MWATT;
+
+	return 0;
+}
+
+#if WIRELESS_EXT > 10
+static int
+wl_iw_set_retry(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, lrl, srl;
+
+	WL_TRACE(("%s: SIOCSIWRETRY\n", dev->name));
+
+	if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME))
+		return -EINVAL;
+
+	if (vwrq->flags & IW_RETRY_LIMIT) {
+
+#if WIRELESS_EXT > 20
+		if ((vwrq->flags & IW_RETRY_LONG) ||(vwrq->flags & IW_RETRY_MAX) ||
+			!((vwrq->flags & IW_RETRY_SHORT) || (vwrq->flags & IW_RETRY_MIN))) {
+#else
+		if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) {
+#endif 
+
+			lrl = htod32(vwrq->value);
+			if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl))))
+				return error;
+		}
+
+#if WIRELESS_EXT > 20
+		if ((vwrq->flags & IW_RETRY_SHORT) ||(vwrq->flags & IW_RETRY_MIN) ||
+			!((vwrq->flags & IW_RETRY_LONG) || (vwrq->flags & IW_RETRY_MAX))) {
+#else
+		if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) {
+#endif 
+
+			srl = htod32(vwrq->value);
+			if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl))))
+				return error;
+		}
+	}
+
+	return 0;
+}
+
+static int
+wl_iw_get_retry(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, lrl, srl;
+
+	WL_TRACE(("%s: SIOCGIWRETRY\n", dev->name));
+
+	vwrq->disabled = 0;      
+
+	if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
+		return -EINVAL;
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) ||
+	    (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl))))
+		return error;
+
+	lrl = dtoh32(lrl);
+	srl = dtoh32(srl);
+
+	if (vwrq->flags & IW_RETRY_MAX) {
+		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+		vwrq->value = lrl;
+	} else {
+		vwrq->flags = IW_RETRY_LIMIT;
+		vwrq->value = srl;
+		if (srl != lrl)
+			vwrq->flags |= IW_RETRY_MIN;
+	}
+
+	return 0;
+}
+#endif 
+
+static int
+wl_iw_set_encode(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wl_wsec_key_t key;
+	int error, val, wsec;
+
+	WL_TRACE(("%s: SIOCSIWENCODE\n", dev->name));
+
+	memset(&key, 0, sizeof(key));
+
+	if ((dwrq->flags & IW_ENCODE_INDEX) == 0) {
+
+		for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) {
+			val = htod32(key.index);
+			if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val))))
+				return error;
+			val = dtoh32(val);
+			if (val)
+				break;
+		}
+
+		if (key.index == DOT11_MAX_DEFAULT_KEYS)
+			key.index = 0;
+	} else {
+		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+		if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+			return -EINVAL;
+	}
+
+	wsec = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED;
+
+	if ((error = dev_wlc_intvar_set(dev, "wsec", wsec)))
+		return error;
+
+	if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) {
+
+		val = htod32(key.index);
+		if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val))))
+			return error;
+	} else {
+		key.len = dwrq->length;
+
+		if (dwrq->length > sizeof(key.data))
+			return -EINVAL;
+
+		memcpy(key.data, extra, dwrq->length);
+
+		key.flags = WL_PRIMARY_KEY;
+		switch (key.len) {
+		case WEP1_KEY_SIZE:
+			key.algo = CRYPTO_ALGO_WEP1;
+			break;
+		case WEP128_KEY_SIZE:
+			key.algo = CRYPTO_ALGO_WEP128;
+			break;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+		case TKIP_KEY_SIZE:
+			key.algo = CRYPTO_ALGO_TKIP;
+			break;
+#endif
+		case AES_KEY_SIZE:
+			key.algo = CRYPTO_ALGO_AES_CCM;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		swap_key_from_BE(&key);
+		if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))
+			return error;
+	}
+
+	val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0;
+	val = htod32(val);
+	if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))
+		return error;
+
+	return 0;
+}
+
+static int
+wl_iw_get_encode(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wl_wsec_key_t key;
+	int error, val, wsec, auth;
+
+	WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name));
+
+	bzero(&key, sizeof(wl_wsec_key_t));
+
+	if ((dwrq->flags & IW_ENCODE_INDEX) == 0) {
+
+		for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) {
+			val = key.index;
+			if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val))))
+				return error;
+			val = dtoh32(val);
+			if (val)
+				break;
+		}
+	} else
+		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+
+	if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+		key.index = 0;
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) ||
+	    (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth))))
+		return error;
+
+	swap_key_to_BE(&key);
+
+	wsec = dtoh32(wsec);
+	auth = dtoh32(auth);
+
+	dwrq->length = MIN(IW_ENCODING_TOKEN_MAX, key.len);
+
+	dwrq->flags = key.index + 1;
+	if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) {
+
+		dwrq->flags |= IW_ENCODE_DISABLED;
+	}
+	if (auth) {
+
+		dwrq->flags |= IW_ENCODE_RESTRICTED;
+	}
+
+	if (dwrq->length && extra)
+		memcpy(extra, key.data, dwrq->length);
+
+	return 0;
+}
+
+static int
+wl_iw_set_power(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, pm;
+
+	WL_TRACE(("%s: SIOCSIWPOWER\n", dev->name));
+
+	pm = vwrq->disabled ? PM_OFF : PM_MAX;
+
+	pm = htod32(pm);
+	if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm))))
+		return error;
+
+	return 0;
+}
+
+static int
+wl_iw_get_power(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error, pm;
+
+	WL_TRACE(("%s: SIOCGIWPOWER\n", dev->name));
+
+	if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))))
+		return error;
+
+	pm = dtoh32(pm);
+	vwrq->disabled = pm ? 0 : 1;
+	vwrq->flags = IW_POWER_ALL_R;
+
+	return 0;
+}
+
+#if WIRELESS_EXT > 17
+static int
+wl_iw_set_wpaie(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *iwp,
+	char *extra
+)
+{
+		dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length);
+
+	return 0;
+}
+
+static int
+wl_iw_get_wpaie(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *iwp,
+	char *extra
+)
+{
+	WL_TRACE(("%s: SIOCGIWGENIE\n", dev->name));
+	iwp->length = 64;
+	dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length);
+	return 0;
+}
+
+static int
+wl_iw_set_encodeext(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_point *dwrq,
+	char *extra
+)
+{
+	wl_wsec_key_t key;
+	int error;
+	struct iw_encode_ext *iwe;
+
+	WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name));
+
+	memset(&key, 0, sizeof(key));
+	iwe = (struct iw_encode_ext *)extra;
+
+	if (dwrq->flags & IW_ENCODE_DISABLED) {
+
+	}
+
+	key.index = 0;
+	if (dwrq->flags & IW_ENCODE_INDEX)
+		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+
+	key.len = iwe->key_len;
+
+	if (!ETHER_ISMULTI(iwe->addr.sa_data))
+		bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN);
+
+	if (key.len == 0) {
+		if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+			WL_WSEC(("Changing the the primary Key to %d\n", key.index));
+
+			key.index = htod32(key.index);
+			error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY,
+				&key.index, sizeof(key.index));
+			if (error)
+				return error;
+		}
+
+		else {
+			swap_key_from_BE(&key);
+			dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+		}
+	}
+
+	else {
+		if (iwe->key_len > sizeof(key.data))
+			return -EINVAL;
+
+		WL_WSEC(("Setting the key index %d\n", key.index));
+		if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+			WL_WSEC(("key is a Primary Key\n"));
+			key.flags = WL_PRIMARY_KEY;
+		}
+
+		bcopy((void *)iwe->key, key.data, iwe->key_len);
+
+		if (iwe->alg == IW_ENCODE_ALG_TKIP) {
+			uint8 keybuf[8];
+			bcopy(&key.data[24], keybuf, sizeof(keybuf));
+			bcopy(&key.data[16], &key.data[24], sizeof(keybuf));
+			bcopy(keybuf, &key.data[16], sizeof(keybuf));
+		}
+
+		if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+			uchar *ivptr;
+			ivptr = (uchar *)iwe->rx_seq;
+			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
+				(ivptr[3] << 8) | ivptr[2];
+			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
+			key.iv_initialized = TRUE;
+		}
+
+		switch (iwe->alg) {
+			case IW_ENCODE_ALG_NONE:
+				key.algo = CRYPTO_ALGO_OFF;
+				break;
+			case IW_ENCODE_ALG_WEP:
+				if (iwe->key_len == WEP1_KEY_SIZE)
+					key.algo = CRYPTO_ALGO_WEP1;
+				else
+					key.algo = CRYPTO_ALGO_WEP128;
+				break;
+			case IW_ENCODE_ALG_TKIP:
+				key.algo = CRYPTO_ALGO_TKIP;
+				break;
+			case IW_ENCODE_ALG_CCMP:
+				key.algo = CRYPTO_ALGO_AES_CCM;
+				break;
+			default:
+				break;
+		}
+		swap_key_from_BE(&key);
+
+		error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+		if (error)
+			return error;
+	}
+	return 0;
+}
+
+#if WIRELESS_EXT > 17
+struct {
+	pmkid_list_t pmkids;
+	pmkid_t foo[MAXPMKID-1];
+} pmkid_list;
+static int
+wl_iw_set_pmksa(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	struct iw_pmksa *iwpmksa;
+	uint i;
+	char eabuf[ETHER_ADDR_STR_LEN];
+	pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid;
+
+	WL_TRACE(("%s: SIOCSIWPMKSA\n", dev->name));
+	iwpmksa = (struct iw_pmksa *)extra;
+	bzero((char *)eabuf, ETHER_ADDR_STR_LEN);
+	if (iwpmksa->cmd == IW_PMKSA_FLUSH) {
+		WL_TRACE(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n"));
+		bzero((char *)&pmkid_list, sizeof(pmkid_list));
+	}
+	if (iwpmksa->cmd == IW_PMKSA_REMOVE) {
+		pmkid_list_t pmkid, *pmkidptr;
+		pmkidptr = &pmkid;
+		bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, ETHER_ADDR_LEN);
+		bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN);
+		{
+			uint j;
+			WL_TRACE(("wl_iw_set_pmksa,IW_PMKSA_REMOVE - PMKID: %s = ",
+				bcm_ether_ntoa(&pmkidptr->pmkid[0].BSSID,
+				eabuf)));
+			for (j = 0; j < WPA2_PMKID_LEN; j++)
+				WL_TRACE(("%02x ", pmkidptr->pmkid[0].PMKID[j]));
+			WL_TRACE(("\n"));
+		}
+		for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
+			if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID,
+				ETHER_ADDR_LEN))
+				break;
+		for (; i < pmkid_list.pmkids.npmkid; i++) {
+			bcopy(&pmkid_array[i+1].BSSID,
+				&pmkid_array[i].BSSID,
+				ETHER_ADDR_LEN);
+			bcopy(&pmkid_array[i+1].PMKID,
+				&pmkid_array[i].PMKID,
+				WPA2_PMKID_LEN);
+		}
+		pmkid_list.pmkids.npmkid--;
+	}
+	if (iwpmksa->cmd == IW_PMKSA_ADD) {
+		bcopy(&iwpmksa->bssid.sa_data[0],
+			&pmkid_array[pmkid_list.pmkids.npmkid].BSSID,
+			ETHER_ADDR_LEN);
+		bcopy(&iwpmksa->pmkid[0], &pmkid_array[pmkid_list.pmkids.npmkid].PMKID,
+			WPA2_PMKID_LEN);
+		{
+			uint j;
+			uint k;
+			k = pmkid_list.pmkids.npmkid;
+			BCM_REFERENCE(k);
+			WL_TRACE(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ",
+				bcm_ether_ntoa(&pmkid_array[k].BSSID,
+				eabuf)));
+			for (j = 0; j < WPA2_PMKID_LEN; j++)
+				WL_TRACE(("%02x ", pmkid_array[k].PMKID[j]));
+			WL_TRACE(("\n"));
+		}
+		pmkid_list.pmkids.npmkid++;
+	}
+	WL_TRACE(("PRINTING pmkid LIST - No of elements %d\n", pmkid_list.pmkids.npmkid));
+	for (i = 0; i < pmkid_list.pmkids.npmkid; i++) {
+		uint j;
+		WL_TRACE(("PMKID[%d]: %s = ", i,
+			bcm_ether_ntoa(&pmkid_array[i].BSSID,
+			eabuf)));
+		for (j = 0; j < WPA2_PMKID_LEN; j++)
+			WL_TRACE(("%02x ", pmkid_array[i].PMKID[j]));
+		printf("\n");
+	}
+	WL_TRACE(("\n"));
+	dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, sizeof(pmkid_list));
+	return 0;
+}
+#endif 
+
+static int
+wl_iw_get_encodeext(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	WL_TRACE(("%s: SIOCGIWENCODEEXT\n", dev->name));
+	return 0;
+}
+
+static int
+wl_iw_set_wpaauth(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error = 0;
+	int paramid;
+	int paramval;
+	uint32 cipher_combined;
+	int val = 0;
+	wl_iw_t *iw = IW_DEV_IF(dev);
+
+	WL_TRACE(("%s: SIOCSIWAUTH\n", dev->name));
+
+	paramid = vwrq->flags & IW_AUTH_INDEX;
+	paramval = vwrq->value;
+
+	WL_TRACE(("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n",
+		dev->name, paramid, paramval));
+
+	switch (paramid) {
+
+	case IW_AUTH_WPA_VERSION:
+
+		if (paramval & IW_AUTH_WPA_VERSION_DISABLED)
+			val = WPA_AUTH_DISABLED;
+		else if (paramval & (IW_AUTH_WPA_VERSION_WPA))
+			val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
+		else if (paramval & IW_AUTH_WPA_VERSION_WPA2)
+			val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+		WL_TRACE(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val));
+		if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val)))
+			return error;
+		break;
+
+	case IW_AUTH_CIPHER_PAIRWISE:
+	case IW_AUTH_CIPHER_GROUP:
+
+		if (paramid == IW_AUTH_CIPHER_PAIRWISE) {
+			iw->pwsec = paramval;
+		}
+		else {
+			iw->gwsec = paramval;
+		}
+
+		if ((error = dev_wlc_intvar_get(dev, "wsec", &val)))
+			return error;
+
+		cipher_combined = iw->gwsec | iw->pwsec;
+		val &= ~(WEP_ENABLED | TKIP_ENABLED | AES_ENABLED);
+		if (cipher_combined & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
+			val |= WEP_ENABLED;
+		if (cipher_combined & IW_AUTH_CIPHER_TKIP)
+			val |= TKIP_ENABLED;
+		if (cipher_combined & IW_AUTH_CIPHER_CCMP)
+			val |= AES_ENABLED;
+
+		if (iw->privacy_invoked && !val) {
+			WL_WSEC(("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming "
+			         "we're a WPS enrollee\n", dev->name, __FUNCTION__));
+			if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) {
+				WL_WSEC(("Failed to set iovar is_WPS_enrollee\n"));
+				return error;
+			}
+		} else if (val) {
+			if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) {
+				WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n"));
+				return error;
+			}
+		}
+
+		if ((error = dev_wlc_intvar_set(dev, "wsec", val)))
+			return error;
+		break;
+
+	case IW_AUTH_KEY_MGMT:
+		if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+			return error;
+
+		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
+			if (paramval & IW_AUTH_KEY_MGMT_PSK)
+				val = WPA_AUTH_PSK;
+			else
+				val = WPA_AUTH_UNSPECIFIED;
+		}
+		else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
+			if (paramval & IW_AUTH_KEY_MGMT_PSK)
+				val = WPA2_AUTH_PSK;
+			else
+				val = WPA2_AUTH_UNSPECIFIED;
+		}
+		WL_TRACE(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val));
+		if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val)))
+			return error;
+		break;
+
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		dev_wlc_bufvar_set(dev, "tkip_countermeasures", (char *)&paramval, 1);
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+
+		WL_ERROR(("Setting the D11auth %d\n", paramval));
+		if (paramval & IW_AUTH_ALG_OPEN_SYSTEM)
+			val = 0;
+		else if (paramval & IW_AUTH_ALG_SHARED_KEY)
+			val = 1;
+		else
+			error = 1;
+		if (!error && (error = dev_wlc_intvar_set(dev, "auth", val)))
+			return error;
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		if (paramval == 0) {
+			val = 0;
+			WL_TRACE(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val));
+			error = dev_wlc_intvar_set(dev, "wpa_auth", val);
+			return error;
+		}
+		else {
+
+		}
+		break;
+
+	case IW_AUTH_DROP_UNENCRYPTED:
+		dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)&paramval, 1);
+		break;
+
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", (char *)&paramval, 1);
+		break;
+
+#if WIRELESS_EXT > 17
+
+	case IW_AUTH_ROAMING_CONTROL:
+		WL_TRACE(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__));
+
+		break;
+
+	case IW_AUTH_PRIVACY_INVOKED: {
+		int wsec;
+
+		if (paramval == 0) {
+			iw->privacy_invoked = FALSE;
+			if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) {
+				WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n"));
+				return error;
+			}
+		} else {
+			iw->privacy_invoked = TRUE;
+			if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec)))
+				return error;
+
+			if (!WSEC_ENABLED(wsec)) {
+
+				if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) {
+					WL_WSEC(("Failed to set iovar is_WPS_enrollee\n"));
+					return error;
+				}
+			} else {
+				if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) {
+					WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n"));
+					return error;
+				}
+			}
+		}
+		break;
+	}
+
+#endif 
+
+	default:
+		break;
+	}
+	return 0;
+}
+#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK))
+
+static int
+wl_iw_get_wpaauth(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	struct iw_param *vwrq,
+	char *extra
+)
+{
+	int error;
+	int paramid;
+	int paramval = 0;
+	int val;
+	wl_iw_t *iw = IW_DEV_IF(dev);
+
+	WL_TRACE(("%s: SIOCGIWAUTH\n", dev->name));
+
+	paramid = vwrq->flags & IW_AUTH_INDEX;
+
+	switch (paramid) {
+	case IW_AUTH_WPA_VERSION:
+
+		if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+			return error;
+		if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED))
+			paramval = IW_AUTH_WPA_VERSION_DISABLED;
+		else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED))
+			paramval = IW_AUTH_WPA_VERSION_WPA;
+		else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED))
+			paramval = IW_AUTH_WPA_VERSION_WPA2;
+		break;
+
+	case IW_AUTH_CIPHER_PAIRWISE:
+		paramval = iw->pwsec;
+		break;
+
+	case IW_AUTH_CIPHER_GROUP:
+		paramval = iw->gwsec;
+		break;
+
+	case IW_AUTH_KEY_MGMT:
+
+		if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+			return error;
+		if (VAL_PSK(val))
+			paramval = IW_AUTH_KEY_MGMT_PSK;
+		else
+			paramval = IW_AUTH_KEY_MGMT_802_1X;
+
+		break;
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		dev_wlc_bufvar_get(dev, "tkip_countermeasures", (char *)&paramval, 1);
+		break;
+
+	case IW_AUTH_DROP_UNENCRYPTED:
+		dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)&paramval, 1);
+		break;
+
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", (char *)&paramval, 1);
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+
+		if ((error = dev_wlc_intvar_get(dev, "auth", &val)))
+			return error;
+		if (!val)
+			paramval = IW_AUTH_ALG_OPEN_SYSTEM;
+		else
+			paramval = IW_AUTH_ALG_SHARED_KEY;
+		break;
+	case IW_AUTH_WPA_ENABLED:
+		if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+			return error;
+		if (val)
+			paramval = TRUE;
+		else
+			paramval = FALSE;
+		break;
+
+#if WIRELESS_EXT > 17
+
+	case IW_AUTH_ROAMING_CONTROL:
+		WL_ERROR(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__));
+
+		break;
+
+	case IW_AUTH_PRIVACY_INVOKED:
+		paramval = iw->privacy_invoked;
+		break;
+
+#endif 
+	}
+	vwrq->value = paramval;
+	return 0;
+}
+#endif 
+
+static const iw_handler wl_iw_handler[] =
+{
+	(iw_handler) wl_iw_config_commit,	
+	(iw_handler) wl_iw_get_name,		
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) wl_iw_set_freq,		
+	(iw_handler) wl_iw_get_freq,		
+	(iw_handler) wl_iw_set_mode,		
+	(iw_handler) wl_iw_get_mode,		
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) wl_iw_get_range,		
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) wl_iw_set_spy,		
+	(iw_handler) wl_iw_get_spy,		
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) wl_iw_set_wap,		
+	(iw_handler) wl_iw_get_wap,		
+#if WIRELESS_EXT > 17
+	(iw_handler) wl_iw_mlme,		
+#else
+	(iw_handler) NULL,			
+#endif
+	(iw_handler) wl_iw_get_aplist,		
+#if WIRELESS_EXT > 13
+	(iw_handler) wl_iw_set_scan,		
+	(iw_handler) wl_iw_get_scan,		
+#else	
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+#endif	
+	(iw_handler) wl_iw_set_essid,		
+	(iw_handler) wl_iw_get_essid,		
+	(iw_handler) wl_iw_set_nick,		
+	(iw_handler) wl_iw_get_nick,		
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) wl_iw_set_rate,		
+	(iw_handler) wl_iw_get_rate,		
+	(iw_handler) wl_iw_set_rts,		
+	(iw_handler) wl_iw_get_rts,		
+	(iw_handler) wl_iw_set_frag,		
+	(iw_handler) wl_iw_get_frag,		
+	(iw_handler) wl_iw_set_txpow,		
+	(iw_handler) wl_iw_get_txpow,		
+#if WIRELESS_EXT > 10
+	(iw_handler) wl_iw_set_retry,		
+	(iw_handler) wl_iw_get_retry,		
+#endif 
+	(iw_handler) wl_iw_set_encode,		
+	(iw_handler) wl_iw_get_encode,		
+	(iw_handler) wl_iw_set_power,		
+	(iw_handler) wl_iw_get_power,		
+#if WIRELESS_EXT > 17
+	(iw_handler) NULL,			
+	(iw_handler) NULL,			
+	(iw_handler) wl_iw_set_wpaie,		
+	(iw_handler) wl_iw_get_wpaie,		
+	(iw_handler) wl_iw_set_wpaauth,		
+	(iw_handler) wl_iw_get_wpaauth,		
+	(iw_handler) wl_iw_set_encodeext,	
+	(iw_handler) wl_iw_get_encodeext,	
+	(iw_handler) wl_iw_set_pmksa,		
+#endif 
+};
+
+#if WIRELESS_EXT > 12
+enum {
+	WL_IW_SET_LEDDC = SIOCIWFIRSTPRIV,
+	WL_IW_SET_VLANMODE,
+	WL_IW_SET_PM
+};
+
+static iw_handler wl_iw_priv_handler[] = {
+	wl_iw_set_leddc,
+	wl_iw_set_vlanmode,
+	wl_iw_set_pm
+};
+
+static struct iw_priv_args wl_iw_priv_args[] = {
+	{
+		WL_IW_SET_LEDDC,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0,
+		"set_leddc"
+	},
+	{
+		WL_IW_SET_VLANMODE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0,
+		"set_vlanmode"
+	},
+	{
+		WL_IW_SET_PM,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0,
+		"set_pm"
+	}
+};
+
+const struct iw_handler_def wl_iw_handler_def =
+{
+	.num_standard = ARRAYSIZE(wl_iw_handler),
+	.num_private = ARRAY_SIZE(wl_iw_priv_handler),
+	.num_private_args = ARRAY_SIZE(wl_iw_priv_args),
+	.standard = (iw_handler *) wl_iw_handler,
+	.private = wl_iw_priv_handler,
+	.private_args = wl_iw_priv_args,
+#if WIRELESS_EXT >= 19
+	get_wireless_stats: wl_get_wireless_stats,
+#endif 
+	};
+#endif 
+
+int
+wl_iw_ioctl(
+	struct net_device *dev,
+	struct ifreq *rq,
+	int cmd
+)
+{
+	struct iwreq *wrq = (struct iwreq *) rq;
+	struct iw_request_info info;
+	iw_handler handler;
+	char *extra = NULL;
+	size_t token_size = 1;
+	int max_tokens = 0, ret = 0;
+
+	if (cmd < SIOCIWFIRST ||
+		IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) ||
+		!(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)]))
+		return -EOPNOTSUPP;
+
+	switch (cmd) {
+
+	case SIOCSIWESSID:
+	case SIOCGIWESSID:
+	case SIOCSIWNICKN:
+	case SIOCGIWNICKN:
+		max_tokens = IW_ESSID_MAX_SIZE + 1;
+		break;
+
+	case SIOCSIWENCODE:
+	case SIOCGIWENCODE:
+#if WIRELESS_EXT > 17
+	case SIOCSIWENCODEEXT:
+	case SIOCGIWENCODEEXT:
+#endif
+		max_tokens = IW_ENCODING_TOKEN_MAX;
+		break;
+
+	case SIOCGIWRANGE:
+		max_tokens = sizeof(struct iw_range);
+		break;
+
+	case SIOCGIWAPLIST:
+		token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality);
+		max_tokens = IW_MAX_AP;
+		break;
+
+#if WIRELESS_EXT > 13
+	case SIOCGIWSCAN:
+		max_tokens = IW_SCAN_MAX_DATA;
+		break;
+#endif 
+
+	case SIOCSIWSPY:
+		token_size = sizeof(struct sockaddr);
+		max_tokens = IW_MAX_SPY;
+		break;
+
+	case SIOCGIWSPY:
+		token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality);
+		max_tokens = IW_MAX_SPY;
+		break;
+	default:
+		break;
+	}
+
+	if (max_tokens && wrq->u.data.pointer) {
+		if (wrq->u.data.length > max_tokens)
+			return -E2BIG;
+
+		if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL)))
+			return -ENOMEM;
+
+		if (copy_from_user(extra, wrq->u.data.pointer, wrq->u.data.length * token_size)) {
+			kfree(extra);
+			return -EFAULT;
+		}
+	}
+
+	info.cmd = cmd;
+	info.flags = 0;
+
+	ret = handler(dev, &info, &wrq->u, extra);
+
+	if (extra) {
+		if (copy_to_user(wrq->u.data.pointer, extra, wrq->u.data.length * token_size)) {
+			kfree(extra);
+			return -EFAULT;
+		}
+
+		kfree(extra);
+	}
+
+	return ret;
+}
+
+bool
+wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason,
+	char* stringBuf, uint buflen)
+{
+	typedef struct conn_fail_event_map_t {
+		uint32 inEvent;			
+		uint32 inStatus;		
+		uint32 inReason;		
+		const char* outName;	
+		const char* outCause;	
+	} conn_fail_event_map_t;
+
+#	define WL_IW_DONT_CARE	9999
+	const conn_fail_event_map_t event_map [] = {
+
+		{WLC_E_SET_SSID,     WLC_E_STATUS_SUCCESS,   WL_IW_DONT_CARE,
+		"Conn", "Success"},
+		{WLC_E_SET_SSID,     WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE,
+		"Conn", "NoNetworks"},
+		{WLC_E_SET_SSID,     WLC_E_STATUS_FAIL,      WL_IW_DONT_CARE,
+		"Conn", "ConfigMismatch"},
+		{WLC_E_PRUNE,        WL_IW_DONT_CARE,        WLC_E_PRUNE_ENCR_MISMATCH,
+		"Conn", "EncrypMismatch"},
+		{WLC_E_PRUNE,        WL_IW_DONT_CARE,        WLC_E_RSN_MISMATCH,
+		"Conn", "RsnMismatch"},
+		{WLC_E_AUTH,         WLC_E_STATUS_TIMEOUT,   WL_IW_DONT_CARE,
+		"Conn", "AuthTimeout"},
+		{WLC_E_AUTH,         WLC_E_STATUS_FAIL,      WL_IW_DONT_CARE,
+		"Conn", "AuthFail"},
+		{WLC_E_AUTH,         WLC_E_STATUS_NO_ACK,    WL_IW_DONT_CARE,
+		"Conn", "AuthNoAck"},
+		{WLC_E_REASSOC,      WLC_E_STATUS_FAIL,      WL_IW_DONT_CARE,
+		"Conn", "ReassocFail"},
+		{WLC_E_REASSOC,      WLC_E_STATUS_TIMEOUT,   WL_IW_DONT_CARE,
+		"Conn", "ReassocTimeout"},
+		{WLC_E_REASSOC,      WLC_E_STATUS_ABORT,     WL_IW_DONT_CARE,
+		"Conn", "ReassocAbort"},
+		{WLC_E_DEAUTH_IND,   WL_IW_DONT_CARE,        WL_IW_DONT_CARE,
+		"Conn", "Deauth"},
+		{WLC_E_DISASSOC_IND, WL_IW_DONT_CARE,        WL_IW_DONT_CARE,
+		"Conn", "DisassocInd"},
+		{WLC_E_DISASSOC,     WL_IW_DONT_CARE,        WL_IW_DONT_CARE,
+		"Conn", "Disassoc"}
+	};
+
+	const char* name = "";
+	const char* cause = NULL;
+	int i;
+
+	for (i = 0;  i < sizeof(event_map)/sizeof(event_map[0]);  i++) {
+		const conn_fail_event_map_t* row = &event_map[i];
+		if (row->inEvent == event_type &&
+		    (row->inStatus == status || row->inStatus == WL_IW_DONT_CARE) &&
+		    (row->inReason == reason || row->inReason == WL_IW_DONT_CARE)) {
+			name = row->outName;
+			cause = row->outCause;
+			break;
+		}
+	}
+
+	if (cause) {
+		memset(stringBuf, 0, buflen);
+		snprintf(stringBuf, buflen, "%s %s %02d %02d",
+			name, cause, status, reason);
+		WL_TRACE(("Connection status: %s\n", stringBuf));
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+#if (WIRELESS_EXT > 14)
+
+static bool
+wl_iw_check_conn_fail(wl_event_msg_t *e, char* stringBuf, uint buflen)
+{
+	uint32 event = e->event_type;
+	uint32 status =  e->status;
+	uint32 reason =  e->reason;
+
+	if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) {
+		return TRUE;
+	} else
+	{
+		return FALSE;
+	}
+}
+#endif 
+
+#ifndef IW_CUSTOM_MAX
+#define IW_CUSTOM_MAX 256 
+#endif 
+
+void
+wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
+{
+#if WIRELESS_EXT > 13
+	union iwreq_data wrqu;
+	char extra[IW_CUSTOM_MAX + 1];
+	int cmd = 0;
+	uint32 event_type = e->event_type;
+	uint16 flags =  e->flags;
+	uint32 datalen = e->datalen;
+	uint32 status =  e->status;
+
+	memset(&wrqu, 0, sizeof(wrqu));
+	memset(extra, 0, sizeof(extra));
+
+	memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN);
+	wrqu.addr.sa_family = ARPHRD_ETHER;
+
+	switch (event_type) {
+	case WLC_E_TXFAIL:
+		cmd = IWEVTXDROP;
+		break;
+#if WIRELESS_EXT > 14
+	case WLC_E_JOIN:
+	case WLC_E_ASSOC_IND:
+	case WLC_E_REASSOC_IND:
+		cmd = IWEVREGISTERED;
+		break;
+	case WLC_E_DEAUTH_IND:
+	case WLC_E_DISASSOC_IND:
+		cmd = SIOCGIWAP;
+		wrqu.data.length = strlen(extra);
+		bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
+		bzero(&extra, ETHER_ADDR_LEN);
+		break;
+
+	case WLC_E_LINK:
+	case WLC_E_NDIS_LINK:
+		cmd = SIOCGIWAP;
+		wrqu.data.length = strlen(extra);
+		if (!(flags & WLC_EVENT_MSG_LINK)) {
+			bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
+			bzero(&extra, ETHER_ADDR_LEN);
+		}
+		break;
+	case WLC_E_ACTION_FRAME:
+		cmd = IWEVCUSTOM;
+		if (datalen + 1 <= sizeof(extra)) {
+			wrqu.data.length = datalen + 1;
+			extra[0] = WLC_E_ACTION_FRAME;
+			memcpy(&extra[1], data, datalen);
+			WL_TRACE(("WLC_E_ACTION_FRAME len %d \n", wrqu.data.length));
+		}
+		break;
+
+	case WLC_E_ACTION_FRAME_COMPLETE:
+		cmd = IWEVCUSTOM;
+		if (sizeof(status) + 1 <= sizeof(extra)) {
+			wrqu.data.length = sizeof(status) + 1;
+			extra[0] = WLC_E_ACTION_FRAME_COMPLETE;
+			memcpy(&extra[1], &status, sizeof(status));
+			WL_TRACE(("wl_iw_event status %d  \n", status));
+		}
+		break;
+#endif 
+#if WIRELESS_EXT > 17
+	case WLC_E_MIC_ERROR: {
+		struct	iw_michaelmicfailure  *micerrevt = (struct  iw_michaelmicfailure  *)&extra;
+		cmd = IWEVMICHAELMICFAILURE;
+		wrqu.data.length = sizeof(struct iw_michaelmicfailure);
+		if (flags & WLC_EVENT_MSG_GROUP)
+			micerrevt->flags |= IW_MICFAILURE_GROUP;
+		else
+			micerrevt->flags |= IW_MICFAILURE_PAIRWISE;
+		memcpy(micerrevt->src_addr.sa_data, &e->addr, ETHER_ADDR_LEN);
+		micerrevt->src_addr.sa_family = ARPHRD_ETHER;
+
+		break;
+	}
+
+	case WLC_E_ASSOC_REQ_IE:
+		cmd = IWEVASSOCREQIE;
+		wrqu.data.length = datalen;
+		if (datalen < sizeof(extra))
+			memcpy(extra, data, datalen);
+		break;
+
+	case WLC_E_ASSOC_RESP_IE:
+		cmd = IWEVASSOCRESPIE;
+		wrqu.data.length = datalen;
+		if (datalen < sizeof(extra))
+			memcpy(extra, data, datalen);
+		break;
+
+	case WLC_E_PMKID_CACHE: {
+		struct iw_pmkid_cand *iwpmkidcand = (struct iw_pmkid_cand *)&extra;
+		pmkid_cand_list_t *pmkcandlist;
+		pmkid_cand_t	*pmkidcand;
+		int count;
+
+		if (data == NULL)
+			break;
+
+		cmd = IWEVPMKIDCAND;
+		pmkcandlist = data;
+		count = ntoh32_ua((uint8 *)&pmkcandlist->npmkid_cand);
+		wrqu.data.length = sizeof(struct iw_pmkid_cand);
+		pmkidcand = pmkcandlist->pmkid_cand;
+		while (count) {
+			bzero(iwpmkidcand, sizeof(struct iw_pmkid_cand));
+			if (pmkidcand->preauth)
+				iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH;
+			bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data,
+			      ETHER_ADDR_LEN);
+			wireless_send_event(dev, cmd, &wrqu, extra);
+			pmkidcand++;
+			count--;
+		}
+		break;
+	}
+#endif 
+
+	case WLC_E_SCAN_COMPLETE:
+#if WIRELESS_EXT > 14
+		cmd = SIOCGIWSCAN;
+#endif
+		break;
+
+	default:
+
+		break;
+	}
+
+	if (cmd) {
+		if (cmd == SIOCGIWSCAN)
+			wireless_send_event(dev, cmd, &wrqu, NULL);
+		else
+			wireless_send_event(dev, cmd, &wrqu, extra);
+	}
+
+#if WIRELESS_EXT > 14
+
+	memset(extra, 0, sizeof(extra));
+	if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) {
+		cmd = IWEVCUSTOM;
+		wrqu.data.length = strlen(extra);
+		wireless_send_event(dev, cmd, &wrqu, extra);
+	}
+#endif 
+
+#endif 
+}
+
+int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
+{
+	int res = 0;
+	wl_cnt_t cnt;
+	int phy_noise;
+	int rssi;
+	scb_val_t scb_val;
+
+	phy_noise = 0;
+	if ((res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, sizeof(phy_noise))))
+		goto done;
+
+	phy_noise = dtoh32(phy_noise);
+	WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n *****", phy_noise));
+
+	scb_val.val = 0;
+	if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t))))
+		goto done;
+
+	rssi = dtoh32(scb_val.val);
+	WL_TRACE(("wl_iw_get_wireless_stats rssi=%d ****** \n", rssi));
+	if (rssi <= WL_IW_RSSI_NO_SIGNAL)
+		wstats->qual.qual = 0;
+	else if (rssi <= WL_IW_RSSI_VERY_LOW)
+		wstats->qual.qual = 1;
+	else if (rssi <= WL_IW_RSSI_LOW)
+		wstats->qual.qual = 2;
+	else if (rssi <= WL_IW_RSSI_GOOD)
+		wstats->qual.qual = 3;
+	else if (rssi <= WL_IW_RSSI_VERY_GOOD)
+		wstats->qual.qual = 4;
+	else
+		wstats->qual.qual = 5;
+
+	wstats->qual.level = 0x100 + rssi;
+	wstats->qual.noise = 0x100 + phy_noise;
+#if WIRELESS_EXT > 18
+	wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM);
+#else
+	wstats->qual.updated |= 7;
+#endif 
+
+#if WIRELESS_EXT > 11
+	WL_TRACE(("wl_iw_get_wireless_stats counters=%d\n *****", (int)sizeof(wl_cnt_t)));
+
+	memset(&cnt, 0, sizeof(wl_cnt_t));
+	res = dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t));
+	if (res)
+	{
+		WL_ERROR(("wl_iw_get_wireless_stats counters failed error=%d ****** \n", res));
+		goto done;
+	}
+
+	cnt.version = dtoh16(cnt.version);
+	if (cnt.version != WL_CNT_T_VERSION) {
+		WL_TRACE(("\tIncorrect version of counters struct: expected %d; got %d\n",
+			WL_CNT_T_VERSION, cnt.version));
+		goto done;
+	}
+
+	wstats->discard.nwid = 0;
+	wstats->discard.code = dtoh32(cnt.rxundec);
+	wstats->discard.fragment = dtoh32(cnt.rxfragerr);
+	wstats->discard.retries = dtoh32(cnt.txfail);
+	wstats->discard.misc = dtoh32(cnt.rxrunt) + dtoh32(cnt.rxgiant);
+	wstats->miss.beacon = 0;
+
+	WL_TRACE(("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n",
+		dtoh32(cnt.txframe), dtoh32(cnt.txbyte)));
+	WL_TRACE(("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", dtoh32(cnt.rxfrmtoolong)));
+	WL_TRACE(("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", dtoh32(cnt.rxbadplcp)));
+	WL_TRACE(("wl_iw_get_wireless_stats counters rxundec=%d\n", dtoh32(cnt.rxundec)));
+	WL_TRACE(("wl_iw_get_wireless_stats counters rxfragerr=%d\n", dtoh32(cnt.rxfragerr)));
+	WL_TRACE(("wl_iw_get_wireless_stats counters txfail=%d\n", dtoh32(cnt.txfail)));
+	WL_TRACE(("wl_iw_get_wireless_stats counters rxrunt=%d\n", dtoh32(cnt.rxrunt)));
+	WL_TRACE(("wl_iw_get_wireless_stats counters rxgiant=%d\n", dtoh32(cnt.rxgiant)));
+
+#endif 
+
+done:
+	return res;
+}
+
+int
+wl_iw_attach(struct net_device *dev, void * dhdp)
+{
+	return 0;
+}
+
+void wl_iw_detach(void)
+{
+}
+
+#endif 
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_iw.h
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_iw.h	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_iw.h	(revision 5)
@@ -0,0 +1,152 @@
+/*
+ * Linux Wireless Extensions support
+ *
+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: wl_iw.h 291086 2011-10-21 01:17:24Z $
+ */
+
+#ifndef _wl_iw_h_
+#define _wl_iw_h_
+
+#include <linux/wireless.h>
+
+#include <typedefs.h>
+#include <proto/ethernet.h>
+#include <wlioctl.h>
+
+#define WL_SCAN_PARAMS_SSID_MAX 	10
+#define GET_SSID			"SSID="
+#define GET_CHANNEL			"CH="
+#define GET_NPROBE 			"NPROBE="
+#define GET_ACTIVE_ASSOC_DWELL  	"ACTIVE="
+#define GET_PASSIVE_ASSOC_DWELL  	"PASSIVE="
+#define GET_HOME_DWELL  		"HOME="
+#define GET_SCAN_TYPE			"TYPE="
+
+#define BAND_GET_CMD				"GETBAND"
+#define BAND_SET_CMD				"SETBAND"
+#define DTIM_SKIP_GET_CMD			"DTIMSKIPGET"
+#define DTIM_SKIP_SET_CMD			"DTIMSKIPSET"
+#define SETSUSPEND_CMD				"SETSUSPENDOPT"
+#define PNOSSIDCLR_SET_CMD			"PNOSSIDCLR"
+
+#define PNOSETUP_SET_CMD			"PNOSETUP " 
+#define PNOENABLE_SET_CMD			"PNOFORCE"
+#define PNODEBUG_SET_CMD			"PNODEBUG"
+#define TXPOWER_SET_CMD			"TXPOWER"
+
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+typedef struct wl_iw_extra_params {
+	int 	target_channel; 
+} wl_iw_extra_params_t;
+
+struct cntry_locales_custom {
+	char iso_abbrev[WLC_CNTRY_BUF_SZ];	
+	char custom_locale[WLC_CNTRY_BUF_SZ];	
+	int32 custom_locale_rev;		
+};
+
+#define	WL_IW_RSSI_MINVAL		-200	
+#define	WL_IW_RSSI_NO_SIGNAL	-91	
+#define	WL_IW_RSSI_VERY_LOW	-80	
+#define	WL_IW_RSSI_LOW		-70	
+#define	WL_IW_RSSI_GOOD		-68	
+#define	WL_IW_RSSI_VERY_GOOD	-58	
+#define	WL_IW_RSSI_EXCELLENT	-57	
+#define	WL_IW_RSSI_INVALID	 0	
+#define MAX_WX_STRING 80
+#ifndef isprint
+#define isprint(c) bcm_isprint(c)
+#endif
+#define WL_IW_SET_ACTIVE_SCAN	(SIOCIWFIRSTPRIV+1)
+#define WL_IW_GET_RSSI			(SIOCIWFIRSTPRIV+3)
+#define WL_IW_SET_PASSIVE_SCAN	(SIOCIWFIRSTPRIV+5)
+#define WL_IW_GET_LINK_SPEED	(SIOCIWFIRSTPRIV+7)
+#define WL_IW_GET_CURR_MACADDR	(SIOCIWFIRSTPRIV+9)
+#define WL_IW_SET_STOP				(SIOCIWFIRSTPRIV+11)
+#define WL_IW_SET_START			(SIOCIWFIRSTPRIV+13)
+
+#define 		G_SCAN_RESULTS 8*1024
+#define 		WE_ADD_EVENT_FIX	0x80
+#define          G_WLAN_SET_ON	0
+#define          G_WLAN_SET_OFF	1
+
+typedef struct wl_iw {
+	char nickname[IW_ESSID_MAX_SIZE];
+
+	struct iw_statistics wstats;
+
+	int spy_num;
+	uint32 pwsec;			
+	uint32 gwsec;			
+	bool privacy_invoked; 		
+	struct ether_addr spy_addr[IW_MAX_SPY];
+	struct iw_quality spy_qual[IW_MAX_SPY];
+	void  *wlinfo;
+} wl_iw_t;
+
+struct wl_ctrl {
+	struct timer_list *timer;
+	struct net_device *dev;
+	long sysioc_pid;
+	struct semaphore sysioc_sem;
+	struct completion sysioc_exited;
+};
+
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+extern const struct iw_handler_def wl_iw_handler_def;
+#endif 
+
+extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data);
+extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats);
+int wl_iw_attach(struct net_device *dev, void * dhdp);
+int wl_iw_send_priv_event(struct net_device *dev, char *flag);
+
+void wl_iw_detach(void);
+
+#define CSCAN_COMMAND				"CSCAN "
+#define CSCAN_TLV_PREFIX 			'S'
+#define CSCAN_TLV_VERSION			1
+#define CSCAN_TLV_SUBVERSION			0
+#define CSCAN_TLV_TYPE_SSID_IE          'S'
+#define CSCAN_TLV_TYPE_CHANNEL_IE   'C'
+#define CSCAN_TLV_TYPE_NPROBE_IE     'N'
+#define CSCAN_TLV_TYPE_ACTIVE_IE      'A'
+#define CSCAN_TLV_TYPE_PASSIVE_IE    'P'
+#define CSCAN_TLV_TYPE_HOME_IE         'H'
+#define CSCAN_TLV_TYPE_STYPE_IE        'T'
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
+	iwe_stream_add_event(info, stream, ends, iwe, extra)
+#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \
+	iwe_stream_add_value(info, event, value, ends, iwe, event_len)
+#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \
+	iwe_stream_add_point(info, stream, ends, iwe, extra)
+#else
+#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
+	iwe_stream_add_event(stream, ends, iwe, extra)
+#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \
+	iwe_stream_add_value(event, value, ends, iwe, event_len)
+#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \
+	iwe_stream_add_point(stream, ends, iwe, extra)
+#endif
+
+#endif 
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_linux.c
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_linux.c	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_linux.c	(revision 5)
@@ -0,0 +1,3474 @@
+/*
+ * Linux-specific portion of
+ * Broadcom 802.11abg Networking Device Driver
+ *
+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: wl_linux.c 580354 2015-08-18 23:42:37Z $
+ */
+
+#define LINUX_PORT
+
+#define __UNDEF_NO_VERSION__
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+#include <linux/module.h>
+#endif
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ethtool.h>
+#include <linux/completion.h>
+#include <linux/usb.h>
+#include <linux/pci_ids.h>
+#define WLC_MAXBSSCFG		1	
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+#include <asm/switch_to.h>
+#else
+#include <asm/system.h>
+#endif
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <proto/802.1d.h>
+
+#include <epivers.h>
+#include <bcmendian.h>
+#include <proto/ethernet.h>
+#include <bcmutils.h>
+#include <pcicfg.h>
+#include <wlioctl.h>
+#include <wlc_key.h>
+#include <siutils.h>
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 4, 5)
+#error "No support for Kernel Rev <= 2.4.5, As the older kernel revs doesn't support Tasklets"
+#endif
+
+#include <wlc_pub.h>
+#include <wl_dbg.h>
+#include <wlc_ethereal.h>
+#include <proto/ieee80211_radiotap.h>
+
+#include <wl_iw.h>
+#ifdef USE_IW
+struct iw_statistics *wl_get_wireless_stats(struct net_device *dev);
+#endif
+
+#include <wl_export.h>
+
+#include <wl_linux.h>
+
+#if defined(USE_CFG80211)
+#include <wl_cfg80211_hybrid.h>
+#endif 
+
+#include <wlc_wowl.h>
+
+static void wl_timer(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
+		struct timer_list *tl
+#else
+		ulong data
+#endif
+		);
+static void _wl_timer(wl_timer_t *t);
+static struct net_device *wl_alloc_linux_if(wl_if_t *wlif);
+
+static int wl_monitor_start(struct sk_buff *skb, struct net_device *dev);
+
+static void wl_start_txqwork(wl_task_t *task);
+static void wl_txq_free(wl_info_t *wl);
+#define TXQ_LOCK(_wl) spin_lock_bh(&(_wl)->txq_lock)
+#define TXQ_UNLOCK(_wl) spin_unlock_bh(&(_wl)->txq_lock)
+
+static void wl_set_multicast_list_workitem(struct work_struct *work);
+
+static void wl_timer_task(wl_task_t *task);
+static void wl_dpc_rxwork(struct wl_task *task);
+
+static int wl_reg_proc_entry(wl_info_t *wl);
+
+static int wl_linux_watchdog(void *ctx);
+static
+int wl_found = 0;
+
+typedef struct priv_link {
+	wl_if_t *wlif;
+} priv_link_t;
+
+#define WL_DEV_IF(dev)          ((wl_if_t*)((priv_link_t*)DEV_PRIV(dev))->wlif)
+
+#ifdef WL_INFO
+#undef WL_INFO
+#endif
+#define WL_INFO(dev)	((wl_info_t*)(WL_DEV_IF(dev)->wl))	
+
+static int wl_open(struct net_device *dev);
+static int wl_close(struct net_device *dev);
+static int BCMFASTPATH wl_start(struct sk_buff *skb, struct net_device *dev);
+static int wl_start_int(wl_info_t *wl, wl_if_t *wlif, struct sk_buff *skb);
+
+static struct net_device_stats *wl_get_stats(struct net_device *dev);
+static int wl_set_mac_address(struct net_device *dev, void *addr);
+static void wl_set_multicast_list(struct net_device *dev);
+static void _wl_set_multicast_list(struct net_device *dev);
+static int wl_ethtool(wl_info_t *wl, void *uaddr, wl_if_t *wlif);
+static void wl_dpc(ulong data);
+static void wl_tx_tasklet(ulong data);
+static void wl_link_up(wl_info_t *wl, char * ifname);
+static void wl_link_down(wl_info_t *wl, char *ifname);
+static int wl_schedule_task(wl_info_t *wl, void (*fn)(struct wl_task *), void *context);
+#if defined(BCMDBG)
+static int wl_dump(wl_info_t *wl, struct bcmstrbuf *b);
+#endif
+static struct wl_if *wl_alloc_if(wl_info_t *wl, int iftype, uint unit, struct wlc_if* wlc_if);
+static void wl_free_if(wl_info_t *wl, wl_if_t *wlif);
+static void wl_get_driver_info(struct net_device *dev, struct ethtool_drvinfo *info);
+
+#if defined(WL_CONFIG_RFKILL)
+#include <linux/rfkill.h>
+static int wl_init_rfkill(wl_info_t *wl);
+static void wl_uninit_rfkill(wl_info_t *wl);
+static int wl_set_radio_block(void *data, bool blocked);
+static void wl_report_radio_state(wl_info_t *wl);
+#endif
+
+MODULE_LICENSE("MIXED/Proprietary");
+
+static struct pci_device_id wl_id_table[] =
+{
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, wl_id_table);
+
+static unsigned int online_cpus = 1;
+
+#ifdef BCMDBG
+static int msglevel = 0xdeadbeef;
+module_param(msglevel, int, 0);
+static int msglevel2 = 0xdeadbeef;
+module_param(msglevel2, int, 0);
+static int phymsglevel = 0xdeadbeef;
+module_param(phymsglevel, int, 0);
+#endif 
+
+#ifdef BCMDBG_ASSERT
+static int assert_type = 0xdeadbeef;
+module_param(assert_type, int, 0);
+#endif
+
+static int passivemode = 0;
+module_param(passivemode, int, 0);
+
+#define WL_TXQ_THRESH	0
+static int wl_txq_thresh = WL_TXQ_THRESH;
+module_param(wl_txq_thresh, int, 0);
+
+static int oneonly = 0;
+module_param(oneonly, int, 0);
+
+static int piomode = 0;
+module_param(piomode, int, 0);
+
+static int instance_base = 0; 
+module_param(instance_base, int, 0);
+
+#if defined(BCMDBG)
+static struct ether_addr local_ea;
+static char *macaddr = NULL;
+module_param(macaddr, charp, S_IRUGO);
+#endif
+
+static int nompc = 0;
+module_param(nompc, int, 0);
+
+#ifdef quote_str
+#undef quote_str
+#endif 
+#ifdef to_str
+#undef to_str
+#endif 
+#define to_str(s) #s
+#define quote_str(s) to_str(s)
+
+#define BRCM_WLAN_IFNAME wlan%d
+
+static char intf_name[IFNAMSIZ] = quote_str(BRCM_WLAN_IFNAME);
+
+module_param_string(intf_name, intf_name, IFNAMSIZ, 0);
+
+static const u_int8_t brcm_oui[] =  {0x00, 0x10, 0x18};
+
+#define WL_RADIOTAP_BRCM2_HT_SNS	0x01
+#define WL_RADIOTAP_BRCM2_HT_MCS	0x00000001
+
+#define WL_RADIOTAP_LEGACY_SNS		0x02
+#define WL_RADIOTAP_LEGACY_VHT		0x00000001
+
+#define IEEE80211_RADIOTAP_HTMOD_40		0x01
+#define IEEE80211_RADIOTAP_HTMOD_SGI		0x02
+#define IEEE80211_RADIOTAP_HTMOD_GF		0x04
+#define IEEE80211_RADIOTAP_HTMOD_LDPC		0x08
+#define IEEE80211_RADIOTAP_HTMOD_STBC_MASK	0x30
+#define IEEE80211_RADIOTAP_HTMOD_STBC_SHIFT	4
+
+#define WL_RADIOTAP_F_NONHT_VHT_DYN_BW			0x01
+
+#define WL_RADIOTAP_F_NONHT_VHT_BW			0x02
+
+struct wl_radiotap_nonht_vht {
+	u_int8_t len;				
+	u_int8_t flags;
+	u_int8_t bw;
+} __attribute__ ((packed));
+
+typedef struct wl_radiotap_nonht_vht wl_radiotap_nonht_vht_t;
+
+struct wl_radiotap_legacy {
+	struct ieee80211_radiotap_header ieee_radiotap;
+	u_int32_t it_present_ext;
+	u_int32_t pad1;
+	uint32 tsft_l;
+	uint32 tsft_h;
+	uint8 flags;
+	uint8 rate;
+	uint16 channel_freq;
+	uint16 channel_flags;
+	uint8 signal;
+	uint8 noise;
+	int8 antenna;
+	uint8 pad2;
+	u_int8_t vend_oui[3];
+	u_int8_t vend_sns;
+	u_int16_t vend_skip_len;
+	wl_radiotap_nonht_vht_t nonht_vht;
+} __attribute__ ((__packed__));
+
+typedef struct wl_radiotap_legacy wl_radiotap_legacy_t;
+
+#define WL_RADIOTAP_LEGACY_SKIP_LEN htol16(sizeof(struct wl_radiotap_legacy) - \
+	offsetof(struct wl_radiotap_legacy, nonht_vht))
+
+#define WL_RADIOTAP_NONHT_VHT_LEN (sizeof(wl_radiotap_nonht_vht_t) - 1)
+
+struct wl_radiotap_ht_brcm_2 {
+	struct ieee80211_radiotap_header ieee_radiotap;
+	u_int32_t it_present_ext;
+	u_int32_t pad1;
+	uint32 tsft_l;
+	uint32 tsft_h;
+	u_int8_t flags;
+	u_int8_t pad2;
+	u_int16_t channel_freq;
+	u_int16_t channel_flags;
+	u_int8_t signal;
+	u_int8_t noise;
+	u_int8_t antenna;
+	u_int8_t pad3;
+	u_int8_t vend_oui[3];
+	u_int8_t vend_sns;
+	u_int16_t vend_skip_len;
+	u_int8_t mcs;
+	u_int8_t htflags;
+} __attribute__ ((packed));
+
+typedef struct wl_radiotap_ht_brcm_2 wl_radiotap_ht_brcm_2_t;
+
+#define WL_RADIOTAP_HT_BRCM2_SKIP_LEN htol16(sizeof(struct wl_radiotap_ht_brcm_2) - \
+	offsetof(struct wl_radiotap_ht_brcm_2, mcs))
+
+struct wl_radiotap_ht_brcm_3 {
+	struct ieee80211_radiotap_header ieee_radiotap;
+	u_int32_t it_present_ext;
+	u_int32_t pad1;
+	uint32 tsft_l;
+	uint32 tsft_h;
+	u_int8_t flags;
+	u_int8_t pad2;
+	u_int16_t channel_freq;
+	u_int16_t channel_flags;
+	u_int8_t signal;
+	u_int8_t noise;
+	u_int8_t antenna;
+	u_int8_t mcs_known;
+	u_int8_t mcs_flags;
+	u_int8_t mcs_index;
+	u_int8_t vend_oui[3];
+	u_int8_t vend_sns;
+	u_int16_t vend_skip_len;
+	wl_radiotap_nonht_vht_t nonht_vht;
+} __attribute__ ((packed));
+
+typedef struct wl_radiotap_ht_brcm_3 wl_radiotap_ht_brcm_3_t;
+
+struct wl_radiotap_ht {
+	struct ieee80211_radiotap_header ieee_radiotap;
+	uint32 tsft_l;
+	uint32 tsft_h;
+	u_int8_t flags;
+	u_int8_t pad1;
+	u_int16_t channel_freq;
+	u_int16_t channel_flags;
+	u_int8_t signal;
+	u_int8_t noise;
+	u_int8_t antenna;
+	u_int8_t mcs_known;
+	u_int8_t mcs_flags;
+	u_int8_t mcs_index;
+} __attribute__ ((packed));
+
+typedef struct wl_radiotap_ht wl_radiotap_ht_t;
+
+struct wl_radiotap_vht {
+	struct ieee80211_radiotap_header ieee_radiotap;
+	uint32 tsft_l;			
+	uint32 tsft_h;			
+	u_int8_t flags;			
+	u_int8_t pad1;
+	u_int16_t channel_freq;		
+	u_int16_t channel_flags;	
+	u_int8_t signal;		
+	u_int8_t noise;			
+	u_int8_t antenna;		
+	u_int8_t pad2;
+	u_int16_t pad3;
+	uint32 ampdu_ref_num;		
+	u_int16_t ampdu_flags;		
+	u_int8_t ampdu_delim_crc;	
+	u_int8_t ampdu_reserved;
+	u_int16_t vht_known;		
+	u_int8_t vht_flags;		
+	u_int8_t vht_bw;		
+	u_int8_t vht_mcs_nss[4];	
+	u_int8_t vht_coding;		
+	u_int8_t vht_group_id;		
+	u_int16_t vht_partial_aid;	
+} __attribute__ ((packed));
+
+typedef struct wl_radiotap_vht wl_radiotap_vht_t;
+
+#define WL_RADIOTAP_PRESENT_LEGACY			\
+	((1 << IEEE80211_RADIOTAP_TSFT) |		\
+	 (1 << IEEE80211_RADIOTAP_RATE) |		\
+	 (1 << IEEE80211_RADIOTAP_CHANNEL) |		\
+	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |	\
+	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |	\
+	 (1 << IEEE80211_RADIOTAP_FLAGS) |		\
+	 (1 << IEEE80211_RADIOTAP_ANTENNA) |		\
+	 (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE) |	\
+	 (1 << IEEE80211_RADIOTAP_EXT))
+
+#define WL_RADIOTAP_PRESENT_HT_BRCM2			\
+	((1 << IEEE80211_RADIOTAP_TSFT) |		\
+	 (1 << IEEE80211_RADIOTAP_FLAGS) |		\
+	 (1 << IEEE80211_RADIOTAP_CHANNEL) |		\
+	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |	\
+	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |	\
+	 (1 << IEEE80211_RADIOTAP_ANTENNA) |		\
+	 (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE) |	\
+	 (1 << IEEE80211_RADIOTAP_EXT))
+
+#define WL_RADIOTAP_PRESENT_HT				\
+	((1 << IEEE80211_RADIOTAP_TSFT) |		\
+	 (1 << IEEE80211_RADIOTAP_FLAGS) |		\
+	 (1 << IEEE80211_RADIOTAP_CHANNEL) |		\
+	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |	\
+	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |	\
+	 (1 << IEEE80211_RADIOTAP_ANTENNA) |		\
+	 (1 << IEEE80211_RADIOTAP_MCS))
+
+#define WL_RADIOTAP_PRESENT_VHT			\
+	((1 << IEEE80211_RADIOTAP_TSFT) |		\
+	 (1 << IEEE80211_RADIOTAP_FLAGS) |		\
+	 (1 << IEEE80211_RADIOTAP_CHANNEL) |		\
+	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |	\
+	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |	\
+	 (1 << IEEE80211_RADIOTAP_ANTENNA) |		\
+	 (1 << IEEE80211_RADIOTAP_AMPDU) |		\
+	 (1 << IEEE80211_RADIOTAP_VHT))
+
+#ifndef ARPHRD_IEEE80211_RADIOTAP
+#define ARPHRD_IEEE80211_RADIOTAP 803
+#endif
+
+#ifndef SRCBASE
+#define SRCBASE "."
+#endif
+
+#if WIRELESS_EXT >= 19 || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
+static struct ethtool_ops wl_ethtool_ops =
+#else
+static const struct ethtool_ops wl_ethtool_ops =
+#endif 
+{
+	.get_drvinfo = wl_get_driver_info,
+};
+#endif 
+
+#if defined(WL_USE_NETDEV_OPS)
+
+static const struct net_device_ops wl_netdev_ops =
+{
+	.ndo_open = wl_open,
+	.ndo_stop = wl_close,
+	.ndo_start_xmit = wl_start,
+	.ndo_get_stats = wl_get_stats,
+	.ndo_set_mac_address = wl_set_mac_address,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+	.ndo_set_rx_mode = wl_set_multicast_list,
+#else
+	.ndo_set_multicast_list = wl_set_multicast_list,
+#endif
+	.ndo_do_ioctl = wl_ioctl
+};
+
+static const struct net_device_ops wl_netdev_monitor_ops =
+{
+	.ndo_start_xmit = wl_monitor_start,
+	.ndo_get_stats = wl_get_stats,
+	.ndo_do_ioctl = wl_ioctl
+};
+#endif 
+
+static void
+wl_if_setup(struct net_device *dev)
+{
+#if defined(WL_USE_NETDEV_OPS)
+	dev->netdev_ops = &wl_netdev_ops;
+#else
+	dev->open = wl_open;
+	dev->stop = wl_close;
+	dev->hard_start_xmit = wl_start;
+	dev->get_stats = wl_get_stats;
+	dev->set_mac_address = wl_set_mac_address;
+	dev->set_multicast_list = wl_set_multicast_list;
+	dev->do_ioctl = wl_ioctl;
+#endif 
+
+#ifdef USE_IW
+#if WIRELESS_EXT < 19
+	dev->get_wireless_stats = wl_get_wireless_stats;
+#endif
+#if WIRELESS_EXT > 12
+	dev->wireless_handlers = (struct iw_handler_def *) &wl_iw_handler_def;
+#endif
+#endif 
+
+#if WIRELESS_EXT >= 19 || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+	dev->ethtool_ops = &wl_ethtool_ops;
+#endif
+}
+
+static wl_info_t *
+wl_attach(uint16 vendor, uint16 device, ulong regs,
+	uint bustype, void *btparam, uint irq, uchar* bar1_addr, uint32 bar1_size)
+{
+	struct net_device *dev;
+	wl_if_t *wlif;
+	wl_info_t *wl;
+	osl_t *osh;
+	int unit, err;
+#if defined(USE_CFG80211)
+	struct device *parentdev;
+#endif
+
+	unit = wl_found + instance_base;
+	err = 0;
+
+	if (unit < 0) {
+		WL_ERROR(("wl%d: unit number overflow, exiting\n", unit));
+		return NULL;
+	}
+
+	if (oneonly && (unit != instance_base)) {
+		WL_ERROR(("wl%d: wl_attach: oneonly is set, exiting\n", unit));
+		return NULL;
+	}
+
+	osh = osl_attach(btparam, bustype, TRUE);
+	ASSERT(osh);
+
+	if ((wl = (wl_info_t*) MALLOC(osh, sizeof(wl_info_t))) == NULL) {
+		WL_ERROR(("wl%d: malloc wl_info_t, out of memory, malloced %d bytes\n", unit,
+			MALLOCED(osh)));
+		osl_detach(osh);
+		return NULL;
+	}
+	bzero(wl, sizeof(wl_info_t));
+
+	wl->osh = osh;
+	wl->unit = unit;
+	atomic_set(&wl->callbacks, 0);
+
+	wl->all_dispatch_mode = (passivemode == 0) ? TRUE : FALSE;
+	if (WL_ALL_PASSIVE_ENAB(wl)) {
+
+		MY_INIT_WORK(&wl->txq_task.work, (work_func_t)wl_start_txqwork);
+		wl->txq_task.context = wl;
+
+		MY_INIT_WORK(&wl->multicast_task.work, (work_func_t)wl_set_multicast_list_workitem);
+
+		MY_INIT_WORK(&wl->wl_dpc_task.work, (work_func_t)wl_dpc_rxwork);
+		wl->wl_dpc_task.context = wl;
+	}
+
+	wl->txq_dispatched = FALSE;
+	wl->txq_head = wl->txq_tail = NULL;
+	wl->txq_cnt = 0;
+
+	wlif = wl_alloc_if(wl, WL_IFTYPE_BSS, unit, NULL);
+	if (!wlif) {
+		WL_ERROR(("wl%d: %s: wl_alloc_if failed\n", unit, __FUNCTION__));
+		MFREE(osh, wl, sizeof(wl_info_t));
+		osl_detach(osh);
+		return NULL;
+	}
+
+	if (wl_alloc_linux_if(wlif) == NULL) {
+		WL_ERROR(("wl%d: %s: wl_alloc_linux_if failed\n", unit, __FUNCTION__));
+		MFREE(osh, wl, sizeof(wl_info_t));
+		osl_detach(osh);
+		return NULL;
+	}
+
+	dev = wlif->dev;
+	wl->dev = dev;
+	wl_if_setup(dev);
+
+	dev->base_addr = regs;
+
+	WL_TRACE(("wl%d: Bus: ", unit));
+	if (bustype == PCMCIA_BUS) {
+
+		wl->piomode = TRUE;
+		WL_TRACE(("PCMCIA\n"));
+	} else if (bustype == PCI_BUS) {
+
+		wl->piomode = piomode;
+		WL_TRACE(("PCI/%s\n", wl->piomode ? "PIO" : "DMA"));
+	}
+	else if (bustype == RPC_BUS) {
+
+	} else {
+		bustype = PCI_BUS;
+		WL_TRACE(("force to PCI\n"));
+	}
+	wl->bcm_bustype = bustype;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
+	if ((wl->regsva = ioremap_nocache(dev->base_addr, PCI_BAR0_WINSZ)) == NULL) {
+#else
+	if ((wl->regsva = ioremap(dev->base_addr, PCI_BAR0_WINSZ)) == NULL) {
+#endif
+		WL_ERROR(("wl%d: ioremap() failed\n", unit));
+		goto fail;
+	}
+
+	wl->bar1_addr = bar1_addr;
+	wl->bar1_size = bar1_size;
+
+	spin_lock_init(&wl->lock);
+	spin_lock_init(&wl->isr_lock);
+
+	if (WL_ALL_PASSIVE_ENAB(wl))
+		sema_init(&wl->sem, 1);
+
+	spin_lock_init(&wl->txq_lock);
+
+	if (!(wl->wlc = wlc_attach((void *) wl, vendor, device, unit, wl->piomode,
+		osh, wl->regsva, wl->bcm_bustype, btparam, &err))) {
+		printf("wl driver %s failed with code %d\n", EPI_VERSION_STR, err);
+		goto fail;
+	}
+	wl->pub = wlc_pub(wl->wlc);
+
+	wlif->wlcif = wlc_wlcif_get_by_index(wl->wlc, 0);
+
+	if (nompc) {
+		if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
+			WL_ERROR(("wl%d: Error setting MPC variable to 0\n", unit));
+		}
+	}
+
+	wlc_iovar_setint(wl->wlc, "scan_passive_time", 170);
+
+	wlc_iovar_setint(wl->wlc, "qtxpower", 23 * 4);
+
+#ifdef BCMDBG
+	if (macaddr != NULL) { 
+		int dbg_err;
+
+		WL_ERROR(("wl%d: setting MAC ADDRESS %s\n", unit, macaddr));
+		bcm_ether_atoe(macaddr, &local_ea);
+
+		dbg_err = wlc_iovar_op(wl->wlc, "cur_etheraddr", NULL, 0, &local_ea,
+			ETHER_ADDR_LEN, IOV_SET, NULL);
+		if (dbg_err)
+			WL_ERROR(("wl%d: Error setting MAC ADDRESS\n", unit));
+	}
+#endif 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0)
+	bcopy(&wl->pub->cur_etheraddr, dev->dev_addr, ETHER_ADDR_LEN);
+#else
+	dev_addr_mod(dev, 0, &wl->pub->cur_etheraddr, ETHER_ADDR_LEN);
+#endif
+
+	online_cpus = 1;
+
+	WL_ERROR(("wl%d: online cpus %d\n", unit, online_cpus));
+
+	tasklet_init(&wl->tasklet, wl_dpc, (ulong)wl);
+
+	tasklet_init(&wl->tx_tasklet, wl_tx_tasklet, (ulong)wl);
+
+	{
+		if (request_irq(irq, wl_isr, IRQF_SHARED, dev->name, wl)) {
+			WL_ERROR(("wl%d: request_irq() failed\n", unit));
+			goto fail;
+		}
+		dev->irq = irq;
+	}
+
+#if defined(USE_IW)
+	WL_ERROR(("Using Wireless Extension\n"));
+#endif
+
+#if defined(USE_CFG80211)
+	parentdev = NULL;
+	if (wl->bcm_bustype == PCI_BUS) {
+		parentdev = &((struct pci_dev *)btparam)->dev;
+	}
+	if (parentdev) {
+		if (wl_cfg80211_attach(dev, parentdev, WL_ALL_PASSIVE_ENAB(wl))) {
+			goto fail;
+		}
+	}
+	else {
+		WL_ERROR(("unsupported bus type\n"));
+		goto fail;
+	}
+#else
+
+	if (wl->bcm_bustype == PCI_BUS) {
+		struct pci_dev *pci_dev = (struct pci_dev *)btparam;
+		if (pci_dev != NULL)
+			SET_NETDEV_DEV(dev, &pci_dev->dev);
+	}
+#endif 
+
+	if (register_netdev(dev)) {
+		WL_ERROR(("wl%d: register_netdev() failed\n", unit));
+		goto fail;
+	}
+	wlif->dev_registed = TRUE;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+#endif 
+#ifdef USE_IW
+	wlif->iw.wlinfo = (void *)wl;
+#endif
+
+#if defined(WL_CONFIG_RFKILL)
+	if (wl_init_rfkill(wl) < 0)
+		WL_ERROR(("%s: init_rfkill_failure\n", __FUNCTION__));
+#endif
+
+	if (wlc_iovar_setint(wl->wlc, "leddc", 0xa0000)) {
+		WL_ERROR(("wl%d: Error setting led duty-cycle\n", unit));
+	}
+	if (wlc_set(wl->wlc, WLC_SET_PM, PM_FAST)) {
+		WL_ERROR(("wl%d: Error setting PM variable to FAST PS\n", unit));
+	}
+
+	if (wlc_iovar_setint(wl->wlc, "vlan_mode", OFF)) {
+		WL_ERROR(("wl%d: Error setting vlan mode OFF\n", unit));
+	}
+
+	if (wlc_set(wl->wlc, WLC_SET_INFRA, 1)) {
+		WL_ERROR(("wl%d: Error setting infra_mode to infrastructure\n", unit));
+	}
+
+	if (wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, NULL, NULL)) {
+		WL_ERROR(("wl%d: %s wlc_module_register() failed\n",
+		          wl->pub->unit, __FUNCTION__));
+		goto fail;
+	}
+
+#ifdef BCMDBG
+	wlc_dump_register(wl->pub, "wl", (dump_fn_t)wl_dump, (void *)wl);
+#endif
+
+	wl_reg_proc_entry(wl);
+
+	printf("%s: Broadcom BCM%04x 802.11 Hybrid Wireless Controller%s %s",
+		dev->name, device,
+		WL_ALL_PASSIVE_ENAB(wl) ?  ", Passive Mode" : "", EPI_VERSION_STR);
+
+#ifdef BCMDBG
+	printf(" (Compiled in " SRCBASE);
+#endif 
+	printf("\n");
+
+	wl_found++;
+	return wl;
+
+fail:
+	wl_free(wl);
+	return NULL;
+}
+
+static void __devexit wl_remove(struct pci_dev *pdev);
+
+int __devinit
+wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int rc;
+	wl_info_t *wl;
+	uint32 val;
+	uint32 bar1_size = 0;
+	void* bar1_addr = NULL;
+
+	WL_TRACE(("%s: bus %d slot %d func %d irq %d\n", __FUNCTION__,
+		pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev->irq));
+
+	if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
+	    (((pdev->device & 0xff00) != 0x4300) &&
+	     (pdev->device != 0x576) &&
+	     ((pdev->device & 0xff00) != 0x4700) &&
+	     ((pdev->device < 43000) || (pdev->device > 43999)))) {
+		WL_TRACE(("%s: unsupported vendor %x device %x\n", __FUNCTION__,
+			pdev->vendor, pdev->device));
+		return (-ENODEV);
+	}
+
+	rc = pci_enable_device(pdev);
+	if (rc) {
+		WL_ERROR(("%s: Cannot enable device %d-%d_%d\n", __FUNCTION__,
+			pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)));
+		return (-ENODEV);
+	}
+	pci_set_master(pdev);
+
+	pci_read_config_dword(pdev, 0x40, &val);
+	if ((val & 0x0000ff00) != 0)
+		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+	bar1_size = pci_resource_len(pdev, 2);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
+		bar1_addr = (uchar *)ioremap_nocache(pci_resource_start(pdev, 2),
+#else
+	bar1_addr = (uchar *)ioremap(pci_resource_start(pdev, 2),
+#endif
+			bar1_size);
+	wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), PCI_BUS, pdev,
+		pdev->irq, bar1_addr, bar1_size);
+
+	if (!wl)
+		return -ENODEV;
+
+	pci_set_drvdata(pdev, wl);
+
+	return 0;
+}
+
+static int
+#if !defined(SIMPLE_DEV_PM_OPS)
+wl_suspend(struct pci_dev *pdev, DRV_SUSPEND_STATE_TYPE state)
+{
+#else
+wl_suspend(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+#endif
+	wl_info_t *wl = (wl_info_t *) pci_get_drvdata(pdev);
+	if (!wl) {
+		WL_ERROR(("wl: wl_suspend: pci_get_drvdata failed\n"));
+		return -ENODEV;
+	}
+	WL_ERROR(("%s: PCI Suspend handler\n", __FUNCTION__));
+
+	WL_LOCK(wl);
+	if (WLOFFLD_ENAB(wl->pub) && wlc_iovar_setint(wl->wlc, "wowl_activate", 1) == 0) {
+		WL_TRACE(("%s: Enabled WOWL OFFLOAD\n", __FUNCTION__));
+	} else {
+		WL_ERROR(("%s: Not WOWL capable\n", __FUNCTION__));
+		wl_down(wl);
+		wl->pub->hw_up = FALSE;
+	}
+	WL_UNLOCK(wl);
+
+	if (BUSTYPE(wl->pub->sih->bustype) == PCI_BUS)
+		si_pci_sleep(wl->pub->sih);
+
+	return 0;
+}
+
+static int
+#if !defined(SIMPLE_DEV_PM_OPS)
+wl_resume(struct pci_dev *pdev)
+{
+#else
+wl_resume(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+#endif
+	int err = 0;
+	wl_info_t *wl = (wl_info_t *) pci_get_drvdata(pdev);
+	if (!wl) {
+		WL_ERROR(("wl: wl_resume: pci_get_drvdata failed\n"));
+		return -ENODEV;
+	}
+
+	WL_ERROR(("%s: PCI Resume handler\n", __FUNCTION__));
+	if (WLOFFLD_ENAB(wl->pub)) {
+		wlc_iovar_setint(wl->wlc, "wowl_activate", 0); 
+		wlc_wowl_wake_reason_process(wl->wlc);
+
+		if (WOWL_ACTIVE(wl->pub)) {
+			if (BUSTYPE(wl->pub->sih->bustype) == PCI_BUS) {
+				si_pci_pmeclr(wl->pub->sih);
+			}
+		}
+	}
+
+	WL_LOCK(wl);
+	err = wl_up(wl);
+	WL_UNLOCK(wl);
+
+	return (err);
+}
+
+static void __devexit
+wl_remove(struct pci_dev *pdev)
+{
+	wl_info_t *wl = (wl_info_t *) pci_get_drvdata(pdev);
+
+	if (!wl) {
+		WL_ERROR(("wl: wl_remove: pci_get_drvdata failed\n"));
+		return;
+	}
+	if (!wlc_chipmatch(pdev->vendor, pdev->device)) {
+		WL_ERROR(("wl: wl_remove: wlc_chipmatch failed\n"));
+		return;
+	}
+
+	WL_LOCK(wl);
+	WL_APSTA_UPDN(("wl%d (%s): wl_remove() -> wl_down()\n", wl->pub->unit, wl->dev->name));
+	wl_down(wl);
+	WL_UNLOCK(wl);
+
+	wl_free(wl);
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+}
+
+#if defined(SIMPLE_DEV_PM_OPS)
+static SIMPLE_DEV_PM_OPS(wl_pm_ops, wl_suspend, wl_resume);
+#endif
+
+static struct pci_driver wl_pci_driver __refdata = {
+	.name =		"wl",
+	.probe =	wl_pci_probe,
+	.remove =	__devexit_p(wl_remove),
+	.id_table =	wl_id_table,
+#ifdef SIMPLE_DEV_PM_OPS
+	.driver.pm =	&wl_pm_ops,
+#else
+	.suspend =      wl_suspend,
+	.resume =       wl_resume,
+#endif 
+};
+
+static int __init
+wl_module_init(void)
+{
+	int error = -ENODEV;
+
+#ifdef BCMDBG
+	if (msglevel != 0xdeadbeef)
+		wl_msg_level = msglevel;
+	else {
+		const char *var = getvar(NULL, "wl_msglevel");
+		if (var)
+			wl_msg_level = bcm_strtoul(var, NULL, 0);
+	}
+	printf("%s: msglevel set to 0x%x\n", __FUNCTION__, wl_msg_level);
+	if (msglevel2 != 0xdeadbeef)
+		wl_msg_level2 = msglevel2;
+	else {
+		const char *var = getvar(NULL, "wl_msglevel2");
+		if (var)
+			wl_msg_level2 = bcm_strtoul(var, NULL, 0);
+	}
+	printf("%s: msglevel2 set to 0x%x\n", __FUNCTION__, wl_msg_level2);
+	{
+		extern uint32 phyhal_msg_level;
+
+		if (phymsglevel != 0xdeadbeef)
+			phyhal_msg_level = phymsglevel;
+		else {
+			const char *var = getvar(NULL, "phy_msglevel");
+			if (var)
+				phyhal_msg_level = bcm_strtoul(var, NULL, 0);
+		}
+		printf("%s: phymsglevel set to 0x%x\n", __FUNCTION__, phyhal_msg_level);
+	}
+#endif 
+
+	{
+		const char *var = getvar(NULL, "wl_dispatch_mode");
+		if (var)
+			passivemode = bcm_strtoul(var, NULL, 0);
+		if (passivemode)
+			printf("%s: passivemode enabled\n", __FUNCTION__);
+	}
+
+#ifdef BCMDBG_ASSERT
+
+	if (assert_type != 0xdeadbeef)
+		g_assert_type = assert_type;
+#endif 
+
+	{
+		char *var = getvar(NULL, "wl_txq_thresh");
+		if (var)
+			wl_txq_thresh = bcm_strtoul(var, NULL, 0);
+#ifdef BCMDBG
+			WL_INFORM(("%s: wl_txq_thresh set to 0x%x\n",
+				__FUNCTION__, wl_txq_thresh));
+#endif
+	}
+
+	if (!(error = pci_module_init(&wl_pci_driver)))
+		return (0);
+
+	return (error);
+}
+
+static void __exit
+wl_module_exit(void)
+{
+
+	pci_unregister_driver(&wl_pci_driver);
+
+}
+
+module_init(wl_module_init);
+module_exit(wl_module_exit);
+
+void
+wl_free(wl_info_t *wl)
+{
+	wl_timer_t *t, *next;
+	osl_t *osh;
+
+	WL_TRACE(("wl: wl_free\n"));
+	{
+		if (wl->dev && wl->dev->irq)
+			free_irq(wl->dev->irq, wl);
+	}
+
+#if defined(WL_CONFIG_RFKILL)
+	wl_uninit_rfkill(wl);
+#endif
+
+	if (wl->dev) {
+		wl_free_if(wl, WL_DEV_IF(wl->dev));
+		wl->dev = NULL;
+	}
+
+	tasklet_kill(&wl->tasklet);
+
+	tasklet_kill(&wl->tx_tasklet);
+
+	if (wl->pub) {
+		wlc_module_unregister(wl->pub, "linux", wl);
+	}
+
+	if (wl->wlc) {
+		{
+		char tmp1[128];
+		sprintf(tmp1, "%s%d", HYBRID_PROC, wl->pub->unit);
+		remove_proc_entry(tmp1, 0);
+		}
+		wlc_detach(wl->wlc);
+		wl->wlc = NULL;
+		wl->pub = NULL;
+	}
+
+	while (atomic_read(&wl->callbacks) > 0)
+		schedule();
+
+	for (t = wl->timers; t; t = next) {
+		next = t->next;
+#ifdef BCMDBG
+		if (t->name)
+			MFREE(wl->osh, t->name, strlen(t->name) + 1);
+#endif
+		MFREE(wl->osh, t, sizeof(wl_timer_t));
+	}
+
+	osh = wl->osh;
+
+	if (wl->regsva && BUSTYPE(wl->bcm_bustype) != SDIO_BUS &&
+	    BUSTYPE(wl->bcm_bustype) != JTAG_BUS) {
+		iounmap((void*)wl->regsva);
+	}
+	wl->regsva = NULL;
+
+	if (wl->bar1_addr) {
+		iounmap(wl->bar1_addr);
+		wl->bar1_addr = NULL;
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+#endif 
+
+	wl_txq_free(wl);
+
+	MFREE(osh, wl, sizeof(wl_info_t));
+
+	if (MALLOCED(osh)) {
+		printf("Memory leak of bytes %d\n", MALLOCED(osh));
+#ifndef BCMDBG_MEM
+		ASSERT(0);
+#endif
+	}
+
+#ifdef BCMDBG_MEM
+
+	MALLOC_DUMP(osh, NULL);
+#endif 
+
+	osl_detach(osh);
+}
+
+static int
+wl_open(struct net_device *dev)
+{
+	wl_info_t *wl;
+	int error = 0;
+
+	if (!dev)
+		return -ENETDOWN;
+
+	wl = WL_INFO(dev);
+
+	WL_TRACE(("wl%d: wl_open\n", wl->pub->unit));
+
+	WL_LOCK(wl);
+	WL_APSTA_UPDN(("wl%d: (%s): wl_open() -> wl_up()\n",
+		wl->pub->unit, wl->dev->name));
+
+	error = wl_up(wl);
+	if (!error) {
+		error = wlc_set(wl->wlc, WLC_SET_PROMISC, (dev->flags & IFF_PROMISC));
+	}
+	WL_UNLOCK(wl);
+
+	if (!error)
+		OLD_MOD_INC_USE_COUNT;
+
+#if defined(USE_CFG80211)
+	if (wl_cfg80211_up(dev)) {
+		WL_ERROR(("%s: failed to bring up cfg80211\n", __func__));
+		return -1;
+	}
+#endif
+	return (error? -ENODEV : 0);
+}
+
+static int
+wl_close(struct net_device *dev)
+{
+	wl_info_t *wl;
+
+	if (!dev)
+		return -ENETDOWN;
+
+#if defined(USE_CFG80211)
+	wl_cfg80211_down(dev);
+#endif
+	wl = WL_INFO(dev);
+
+	WL_TRACE(("wl%d: wl_close\n", wl->pub->unit));
+
+	WL_LOCK(wl);
+	WL_APSTA_UPDN(("wl%d (%s): wl_close() -> wl_down()\n",
+		wl->pub->unit, wl->dev->name));
+
+	if (wl->if_list == NULL) {
+		wl_down(wl);
+	}
+	WL_UNLOCK(wl);
+
+	OLD_MOD_DEC_USE_COUNT;
+
+	return (0);
+}
+
+void * BCMFASTPATH
+wl_get_ifctx(struct wl_info *wl, int ctx_id, wl_if_t *wlif)
+{
+	void *ifctx = NULL;
+
+	switch (ctx_id) {
+	case IFCTX_NETDEV:
+		ifctx = (void *)((wlif == NULL) ? wl->dev : wlif->dev);
+		break;
+
+	default:
+		break;
+	}
+
+	return ifctx;
+}
+
+static int BCMFASTPATH
+wl_start_int(wl_info_t *wl, wl_if_t *wlif, struct sk_buff *skb)
+{
+	void *pkt;
+
+	WL_TRACE(("wl%d: wl_start: len %d data_len %d summed %d csum: 0x%x\n",
+		wl->pub->unit, skb->len, skb->data_len, skb->ip_summed, (uint32)skb->csum));
+
+	WL_LOCK(wl);
+
+	pkt = PKTFRMNATIVE(wl->osh, skb);
+	ASSERT(pkt != NULL);
+
+	if (WME_ENAB(wl->pub) && (PKTPRIO(pkt) == 0))
+		pktsetprio(pkt, FALSE);
+
+	wlc_sendpkt(wl->wlc, pkt, wlif->wlcif);
+
+	WL_UNLOCK(wl);
+
+	return (0);
+}
+
+void
+wl_txflowcontrol(wl_info_t *wl, struct wl_if *wlif, bool state, int prio)
+{
+	struct net_device *dev;
+
+	ASSERT(prio == ALLPRIO);
+
+	if (wlif == NULL)
+		dev = wl->dev;
+	else if (!wlif->dev_registed)
+		return;
+	else
+		dev = wlif->dev;
+
+	if (state == ON)
+		netif_stop_queue(dev);
+	else
+		netif_wake_queue(dev);
+}
+
+static int
+wl_schedule_task(wl_info_t *wl, void (*fn)(struct wl_task *task), void *context)
+{
+	wl_task_t *task;
+
+	WL_TRACE(("wl%d: wl_schedule_task\n", wl->pub->unit));
+
+	if (!(task = MALLOC(wl->osh, sizeof(wl_task_t)))) {
+		WL_ERROR(("wl%d: wl_schedule_task: out of memory, malloced %d bytes\n",
+			wl->pub->unit, MALLOCED(wl->osh)));
+		return -ENOMEM;
+	}
+
+	MY_INIT_WORK(&task->work, (work_func_t)fn);
+	task->context = context;
+
+	if (!schedule_work(&task->work)) {
+		WL_ERROR(("wl%d: schedule_work() failed\n", wl->pub->unit));
+		MFREE(wl->osh, task, sizeof(wl_task_t));
+		return -ENOMEM;
+	}
+
+	atomic_inc(&wl->callbacks);
+
+	return 0;
+}
+
+static struct wl_if *
+wl_alloc_if(wl_info_t *wl, int iftype, uint subunit, struct wlc_if *wlcif)
+{
+	wl_if_t *wlif;
+	wl_if_t *p;
+
+	if (!(wlif = MALLOC(wl->osh, sizeof(wl_if_t)))) {
+		WL_ERROR(("wl%d: wl_alloc_if: out of memory, malloced %d bytes\n",
+			(wl->pub)?wl->pub->unit:subunit, MALLOCED(wl->osh)));
+		return NULL;
+	}
+	bzero(wlif, sizeof(wl_if_t));
+	wlif->wl = wl;
+	wlif->wlcif = wlcif;
+	wlif->subunit = subunit;
+	wlif->if_type = iftype;
+
+	if (wl->if_list == NULL)
+		wl->if_list = wlif;
+	else {
+		p = wl->if_list;
+		while (p->next != NULL)
+			p = p->next;
+		p->next = wlif;
+	}
+
+	return wlif;
+}
+
+static void
+wl_free_if(wl_info_t *wl, wl_if_t *wlif)
+{
+	wl_if_t *p;
+	ASSERT(wlif);
+	ASSERT(wl);
+
+	WL_TRACE(("%s\n", __FUNCTION__));
+
+	if (wlif->dev_registed) {
+		ASSERT(wlif->dev);
+		unregister_netdev(wlif->dev);
+		wlif->dev_registed = FALSE;
+	}
+
+#if defined(USE_CFG80211)
+	wl_cfg80211_detach(wlif->dev);
+#endif
+
+	p = wl->if_list;
+	if (p == wlif)
+		wl->if_list = p->next;
+	else {
+		while (p != NULL && p->next != wlif)
+			p = p->next;
+		if (p != NULL)
+			p->next = p->next->next;
+	}
+
+	if (wlif->dev) {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
+		MFREE(wl->osh, wlif->dev->priv, sizeof(priv_link_t));
+		MFREE(wl->osh, wlif->dev, sizeof(struct net_device));
+#else
+		free_netdev(wlif->dev);
+		wlif->dev = NULL;
+#endif 
+	}
+
+	MFREE(wl->osh, wlif, sizeof(wl_if_t));
+}
+
+static struct net_device *
+wl_alloc_linux_if(wl_if_t *wlif)
+{
+	wl_info_t *wl = wlif->wl;
+	struct net_device *dev;
+	priv_link_t *priv_link;
+
+	WL_TRACE(("%s\n", __FUNCTION__));
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
+	dev = MALLOC(wl->osh, sizeof(struct net_device));
+	if (!dev) {
+		WL_ERROR(("wl%d: %s: malloc of net_device failed\n",
+			(wl->pub)?wl->pub->unit:wlif->subunit, __FUNCTION__));
+		return NULL;
+	}
+	bzero(dev, sizeof(struct net_device));
+	ether_setup(dev);
+
+	strncpy(dev->name, intf_name, IFNAMSIZ-1);
+	dev->name[IFNAMSIZ-1] = '\0';
+
+	priv_link = MALLOC(wl->osh, sizeof(priv_link_t));
+	if (!priv_link) {
+		WL_ERROR(("wl%d: %s: malloc of priv_link failed\n",
+			(wl->pub)?wl->pub->unit:wlif->subunit, __FUNCTION__));
+		MFREE(wl->osh, dev, sizeof(struct net_device));
+		return NULL;
+	}
+	dev->priv = priv_link;
+#else
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
+	dev = alloc_netdev(sizeof(priv_link_t), intf_name, ether_setup);
+#else
+	dev = alloc_netdev(sizeof(priv_link_t), intf_name, NET_NAME_UNKNOWN, ether_setup);
+#endif
+
+	if (!dev) {
+		WL_ERROR(("wl%d: %s: alloc_netdev failed\n",
+			(wl->pub)?wl->pub->unit:wlif->subunit, __FUNCTION__));
+		return NULL;
+	}
+	priv_link = netdev_priv(dev);
+	if (!priv_link) {
+		WL_ERROR(("wl%d: %s: cannot get netdev_priv\n",
+			(wl->pub)?wl->pub->unit:wlif->subunit, __FUNCTION__));
+		return NULL;
+	}
+#endif 
+
+	priv_link->wlif = wlif;
+	wlif->dev = dev;
+
+	if (wlif->if_type != WL_IFTYPE_MON && wl->dev && netif_queue_stopped(wl->dev))
+		netif_stop_queue(dev);
+
+	return dev;
+}
+
+char *
+wl_ifname(wl_info_t *wl, wl_if_t *wlif)
+{
+	if (wlif) {
+		return wlif->name;
+	} else {
+		return wl->dev->name;
+	}
+}
+
+void
+wl_init(wl_info_t *wl)
+{
+	WL_TRACE(("wl%d: wl_init\n", wl->pub->unit));
+
+	wl_reset(wl);
+
+	wlc_init(wl->wlc);
+}
+
+uint
+wl_reset(wl_info_t *wl)
+{
+	uint32 macintmask;
+
+	WL_TRACE(("wl%d: wl_reset\n", wl->pub->unit));
+
+	macintmask = wl_intrsoff(wl);
+
+	wlc_reset(wl->wlc);
+
+	wl_intrsrestore(wl, macintmask);
+
+	wl->resched = 0;
+
+	return (0);
+}
+
+void BCMFASTPATH
+wl_intrson(wl_info_t *wl)
+{
+	unsigned long flags = 0;
+
+	INT_LOCK(wl, flags);
+	wlc_intrson(wl->wlc);
+	INT_UNLOCK(wl, flags);
+}
+
+bool
+wl_alloc_dma_resources(wl_info_t *wl, uint addrwidth)
+{
+	return TRUE;
+}
+
+uint32 BCMFASTPATH
+wl_intrsoff(wl_info_t *wl)
+{
+	unsigned long flags = 0;
+	uint32 status;
+
+	INT_LOCK(wl, flags);
+	status = wlc_intrsoff(wl->wlc);
+	INT_UNLOCK(wl, flags);
+	return status;
+}
+
+void
+wl_intrsrestore(wl_info_t *wl, uint32 macintmask)
+{
+	unsigned long flags = 0;
+
+	INT_LOCK(wl, flags);
+	wlc_intrsrestore(wl->wlc, macintmask);
+	INT_UNLOCK(wl, flags);
+}
+
+int
+wl_up(wl_info_t *wl)
+{
+	int error = 0;
+	wl_if_t *wlif;
+
+	WL_TRACE(("wl%d: wl_up\n", wl->pub->unit));
+
+	if (wl->pub->up)
+		return (0);
+
+	error = wlc_up(wl->wlc);
+
+	if (!error) {
+		for (wlif = wl->if_list; wlif != NULL; wlif = wlif->next) {
+			wl_txflowcontrol(wl, wlif, OFF, ALLPRIO);
+		}
+	}
+
+	return (error);
+}
+
+void
+wl_down(wl_info_t *wl)
+{
+	wl_if_t *wlif;
+	int monitor = 0;
+	uint callbacks, ret_val = 0;
+
+	WL_TRACE(("wl%d: wl_down\n", wl->pub->unit));
+
+	for (wlif = wl->if_list; wlif != NULL; wlif = wlif->next) {
+		if (wlif->dev) {
+			netif_down(wlif->dev);
+			netif_stop_queue(wlif->dev);
+		}
+	}
+
+	if (wl->monitor_dev) {
+		ret_val = wlc_ioctl(wl->wlc, WLC_SET_MONITOR, &monitor, sizeof(int), NULL);
+		if (ret_val != BCME_OK) {
+			WL_ERROR(("%s: Disabling MONITOR failed %d\n", __FUNCTION__, ret_val));
+		}
+	}
+
+	if (wl->wlc)
+		ret_val = wlc_down(wl->wlc);
+
+	callbacks = atomic_read(&wl->callbacks) - ret_val;
+	BCM_REFERENCE(callbacks);
+
+	WL_UNLOCK(wl);
+
+	if (WL_ALL_PASSIVE_ENAB(wl)) {
+		int i = 0;
+		for (i = 0; (atomic_read(&wl->callbacks) > callbacks) && i < 10000; i++) {
+			schedule();
+			flush_scheduled_work();
+		}
+	}
+	else
+	{
+
+		SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
+	}
+
+	WL_LOCK(wl);
+}
+
+static int
+wl_toe_get(wl_info_t *wl, uint32 *toe_ol)
+{
+	if (wlc_iovar_getint(wl->wlc, "toe_ol", toe_ol) != 0)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static int
+wl_toe_set(wl_info_t *wl, uint32 toe_ol)
+{
+	if (wlc_iovar_setint(wl->wlc, "toe_ol", toe_ol) != 0)
+		return -EOPNOTSUPP;
+
+	if (wlc_iovar_setint(wl->wlc, "toe", (toe_ol != 0)) != 0)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static void
+wl_get_driver_info(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	wl_info_t *wl = WL_INFO(dev);
+
+#if WIRELESS_EXT >= 19 || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+	if (!wl || !wl->pub || !wl->wlc || !wl->dev)
+		return;
+#endif
+	bzero(info, sizeof(struct ethtool_drvinfo));
+	snprintf(info->driver, sizeof(info->driver), "wl%d", wl->pub->unit);
+	strncpy(info->version, EPI_VERSION_STR, sizeof(info->version));
+	info->version[(sizeof(info->version))-1] = '\0';
+}
+
+static int
+wl_ethtool(wl_info_t *wl, void *uaddr, wl_if_t *wlif)
+{
+	struct ethtool_drvinfo info;
+	struct ethtool_value edata;
+	uint32 cmd;
+	uint32 toe_cmpnt = 0, csum_dir;
+	int ret;
+
+	if (!wl || !wl->pub || !wl->wlc)
+		return -ENODEV;
+
+	WL_TRACE(("wl%d: %s\n", wl->pub->unit, __FUNCTION__));
+
+	if (copy_from_user(&cmd, uaddr, sizeof(uint32)))
+		return (-EFAULT);
+
+	switch (cmd) {
+	case ETHTOOL_GDRVINFO:
+		if (!wl->dev)
+			return -ENETDOWN;
+
+		wl_get_driver_info(wl->dev, &info);
+		info.cmd = cmd;
+		if (copy_to_user(uaddr, &info, sizeof(info)))
+			return (-EFAULT);
+		break;
+
+	case ETHTOOL_GRXCSUM:
+	case ETHTOOL_GTXCSUM:
+		if ((ret = wl_toe_get(wl, &toe_cmpnt)) < 0)
+			return ret;
+
+		csum_dir = (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+
+		edata.cmd = cmd;
+		edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
+
+		if (copy_to_user(uaddr, &edata, sizeof(edata)))
+			return (-EFAULT);
+		break;
+
+	case ETHTOOL_SRXCSUM:
+	case ETHTOOL_STXCSUM:
+		if (copy_from_user(&edata, uaddr, sizeof(edata)))
+			return (-EFAULT);
+
+		if ((ret = wl_toe_get(wl, &toe_cmpnt)) < 0)
+			return ret;
+
+		csum_dir = (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+
+		if (edata.data != 0)
+			toe_cmpnt |= csum_dir;
+		else
+			toe_cmpnt &= ~csum_dir;
+
+		if ((ret = wl_toe_set(wl, toe_cmpnt)) < 0)
+			return ret;
+
+		if (cmd == ETHTOOL_STXCSUM) {
+			if (!wl->dev)
+				return -ENETDOWN;
+			if (edata.data)
+				wl->dev->features |= NETIF_F_IP_CSUM;
+			else
+				wl->dev->features &= ~NETIF_F_IP_CSUM;
+		}
+
+		break;
+
+	default:
+		return (-EOPNOTSUPP);
+
+	}
+
+	return (0);
+}
+
+int
+wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	wl_info_t *wl;
+	wl_if_t *wlif;
+	void *buf = NULL;
+	wl_ioctl_t ioc;
+	int bcmerror;
+
+	if (!dev)
+		return -ENETDOWN;
+
+	wl = WL_INFO(dev);
+	wlif = WL_DEV_IF(dev);
+	if (wlif == NULL || wl == NULL || wl->dev == NULL)
+		return -ENETDOWN;
+
+	bcmerror = 0;
+
+	WL_TRACE(("wl%d: wl_ioctl: cmd 0x%x\n", wl->pub->unit, cmd));
+
+#ifdef USE_IW
+
+	if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
+
+		return wl_iw_ioctl(dev, ifr, cmd);
+	}
+#endif 
+
+	if (cmd == SIOCETHTOOL)
+		return (wl_ethtool(wl, (void*)ifr->ifr_data, wlif));
+
+	switch (cmd) {
+		case SIOCDEVPRIVATE :
+			break;
+		default:
+			bcmerror = BCME_UNSUPPORTED;
+			goto done2;
+	}
+
+	if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) {
+		bcmerror = BCME_BADADDR;
+		goto done2;
+	}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
+	if (segment_eq(get_fs(), KERNEL_DS))
+#else
+	if (uaccess_kernel())
+#endif
+		buf = ioc.buf;
+
+	else if (ioc.buf) {
+#else
+	if (ioc.buf) {
+#endif
+		if (!(buf = (void *) MALLOC(wl->osh, MAX(ioc.len, WLC_IOCTL_MAXLEN)))) {
+			bcmerror = BCME_NORESOURCE;
+			goto done2;
+		}
+
+		if (copy_from_user(buf, ioc.buf, ioc.len)) {
+			bcmerror = BCME_BADADDR;
+			goto done1;
+		}
+	}
+
+	WL_LOCK(wl);
+		bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
+	WL_UNLOCK(wl);
+
+done1:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
+	if (ioc.buf && (ioc.buf != buf)) {
+#else
+	if (ioc.buf) {
+#endif
+		if (copy_to_user(ioc.buf, buf, ioc.len))
+			bcmerror = BCME_BADADDR;
+		MFREE(wl->osh, buf, MAX(ioc.len, WLC_IOCTL_MAXLEN));
+	}
+
+done2:
+	ASSERT(VALID_BCMERROR(bcmerror));
+	if (bcmerror != 0)
+		wl->pub->bcmerror = bcmerror;
+	return (OSL_ERROR(bcmerror));
+}
+
+int
+wlc_ioctl_internal(struct net_device *dev, int cmd, void *buf, int len)
+{
+	wl_info_t *wl;
+	wl_if_t *wlif;
+	int bcmerror;
+
+	if (!dev)
+		return -ENETDOWN;
+
+	wl = WL_INFO(dev);
+	wlif = WL_DEV_IF(dev);
+	if (wlif == NULL || wl == NULL || wl->dev == NULL)
+		return -ENETDOWN;
+
+	bcmerror = 0;
+
+	WL_TRACE(("wl%d: wlc_ioctl_internal: cmd 0x%x\n", wl->pub->unit, cmd));
+
+	WL_LOCK(wl);
+	if (!capable(CAP_NET_ADMIN)) {
+		bcmerror = BCME_EPERM;
+	} else {
+		bcmerror = wlc_ioctl(wl->wlc, cmd, buf, len, wlif->wlcif);
+	}
+	WL_UNLOCK(wl);
+
+	ASSERT(VALID_BCMERROR(bcmerror));
+	if (bcmerror != 0)
+		wl->pub->bcmerror = bcmerror;
+	return (OSL_ERROR(bcmerror));
+}
+
+static struct net_device_stats*
+wl_get_stats(struct net_device *dev)
+{
+	struct net_device_stats *stats_watchdog = NULL;
+	struct net_device_stats *stats = NULL;
+	wl_info_t *wl;
+	wl_if_t *wlif;
+
+	if (!dev)
+		return NULL;
+
+	if ((wl = WL_INFO(dev)) == NULL)
+		return NULL;
+
+	if ((wlif = WL_DEV_IF(dev)) == NULL)
+		return NULL;
+
+	if ((stats = &wlif->stats) == NULL)
+		return NULL;
+
+	WL_TRACE(("wl%d: wl_get_stats\n", wl->pub->unit));
+
+	ASSERT(wlif->stats_id < 2);
+	stats_watchdog = &wlif->stats_watchdog[wlif->stats_id];
+	memcpy(stats, stats_watchdog, sizeof(struct net_device_stats));
+	return (stats);
+}
+
+#ifdef USE_IW
+struct iw_statistics *
+wl_get_wireless_stats(struct net_device *dev)
+{
+	int res = 0;
+	wl_info_t *wl;
+	wl_if_t *wlif;
+	struct iw_statistics *wstats = NULL;
+	struct iw_statistics *wstats_watchdog = NULL;
+	int phy_noise, rssi;
+
+	if (!dev)
+		return NULL;
+
+	if ((wl = WL_INFO(dev)) == NULL)
+		return NULL;
+
+	if ((wlif = WL_DEV_IF(dev)) == NULL)
+		return NULL;
+
+	if ((wstats = &wlif->wstats) == NULL)
+		return NULL;
+
+	WL_TRACE(("wl%d: wl_get_wireless_stats\n", wl->pub->unit));
+
+	ASSERT(wlif->stats_id < 2);
+	wstats_watchdog = &wlif->wstats_watchdog[wlif->stats_id];
+
+	phy_noise = wlif->phy_noise;
+#if WIRELESS_EXT > 11
+	wstats->discard.nwid = 0;
+	wstats->discard.code = wstats_watchdog->discard.code;
+	wstats->discard.fragment = wstats_watchdog->discard.fragment;
+	wstats->discard.retries = wstats_watchdog->discard.retries;
+	wstats->discard.misc = wstats_watchdog->discard.misc;
+
+	wstats->miss.beacon = 0;
+#endif 
+
+	if (AP_ENAB(wl->pub))
+		rssi = 0;
+	else {
+		scb_val_t scb;
+		res = wlc_ioctl(wl->wlc, WLC_GET_RSSI, &scb, sizeof(int), wlif->wlcif);
+		if (res) {
+			WL_ERROR(("wl%d: %s: WLC_GET_RSSI failed (%d)\n",
+				wl->pub->unit, __FUNCTION__, res));
+			return NULL;
+		}
+		rssi = scb.val;
+	}
+
+	if (rssi <= WLC_RSSI_NO_SIGNAL)
+		wstats->qual.qual = 0;
+	else if (rssi <= WLC_RSSI_VERY_LOW)
+		wstats->qual.qual = 1;
+	else if (rssi <= WLC_RSSI_LOW)
+		wstats->qual.qual = 2;
+	else if (rssi <= WLC_RSSI_GOOD)
+		wstats->qual.qual = 3;
+	else if (rssi <= WLC_RSSI_VERY_GOOD)
+		wstats->qual.qual = 4;
+	else
+		wstats->qual.qual = 5;
+
+	wstats->qual.level = 0x100 + rssi;
+	wstats->qual.noise = 0x100 + phy_noise;
+#if WIRELESS_EXT > 18
+	wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM);
+#else
+	wstats->qual.updated |= 7;
+#endif 
+
+	return wstats;
+}
+#endif 
+
+static int
+wl_set_mac_address(struct net_device *dev, void *addr)
+{
+	int err = 0;
+	wl_info_t *wl;
+	struct sockaddr *sa = (struct sockaddr *) addr;
+
+	if (!dev)
+		return -ENETDOWN;
+
+	wl = WL_INFO(dev);
+
+	WL_TRACE(("wl%d: wl_set_mac_address\n", wl->pub->unit));
+
+	WL_LOCK(wl);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0)
+	bcopy(sa->sa_data, dev->dev_addr, ETHER_ADDR_LEN);
+#else
+	dev_addr_mod(dev, 0, sa->sa_data, ETHER_ADDR_LEN);
+#endif
+	err = wlc_iovar_op(wl->wlc, "cur_etheraddr", NULL, 0, sa->sa_data, ETHER_ADDR_LEN,
+		IOV_SET, (WL_DEV_IF(dev))->wlcif);
+	WL_UNLOCK(wl);
+	if (err)
+		WL_ERROR(("wl%d: wl_set_mac_address: error setting MAC addr override\n",
+			wl->pub->unit));
+	return err;
+}
+
+static void
+wl_set_multicast_list(struct net_device *dev)
+{
+	if (!WL_ALL_PASSIVE_ENAB((wl_info_t *)WL_INFO(dev)))
+		_wl_set_multicast_list(dev);
+	else {
+		wl_info_t *wl = WL_INFO(dev);
+		wl->multicast_task.context = dev;
+
+		if (schedule_work(&wl->multicast_task.work)) {
+
+			atomic_inc(&wl->callbacks);
+		}
+	}
+}
+
+static void
+_wl_set_multicast_list(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
+	struct dev_mc_list *mclist;
+#else
+	struct netdev_hw_addr *ha;
+#endif
+	wl_info_t *wl;
+	int i, buflen;
+	struct maclist *maclist;
+	int allmulti;
+
+	if (!dev)
+		return;
+	wl = WL_INFO(dev);
+
+	WL_TRACE(("wl%d: wl_set_multicast_list\n", wl->pub->unit));
+
+	if (wl->pub->up) {
+		allmulti = (dev->flags & IFF_ALLMULTI)? TRUE: FALSE;
+
+		buflen = sizeof(struct maclist) + (MAXMULTILIST * ETHER_ADDR_LEN);
+
+		if ((maclist = MALLOC(wl->pub->osh, buflen)) == NULL) {
+			return;
+		}
+
+		i = 0;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
+		for (mclist = dev->mc_list; mclist && (i < dev->mc_count); mclist = mclist->next) {
+			if (i >= MAXMULTILIST) {
+				allmulti = TRUE;
+				i = 0;
+				break;
+			}
+			bcopy(mclist->dmi_addr, &maclist->ea[i++], ETHER_ADDR_LEN);
+		}
+#else
+		netdev_for_each_mc_addr(ha, dev) {
+			if (i >= MAXMULTILIST) {
+				allmulti = TRUE;
+				i = 0;
+				break;
+			}
+			bcopy(ha->addr, &maclist->ea[i++], ETHER_ADDR_LEN);
+		}
+#endif 
+		maclist->count = i;
+
+		WL_LOCK(wl);
+
+		wlc_iovar_op(wl->wlc, "allmulti", NULL, 0, &allmulti, sizeof(allmulti), IOV_SET,
+			(WL_DEV_IF(dev))->wlcif);
+		wlc_set(wl->wlc, WLC_SET_PROMISC, (dev->flags & IFF_PROMISC));
+
+		wlc_iovar_op(wl->wlc, "mcast_list", NULL, 0, maclist, buflen, IOV_SET,
+			(WL_DEV_IF(dev))->wlcif);
+
+		WL_UNLOCK(wl);
+		MFREE(wl->pub->osh, maclist, buflen);
+	}
+
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+irqreturn_t BCMFASTPATH
+wl_isr(int irq, void *dev_id)
+#else
+irqreturn_t BCMFASTPATH
+wl_isr(int irq, void *dev_id, struct pt_regs *ptregs)
+#endif 
+{
+	wl_info_t *wl;
+	bool ours, wantdpc;
+	unsigned long flags;
+
+	wl = (wl_info_t*) dev_id;
+
+	WL_ISRLOCK(wl, flags);
+
+	if ((ours = wlc_isr(wl->wlc, &wantdpc))) {
+
+		if (wantdpc) {
+
+			ASSERT(wl->resched == FALSE);
+			if (WL_ALL_PASSIVE_ENAB(wl)) {
+				if (schedule_work(&wl->wl_dpc_task.work))
+					atomic_inc(&wl->callbacks);
+				else
+					ASSERT(0);
+			} else
+			tasklet_schedule(&wl->tasklet);
+		}
+	}
+
+	WL_ISRUNLOCK(wl, flags);
+
+	return IRQ_RETVAL(ours);
+}
+
+static void BCMFASTPATH
+wl_dpc(ulong data)
+{
+	wl_info_t *wl;
+
+	wl = (wl_info_t *)data;
+
+	WL_LOCK(wl);
+
+	if (wl->pub->up) {
+		wlc_dpc_info_t dpci = {0};
+
+		if (wl->resched) {
+			unsigned long flags = 0;
+			INT_LOCK(wl, flags);
+			wlc_intrsupd(wl->wlc);
+			INT_UNLOCK(wl, flags);
+		}
+
+		wl->resched = wlc_dpc(wl->wlc, TRUE, &dpci);
+
+		wl->processed = dpci.processed;
+	}
+
+	if (!wl->pub->up) {
+
+		if ((WL_ALL_PASSIVE_ENAB(wl))) {
+			atomic_dec(&wl->callbacks);
+		}
+		goto done;
+	}
+
+	if (wl->resched) {
+		if (!(WL_ALL_PASSIVE_ENAB(wl)))
+			tasklet_schedule(&wl->tasklet);
+		else
+			if (!schedule_work(&wl->wl_dpc_task.work)) {
+
+				ASSERT(0);
+			}
+	}
+	else {
+
+		if (WL_ALL_PASSIVE_ENAB(wl))
+			atomic_dec(&wl->callbacks);
+		wl_intrson(wl);
+	}
+
+done:
+	WL_UNLOCK(wl);
+	return;
+}
+
+static void BCMFASTPATH
+wl_dpc_rxwork(struct wl_task *task)
+{
+	wl_info_t *wl = (wl_info_t *)task->context;
+	WL_TRACE(("wl%d: %s\n", wl->pub->unit, __FUNCTION__));
+
+	wl_dpc((unsigned long)wl);
+	return;
+}
+
+void BCMFASTPATH
+wl_sendup(wl_info_t *wl, wl_if_t *wlif, void *p, int numpkt)
+{
+	struct sk_buff *skb;
+	bool brcm_specialpkt;
+
+	WL_TRACE(("wl%d: wl_sendup: %d bytes\n", wl->pub->unit, PKTLEN(wl->osh, p)));
+
+	brcm_specialpkt =
+		(ntoh16_ua(PKTDATA(wl->pub->osh, p) + ETHER_TYPE_OFFSET) == ETHER_TYPE_BRCM);
+
+	if (!brcm_specialpkt) {
+
+	}
+
+	if (wlif) {
+
+		if (!wlif->dev || !netif_device_present(wlif->dev)) {
+			WL_ERROR(("wl%d: wl_sendup: interface not ready\n", wl->pub->unit));
+			PKTFREE(wl->osh, p, FALSE);
+			return;
+		}
+
+		skb = PKTTONATIVE(wl->osh, p);
+		skb->dev = wlif->dev;
+	} else {
+
+		skb = PKTTONATIVE(wl->osh, p);
+		skb->dev = wl->dev;
+
+	}
+
+	skb->protocol = eth_type_trans(skb, skb->dev);
+
+	if (!brcm_specialpkt && !ISALIGNED(skb->data, 4)) {
+		WL_ERROR(("Unaligned assert. skb %p. skb->data %p.\n", skb, skb->data));
+		if (wlif) {
+			WL_ERROR(("wl_sendup: dev name is %s (wlif) \n", wlif->dev->name));
+			WL_ERROR(("wl_sendup: hard header len  %d (wlif) \n",
+				wlif->dev->hard_header_len));
+		}
+		WL_ERROR(("wl_sendup: dev name is %s (wl) \n", wl->dev->name));
+		WL_ERROR(("wl_sendup: hard header len %d (wl) \n", wl->dev->hard_header_len));
+		ASSERT(ISALIGNED(skb->data, 4));
+	}
+
+	WL_APSTA_RX(("wl%d: wl_sendup(): pkt %p summed %d on interface %p (%s)\n",
+		wl->pub->unit, p, skb->ip_summed, wlif, skb->dev->name));
+
+	netif_rx(skb);
+
+}
+
+int
+wl_osl_pcie_rc(struct wl_info *wl, uint op, int param)
+{
+	return 0;
+}
+
+void
+wl_dump_ver(wl_info_t *wl, struct bcmstrbuf *b)
+{
+	bcm_bprintf(b, "wl%d: version %s\n", wl->pub->unit, EPI_VERSION_STR);
+}
+
+#if defined(BCMDBG)
+static int
+wl_dump(wl_info_t *wl, struct bcmstrbuf *b)
+{
+	wl_if_t *p;
+	int i;
+
+	wl_dump_ver(wl, b);
+
+	bcm_bprintf(b, "name %s dev %p tbusy %d callbacks %d malloced %d\n",
+		wl->dev->name, wl->dev, (uint)netif_queue_stopped(wl->dev),
+		atomic_read(&wl->callbacks), MALLOCED(wl->osh));
+
+	p = wl->if_list;
+	if (p)
+		p = p->next;
+	for (i = 0; p != NULL; p = p->next, i++) {
+		if ((i % 4) == 0) {
+			if (i != 0)
+				bcm_bprintf(b, "\n");
+			bcm_bprintf(b, "Interfaces:");
+		}
+		bcm_bprintf(b, " name %s dev %p", p->dev->name, p->dev);
+	}
+	if (i)
+		bcm_bprintf(b, "\n");
+
+	return 0;
+}
+#endif 
+
+static void
+wl_link_up(wl_info_t *wl, char *ifname)
+{
+	WL_ERROR(("wl%d: link up (%s)\n", wl->pub->unit, ifname));
+}
+
+static void
+wl_link_down(wl_info_t *wl, char *ifname)
+{
+	WL_ERROR(("wl%d: link down (%s)\n", wl->pub->unit, ifname));
+}
+
+void
+wl_event(wl_info_t *wl, char *ifname, wlc_event_t *e)
+{
+#ifdef USE_IW
+	wl_iw_event(wl->dev, &(e->event), e->data);
+#endif 
+
+#if defined(USE_CFG80211)
+	wl_cfg80211_event(wl->dev, &(e->event), e->data);
+#endif
+	switch (e->event.event_type) {
+	case WLC_E_LINK:
+	case WLC_E_NDIS_LINK:
+		if (e->event.flags&WLC_EVENT_MSG_LINK)
+			wl_link_up(wl, ifname);
+		else
+			wl_link_down(wl, ifname);
+		break;
+#if defined(WL_CONFIG_RFKILL)
+	case WLC_E_RADIO: {
+		mbool i;
+		if (wlc_get(wl->wlc, WLC_GET_RADIO, &i) < 0)
+			WL_ERROR(("%s: WLC_GET_RADIO failed\n", __FUNCTION__));
+		if (wl->last_phyind == (mbool)(i & WL_RADIO_HW_DISABLE))
+			break;
+
+		wl->last_phyind = (mbool)(i & WL_RADIO_HW_DISABLE);
+
+		WL_ERROR(("wl%d: Radio hardware state changed to %d\n", wl->pub->unit, i));
+		wl_report_radio_state(wl);
+		break;
+	}
+#else
+	case WLC_E_RADIO:
+		break;
+#endif 
+	}
+}
+
+void
+wl_event_sync(wl_info_t *wl, char *ifname, wlc_event_t *e)
+{
+}
+
+static void BCMFASTPATH
+wl_sched_tx_tasklet(void *t)
+{
+	wl_info_t *wl = (wl_info_t *)t;
+	tasklet_schedule(&wl->tx_tasklet);
+}
+
+#define WL_CONFIG_SMP()	FALSE
+
+static int BCMFASTPATH
+wl_start(struct sk_buff *skb, struct net_device *dev)
+{
+	wl_if_t *wlif;
+	wl_info_t *wl;
+
+	if (!dev)
+		return -ENETDOWN;
+
+	wlif = WL_DEV_IF(dev);
+	wl = WL_INFO(dev);
+
+		skb->prev = NULL;
+	if (WL_ALL_PASSIVE_ENAB(wl) || (WL_RTR() && WL_CONFIG_SMP())) {
+
+		TXQ_LOCK(wl);
+
+		if ((wl_txq_thresh > 0) && (wl->txq_cnt >= wl_txq_thresh)) {
+			PKTFRMNATIVE(wl->osh, skb);
+			PKTCFREE(wl->osh, skb, TRUE);
+			TXQ_UNLOCK(wl);
+			return 0;
+		}
+
+		if (wl->txq_head == NULL)
+			wl->txq_head = skb;
+		else
+			wl->txq_tail->prev = skb;
+		wl->txq_tail = skb;
+		wl->txq_cnt++;
+
+		if (!wl->txq_dispatched) {
+			int32 err = 0;
+
+			if (!WL_ALL_PASSIVE_ENAB(wl))
+				wl_sched_tx_tasklet(wl);
+			else
+				err = (int32)(schedule_work(&wl->txq_task.work) == 0);
+
+			if (!err) {
+				atomic_inc(&wl->callbacks);
+				wl->txq_dispatched = TRUE;
+			} else
+				WL_ERROR(("wl%d: wl_start/schedule_work failed\n",
+				          wl->pub->unit));
+		}
+
+		TXQ_UNLOCK(wl);
+	} else
+		return wl_start_int(wl, wlif, skb);
+
+	return (0);
+}
+
+static void BCMFASTPATH
+wl_start_txqwork(wl_task_t *task)
+{
+	wl_info_t *wl = (wl_info_t *)task->context;
+	struct sk_buff *skb;
+
+	WL_TRACE(("wl%d: %s txq_cnt %d\n", wl->pub->unit, __FUNCTION__, wl->txq_cnt));
+
+#ifdef BCMDBG
+	if (wl->txq_cnt >= 500)
+		WL_ERROR(("wl%d: WARNING dispatching over 500 packets in txqwork(%d)\n",
+			wl->pub->unit, wl->txq_cnt));
+#endif
+
+	TXQ_LOCK(wl);
+	while (wl->txq_head) {
+		skb = wl->txq_head;
+		wl->txq_head = skb->prev;
+		skb->prev = NULL;
+		if (wl->txq_head == NULL)
+			wl->txq_tail = NULL;
+		wl->txq_cnt--;
+		TXQ_UNLOCK(wl);
+
+		wl_start_int(wl, WL_DEV_IF(skb->dev), skb);
+
+		TXQ_LOCK(wl);
+	}
+
+	wl->txq_dispatched = FALSE;
+	atomic_dec(&wl->callbacks);
+	TXQ_UNLOCK(wl);
+
+	return;
+}
+
+static void BCMFASTPATH
+wl_tx_tasklet(ulong data)
+{
+	wl_task_t task;
+	task.context = (void *)data;
+	wl_start_txqwork(&task);
+}
+
+static void
+wl_txq_free(wl_info_t *wl)
+{
+	struct sk_buff *skb;
+
+	if (wl->txq_head == NULL) {
+		ASSERT(wl->txq_tail == NULL);
+		return;
+	}
+
+	while (wl->txq_head) {
+		skb = wl->txq_head;
+		wl->txq_head = skb->prev;
+		wl->txq_cnt--;
+		PKTFRMNATIVE(wl->osh, skb);
+		PKTCFREE(wl->osh, skb, TRUE);
+	}
+
+	wl->txq_tail = NULL;
+}
+
+static void
+wl_set_multicast_list_workitem(struct work_struct *work)
+{
+	wl_task_t *task = (wl_task_t *)work;
+	struct net_device *dev = (struct net_device*)task->context;
+	wl_info_t *wl;
+
+	wl = WL_INFO(dev);
+
+	atomic_dec(&wl->callbacks);
+
+	_wl_set_multicast_list(dev);
+}
+
+static void
+wl_timer_task(wl_task_t *task)
+{
+	wl_timer_t *t = (wl_timer_t *)task->context;
+
+	_wl_timer(t);
+	MFREE(t->wl->osh, task, sizeof(wl_task_t));
+
+	atomic_dec(&t->wl->callbacks);
+}
+
+static void
+wl_timer(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
+		struct timer_list *tl
+#else
+		ulong data
+#endif
+) {
+	wl_timer_t *t =
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
+		from_timer(t, tl, timer);
+#else
+		(wl_timer_t *)data;
+#endif
+
+	if (!WL_ALL_PASSIVE_ENAB(t->wl))
+		_wl_timer(t);
+	else
+		wl_schedule_task(t->wl, wl_timer_task, t);
+}
+
+static void
+_wl_timer(wl_timer_t *t)
+{
+	wl_info_t *wl = t->wl;
+
+	WL_LOCK(wl);
+
+	if (t->set && (!timer_pending(&t->timer))) {
+		if (t->periodic) {
+			t->timer.expires = jiffies + t->ms*HZ/1000;
+			atomic_inc(&wl->callbacks);
+			add_timer(&t->timer);
+			t->set = TRUE;
+		} else
+			t->set = FALSE;
+
+		t->fn(t->arg);
+#ifdef BCMDBG
+		wlc_update_perf_stats(wl->wlc, WLC_PERF_STATS_TMR_DPC);
+		t->ticks++;
+#endif
+
+	}
+
+	atomic_dec(&wl->callbacks);
+
+	WL_UNLOCK(wl);
+}
+
+wl_timer_t *
+wl_init_timer(wl_info_t *wl, void (*fn)(void *arg), void *arg, const char *tname)
+{
+	wl_timer_t *t;
+
+	t = (wl_timer_t*)MALLOC(wl->osh, sizeof(wl_timer_t));
+
+	if (t == NULL) {
+		WL_ERROR(("wl%d: wl_init_timer: out of memory, malloced %d bytes\n",
+			wl->unit, MALLOCED(wl->osh)));
+		return 0;
+	}
+
+	bzero(t, sizeof(wl_timer_t));
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
+	timer_setup(&t->timer, wl_timer, 0);
+#else
+	init_timer(&t->timer);
+	t->timer.data = (ulong) t;
+	t->timer.function = wl_timer;
+#endif
+	t->wl = wl;
+	t->fn = fn;
+	t->arg = arg;
+	t->next = wl->timers;
+	wl->timers = t;
+
+#ifdef BCMDBG
+	if ((t->name = MALLOC(wl->osh, strlen(tname) + 1)))
+		strcpy(t->name, tname);
+#endif
+
+	return t;
+}
+
+void
+wl_add_timer(wl_info_t *wl, wl_timer_t *t, uint ms, int periodic)
+{
+#ifdef BCMDBG
+	if (t->set) {
+		WL_ERROR(("%s: Already set. Name: %s, per %d\n",
+			__FUNCTION__, t->name, periodic));
+	}
+#endif
+
+	t->ms = ms;
+	t->periodic = (bool) periodic;
+
+	if (t->set)
+		return;
+
+	t->set = TRUE;
+	t->timer.expires = jiffies + ms*HZ/1000;
+
+	atomic_inc(&wl->callbacks);
+	add_timer(&t->timer);
+}
+
+bool
+wl_del_timer(wl_info_t *wl, wl_timer_t *t)
+{
+	ASSERT(t);
+	if (t->set) {
+		t->set = FALSE;
+		if (!del_timer(&t->timer)) {
+#ifdef BCMDBG
+			WL_INFORM(("wl%d: Failed to delete timer %s\n", wl->unit, t->name));
+#endif
+			return TRUE;
+		}
+		atomic_dec(&wl->callbacks);
+	}
+
+	return TRUE;
+}
+
+void
+wl_free_timer(wl_info_t *wl, wl_timer_t *t)
+{
+	wl_timer_t *tmp;
+
+	wl_del_timer(wl, t);
+
+	if (wl->timers == t) {
+		wl->timers = wl->timers->next;
+#ifdef BCMDBG
+		if (t->name)
+			MFREE(wl->osh, t->name, strlen(t->name) + 1);
+#endif
+		MFREE(wl->osh, t, sizeof(wl_timer_t));
+		return;
+
+	}
+
+	tmp = wl->timers;
+	while (tmp) {
+		if (tmp->next == t) {
+			tmp->next = t->next;
+#ifdef BCMDBG
+			if (t->name)
+				MFREE(wl->osh, t->name, strlen(t->name) + 1);
+#endif
+			MFREE(wl->osh, t, sizeof(wl_timer_t));
+			return;
+		}
+		tmp = tmp->next;
+	}
+
+}
+
+void
+wl_monitor(wl_info_t *wl, wl_rxsts_t *rxsts, void *p)
+{
+	struct sk_buff *oskb = (struct sk_buff *)p;
+	struct sk_buff *skb;
+	uchar *pdata;
+	uint len;
+
+	len = 0;
+	skb = NULL;
+	WL_TRACE(("wl%d: wl_monitor\n", wl->pub->unit));
+
+	if (!wl->monitor_dev)
+		return;
+
+	if (wl->monitor_type == 1) {
+		p80211msg_t *phdr;
+
+		len = sizeof(p80211msg_t) + oskb->len - D11_PHY_HDR_LEN;
+		if ((skb = dev_alloc_skb(len)) == NULL) {
+			WL_ERROR(("%s: dev_alloc_skb() failure, mon type 1",  __FUNCTION__));
+			return;
+		}
+
+		skb_put(skb, len);
+		phdr = (p80211msg_t*)skb->data;
+
+		phdr->msgcode = WL_MON_FRAME;
+		phdr->msglen = sizeof(p80211msg_t);
+		strcpy(phdr->devname, wl->dev->name);
+
+		phdr->hosttime.did = WL_MON_FRAME_HOSTTIME;
+		phdr->hosttime.status = P80211ITEM_OK;
+		phdr->hosttime.len = 4;
+		phdr->hosttime.data = jiffies;
+
+		phdr->channel.did = WL_MON_FRAME_CHANNEL;
+		phdr->channel.status = P80211ITEM_NO_VALUE;
+		phdr->channel.len = 4;
+		phdr->channel.data = 0;
+
+		phdr->signal.did = WL_MON_FRAME_SIGNAL;
+		phdr->signal.status = P80211ITEM_OK;
+		phdr->signal.len = 4;
+
+		phdr->signal.data = rxsts->preamble;
+
+		phdr->noise.did = WL_MON_FRAME_NOISE;
+		phdr->noise.status = P80211ITEM_NO_VALUE;
+		phdr->noise.len = 4;
+		phdr->noise.data = 0;
+
+		phdr->rate.did = WL_MON_FRAME_RATE;
+		phdr->rate.status = P80211ITEM_OK;
+		phdr->rate.len = 4;
+		phdr->rate.data = rxsts->datarate;
+
+		phdr->istx.did = WL_MON_FRAME_ISTX;
+		phdr->istx.status = P80211ITEM_NO_VALUE;
+		phdr->istx.len = 4;
+		phdr->istx.data = 0;
+
+		phdr->mactime.did = WL_MON_FRAME_MACTIME;
+		phdr->mactime.status = P80211ITEM_OK;
+		phdr->mactime.len = 4;
+		phdr->mactime.data = rxsts->mactime;
+
+		phdr->rssi.did = WL_MON_FRAME_RSSI;
+		phdr->rssi.status = P80211ITEM_OK;
+		phdr->rssi.len = 4;
+		phdr->rssi.data = rxsts->signal;		
+
+		phdr->sq.did = WL_MON_FRAME_SQ;
+		phdr->sq.status = P80211ITEM_OK;
+		phdr->sq.len = 4;
+		phdr->sq.data = rxsts->sq;
+
+		phdr->frmlen.did = WL_MON_FRAME_FRMLEN;
+		phdr->frmlen.status = P80211ITEM_OK;
+		phdr->frmlen.status = P80211ITEM_OK;
+		phdr->frmlen.len = 4;
+		phdr->frmlen.data = rxsts->pktlength;
+
+		pdata = skb->data + sizeof(p80211msg_t);
+		bcopy(oskb->data + D11_PHY_HDR_LEN, pdata, oskb->len - D11_PHY_HDR_LEN);
+
+	}
+	else if (wl->monitor_type == 2) {
+		int channel_frequency;
+		uint16 channel_flags;
+		uint8 flags;
+		uint16 rtap_len;
+		struct dot11_header *mac_header;
+		uint16 fc;
+
+		if (rxsts->phytype != WL_RXS_PHY_N)
+			rtap_len = sizeof(wl_radiotap_legacy_t);
+		else
+			rtap_len = sizeof(wl_radiotap_ht_brcm_2_t);
+
+		len = rtap_len + (oskb->len - D11_PHY_HDR_LEN);
+		if ((skb = dev_alloc_skb(len)) == NULL) {
+			WL_ERROR(("%s: dev_alloc_skb() failure, mon type 2",  __FUNCTION__));
+			return;
+		}
+
+		skb_put(skb, len);
+
+		if (CHSPEC_IS2G(rxsts->chanspec)) {
+			channel_flags = IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN;
+			channel_frequency = wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			                                   WF_CHAN_FACTOR_2_4_G);
+		} else {
+			channel_flags = IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM;
+			channel_frequency = wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			                                   WF_CHAN_FACTOR_5_G);
+		}
+
+		mac_header = (struct dot11_header *)(oskb->data + D11_PHY_HDR_LEN);
+		fc = ltoh16(mac_header->fc);
+
+		flags = IEEE80211_RADIOTAP_F_FCS;
+
+		if (rxsts->preamble == WL_RXS_PREAMBLE_SHORT)
+			flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+		if (fc & FC_WEP)
+			flags |= IEEE80211_RADIOTAP_F_WEP;
+
+		if (fc & FC_MOREFRAG)
+			flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+		if (rxsts->pkterror & WL_RXS_CRC_ERROR)
+			flags |= IEEE80211_RADIOTAP_F_BADFCS;
+
+		if (rxsts->phytype != WL_RXS_PHY_N) {
+			wl_radiotap_legacy_t *rtl = (wl_radiotap_legacy_t *)skb->data;
+
+			rtl->ieee_radiotap.it_version = 0;
+			rtl->ieee_radiotap.it_pad = 0;
+			rtl->ieee_radiotap.it_len = HTOL16(rtap_len);
+			rtl->ieee_radiotap.it_present = HTOL32(WL_RADIOTAP_PRESENT_LEGACY);
+
+			rtl->tsft_l = htol32(rxsts->mactime);
+			rtl->tsft_h = 0;
+			rtl->flags = flags;
+			rtl->rate = rxsts->datarate;
+			rtl->channel_freq = HTOL16(channel_frequency);
+			rtl->channel_flags = HTOL16(channel_flags);
+			rtl->signal = (int8)rxsts->signal;
+			rtl->noise = (int8)rxsts->noise;
+			rtl->antenna = rxsts->antenna;
+
+			memcpy(rtl->vend_oui, brcm_oui, sizeof(brcm_oui));
+			rtl->vend_skip_len = WL_RADIOTAP_LEGACY_SKIP_LEN;
+			rtl->vend_sns = 0;
+
+			memset(&rtl->nonht_vht, 0, sizeof(rtl->nonht_vht));
+			rtl->nonht_vht.len = WL_RADIOTAP_NONHT_VHT_LEN;
+		} else {
+			wl_radiotap_ht_brcm_2_t *rtht = (wl_radiotap_ht_brcm_2_t *)skb->data;
+
+			rtht->ieee_radiotap.it_version = 0;
+			rtht->ieee_radiotap.it_pad = 0;
+			rtht->ieee_radiotap.it_len = HTOL16(rtap_len);
+			rtht->ieee_radiotap.it_present = HTOL32(WL_RADIOTAP_PRESENT_HT_BRCM2);
+			rtht->it_present_ext = HTOL32(WL_RADIOTAP_BRCM2_HT_MCS);
+			rtht->pad1 = 0;
+
+			rtht->tsft_l = htol32(rxsts->mactime);
+			rtht->tsft_h = 0;
+			rtht->flags = flags;
+			rtht->pad2 = 0;
+			rtht->channel_freq = HTOL16(channel_frequency);
+			rtht->channel_flags = HTOL16(channel_flags);
+			rtht->signal = (int8)rxsts->signal;
+			rtht->noise = (int8)rxsts->noise;
+			rtht->antenna = rxsts->antenna;
+			rtht->pad3 = 0;
+
+			memcpy(rtht->vend_oui, brcm_oui, sizeof(brcm_oui));
+			rtht->vend_sns = WL_RADIOTAP_BRCM2_HT_SNS;
+			rtht->vend_skip_len = WL_RADIOTAP_HT_BRCM2_SKIP_LEN;
+			rtht->mcs = rxsts->mcs;
+			rtht->htflags = 0;
+			if (rxsts->htflags & WL_RXS_HTF_40)
+				rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_40;
+			if (rxsts->htflags & WL_RXS_HTF_SGI)
+				rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_SGI;
+			if (rxsts->preamble & WL_RXS_PREAMBLE_HT_GF)
+				rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_GF;
+			if (rxsts->htflags & WL_RXS_HTF_LDPC)
+				rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_LDPC;
+			rtht->htflags |=
+				(rxsts->htflags & WL_RXS_HTF_STBC_MASK) <<
+				IEEE80211_RADIOTAP_HTMOD_STBC_SHIFT;
+		}
+
+		pdata = skb->data + rtap_len;
+		bcopy(oskb->data + D11_PHY_HDR_LEN, pdata, oskb->len - D11_PHY_HDR_LEN);
+	}
+	else if (wl->monitor_type == 3) {
+		int channel_frequency;
+		uint16 channel_flags;
+		uint8 flags;
+		uint16 rtap_len;
+		struct dot11_header * mac_header;
+		uint16 fc;
+
+		if (rxsts->phytype == WL_RXS_PHY_N) {
+			if (rxsts->encoding == WL_RXS_ENCODING_HT)
+				rtap_len = sizeof(wl_radiotap_ht_t);
+			else if (rxsts->encoding == WL_RXS_ENCODING_VHT)
+				rtap_len = sizeof(wl_radiotap_vht_t);
+			else
+				rtap_len = sizeof(wl_radiotap_legacy_t);
+		} else {
+			rtap_len = sizeof(wl_radiotap_legacy_t);
+		}
+
+		len = rtap_len + (oskb->len - D11_PHY_HDR_LEN);
+
+		if (oskb->next) {
+			struct sk_buff *amsdu_p = oskb->next;
+			uint amsdu_len = 0;
+			while (amsdu_p) {
+				amsdu_len += amsdu_p->len;
+				amsdu_p = amsdu_p->next;
+			}
+			len += amsdu_len;
+		}
+
+		if ((skb = dev_alloc_skb(len)) == NULL) {
+			WL_ERROR(("%s: dev_alloc_skb() failure, mon type 3",  __FUNCTION__));
+			return;
+		}
+
+		skb_put(skb, len);
+
+		if (CHSPEC_IS2G(rxsts->chanspec)) {
+			channel_flags = IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN;
+			channel_frequency = wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			                                   WF_CHAN_FACTOR_2_4_G);
+		} else {
+			channel_flags = IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM;
+			channel_frequency = wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			                                   WF_CHAN_FACTOR_5_G);
+		}
+
+		mac_header = (struct dot11_header *)(oskb->data + D11_PHY_HDR_LEN);
+		fc = ltoh16(mac_header->fc);
+
+		flags = IEEE80211_RADIOTAP_F_FCS;
+
+		if (rxsts->preamble == WL_RXS_PREAMBLE_SHORT)
+			flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+		if (fc & FC_WEP)
+			flags |= IEEE80211_RADIOTAP_F_WEP;
+
+		if (fc & FC_MOREFRAG)
+			flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+		if (rxsts->pkterror & WL_RXS_CRC_ERROR)
+			flags |= IEEE80211_RADIOTAP_F_BADFCS;
+
+		if ((rxsts->phytype != WL_RXS_PHY_N) ||
+			((rxsts->encoding != WL_RXS_ENCODING_HT) &&
+			(rxsts->encoding != WL_RXS_ENCODING_VHT))) {
+			wl_radiotap_legacy_t *rtl = (wl_radiotap_legacy_t *)skb->data;
+
+			rtl->ieee_radiotap.it_version = 0;
+			rtl->ieee_radiotap.it_pad = 0;
+			rtl->ieee_radiotap.it_len = HTOL16(rtap_len);
+			rtl->ieee_radiotap.it_present = HTOL32(WL_RADIOTAP_PRESENT_LEGACY);
+
+			rtl->it_present_ext = HTOL32(WL_RADIOTAP_LEGACY_VHT);
+			rtl->tsft_l = htol32(rxsts->mactime);
+			rtl->tsft_h = 0;
+			rtl->flags = flags;
+			rtl->rate = rxsts->datarate;
+			rtl->channel_freq = HTOL16(channel_frequency);
+			rtl->channel_flags = HTOL16(channel_flags);
+			rtl->signal = (int8)rxsts->signal;
+			rtl->noise = (int8)rxsts->noise;
+			rtl->antenna = rxsts->antenna;
+
+			memcpy(rtl->vend_oui, brcm_oui, sizeof(brcm_oui));
+			rtl->vend_skip_len = WL_RADIOTAP_LEGACY_SKIP_LEN;
+			rtl->vend_sns = 0;
+
+			memset(&rtl->nonht_vht, 0, sizeof(rtl->nonht_vht));
+			rtl->nonht_vht.len = WL_RADIOTAP_NONHT_VHT_LEN;
+			if (((fc & FC_KIND_MASK) == FC_RTS) ||
+				((fc & FC_KIND_MASK) == FC_CTS)) {
+				rtl->nonht_vht.flags |= WL_RADIOTAP_F_NONHT_VHT_BW;
+				rtl->nonht_vht.bw = rxsts->bw_nonht;
+				rtl->vend_sns = WL_RADIOTAP_LEGACY_SNS;
+
+			}
+			if ((fc & FC_KIND_MASK) == FC_RTS) {
+				if (rxsts->vhtflags & WL_RXS_VHTF_DYN_BW_NONHT)
+					rtl->nonht_vht.flags
+						|= WL_RADIOTAP_F_NONHT_VHT_DYN_BW;
+			}
+		}
+		else if (rxsts->encoding == WL_RXS_ENCODING_VHT) {
+			wl_radiotap_vht_t *rtvht = (wl_radiotap_vht_t *)skb->data;
+
+			rtvht->ieee_radiotap.it_version = 0;
+			rtvht->ieee_radiotap.it_pad = 0;
+			rtvht->ieee_radiotap.it_len = HTOL16(rtap_len);
+			rtvht->ieee_radiotap.it_present =
+				HTOL32(WL_RADIOTAP_PRESENT_VHT);
+
+			rtvht->tsft_l = htol32(rxsts->mactime);
+			rtvht->tsft_h = 0;
+			rtvht->flags = flags;
+			rtvht->pad1 = 0;
+			rtvht->channel_freq = HTOL16(channel_frequency);
+			rtvht->channel_flags = HTOL16(channel_flags);
+			rtvht->signal = (int8)rxsts->signal;
+			rtvht->noise = (int8)rxsts->noise;
+			rtvht->antenna = rxsts->antenna;
+
+			rtvht->vht_known = (IEEE80211_RADIOTAP_VHT_HAVE_STBC |
+				IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS |
+				IEEE80211_RADIOTAP_VHT_HAVE_GI |
+				IEEE80211_RADIOTAP_VHT_HAVE_SGI_NSYM_DA |
+				IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA |
+				IEEE80211_RADIOTAP_VHT_HAVE_BF |
+				IEEE80211_RADIOTAP_VHT_HAVE_BW |
+				IEEE80211_RADIOTAP_VHT_HAVE_GID |
+				IEEE80211_RADIOTAP_VHT_HAVE_PAID);
+
+			STATIC_ASSERT(WL_RXS_VHTF_STBC ==
+				IEEE80211_RADIOTAP_VHT_STBC);
+			STATIC_ASSERT(WL_RXS_VHTF_TXOP_PS ==
+				IEEE80211_RADIOTAP_VHT_TXOP_PS);
+			STATIC_ASSERT(WL_RXS_VHTF_SGI ==
+				IEEE80211_RADIOTAP_VHT_SGI);
+			STATIC_ASSERT(WL_RXS_VHTF_SGI_NSYM_DA ==
+				IEEE80211_RADIOTAP_VHT_SGI_NSYM_DA);
+			STATIC_ASSERT(WL_RXS_VHTF_LDPC_EXTRA ==
+				IEEE80211_RADIOTAP_VHT_LDPC_EXTRA);
+			STATIC_ASSERT(WL_RXS_VHTF_BF ==
+				IEEE80211_RADIOTAP_VHT_BF);
+
+			rtvht->vht_flags = HTOL16(rxsts->vhtflags);
+
+			STATIC_ASSERT(WL_RXS_VHT_BW_20 ==
+				IEEE80211_RADIOTAP_VHT_BW_20);
+			STATIC_ASSERT(WL_RXS_VHT_BW_40 ==
+				IEEE80211_RADIOTAP_VHT_BW_40);
+			STATIC_ASSERT(WL_RXS_VHT_BW_20L ==
+				IEEE80211_RADIOTAP_VHT_BW_20L);
+			STATIC_ASSERT(WL_RXS_VHT_BW_20U ==
+				IEEE80211_RADIOTAP_VHT_BW_20U);
+			STATIC_ASSERT(WL_RXS_VHT_BW_80 ==
+				IEEE80211_RADIOTAP_VHT_BW_80);
+			STATIC_ASSERT(WL_RXS_VHT_BW_40L ==
+				IEEE80211_RADIOTAP_VHT_BW_40L);
+			STATIC_ASSERT(WL_RXS_VHT_BW_40U ==
+				IEEE80211_RADIOTAP_VHT_BW_40U);
+			STATIC_ASSERT(WL_RXS_VHT_BW_20LL ==
+				IEEE80211_RADIOTAP_VHT_BW_20LL);
+			STATIC_ASSERT(WL_RXS_VHT_BW_20LU ==
+				IEEE80211_RADIOTAP_VHT_BW_20LU);
+			STATIC_ASSERT(WL_RXS_VHT_BW_20UL ==
+				IEEE80211_RADIOTAP_VHT_BW_20UL);
+			STATIC_ASSERT(WL_RXS_VHT_BW_20UU ==
+				IEEE80211_RADIOTAP_VHT_BW_20UU);
+
+			rtvht->vht_bw = rxsts->bw;
+
+			rtvht->vht_mcs_nss[0] = (rxsts->mcs << 4) |
+				(rxsts->nss & IEEE80211_RADIOTAP_VHT_NSS);
+			rtvht->vht_mcs_nss[1] = 0;
+			rtvht->vht_mcs_nss[2] = 0;
+			rtvht->vht_mcs_nss[3] = 0;
+
+			STATIC_ASSERT(WL_RXS_VHTF_CODING_LDCP ==
+				IEEE80211_RADIOTAP_VHT_CODING_LDPC);
+
+			rtvht->vht_coding = rxsts->coding;
+			rtvht->vht_group_id = rxsts->gid;
+			rtvht->vht_partial_aid = HTOL16(rxsts->aid);
+
+			rtvht->ampdu_flags = 0;
+			rtvht->ampdu_delim_crc = 0;
+
+			rtvht->ampdu_ref_num = rxsts->ampdu_counter;
+
+			if (!(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_FIRST) &&
+				!(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_SUB))
+				rtvht->ampdu_flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST;
+
+			if (rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_NONE)
+				rtvht->ampdu_flags |= IEEE80211_RADIOTAP_AMPDU_MPDU_ONLY;
+		}
+		else if (rxsts->encoding == WL_RXS_ENCODING_HT) {
+			wl_radiotap_ht_t *rtht =
+				(wl_radiotap_ht_t *)skb->data;
+
+			rtht->ieee_radiotap.it_version = 0;
+			rtht->ieee_radiotap.it_pad = 0;
+			rtht->ieee_radiotap.it_len = HTOL16(rtap_len);
+			rtht->ieee_radiotap.it_present
+				= HTOL32(WL_RADIOTAP_PRESENT_HT);
+			rtht->pad1 = 0;
+
+			rtht->tsft_l = htol32(rxsts->mactime);
+			rtht->tsft_h = 0;
+			rtht->flags = flags;
+			rtht->channel_freq = HTOL16(channel_frequency);
+			rtht->channel_flags = HTOL16(channel_flags);
+			rtht->signal = (int8)rxsts->signal;
+			rtht->noise = (int8)rxsts->noise;
+			rtht->antenna = rxsts->antenna;
+
+			rtht->mcs_known = (IEEE80211_RADIOTAP_MCS_HAVE_BW |
+				IEEE80211_RADIOTAP_MCS_HAVE_MCS |
+				IEEE80211_RADIOTAP_MCS_HAVE_GI |
+				IEEE80211_RADIOTAP_MCS_HAVE_FEC |
+				IEEE80211_RADIOTAP_MCS_HAVE_FMT);
+
+			rtht->mcs_flags = 0;
+			switch (rxsts->htflags & WL_RXS_HTF_BW_MASK) {
+				case WL_RXS_HTF_20L:
+					rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20L;
+					break;
+				case WL_RXS_HTF_20U:
+					rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20U;
+					break;
+				case WL_RXS_HTF_40:
+					rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_40;
+					break;
+				default:
+					rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20;
+			}
+
+			if (rxsts->htflags & WL_RXS_HTF_SGI) {
+				rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_SGI;
+			}
+			if (rxsts->preamble & WL_RXS_PREAMBLE_HT_GF) {
+				rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_FMT_GF;
+			}
+			if (rxsts->htflags & WL_RXS_HTF_LDPC) {
+				rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_FEC_LDPC;
+			}
+			rtht->mcs_index = rxsts->mcs;
+		}
+
+		pdata = skb->data + rtap_len;
+		bcopy(oskb->data + D11_PHY_HDR_LEN, pdata, oskb->len - D11_PHY_HDR_LEN);
+
+		if (oskb->next) {
+			struct sk_buff *amsdu_p = oskb->next;
+			amsdu_p = oskb->next;
+			pdata += (oskb->len - D11_PHY_HDR_LEN);
+			while (amsdu_p) {
+				bcopy(amsdu_p->data, pdata, amsdu_p->len);
+				pdata += amsdu_p->len;
+				amsdu_p = amsdu_p->next;
+			}
+		}
+	}
+
+	if (skb == NULL) return;
+
+	skb->dev = wl->monitor_dev;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
+	skb->dev->last_rx = jiffies;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+	skb_reset_mac_header(skb);
+#else
+	skb->mac.raw = skb->data;
+#endif
+	skb->ip_summed = CHECKSUM_NONE;
+	skb->pkt_type = PACKET_OTHERHOST;
+	skb->protocol = htons(ETH_P_80211_RAW);
+
+	netif_rx(skb);
+}
+
+static int
+wl_monitor_start(struct sk_buff *skb, struct net_device *dev)
+{
+	wl_info_t *wl;
+
+	wl = WL_DEV_IF(dev)->wl;
+	PKTFREE(wl->osh, skb, FALSE);
+	return 0;
+}
+
+static void
+_wl_add_monitor_if(wl_task_t *task)
+{
+	struct net_device *dev;
+	wl_if_t *wlif = (wl_if_t *) task->context;
+	wl_info_t *wl = wlif->wl;
+
+	WL_TRACE(("wl%d: %s\n", wl->pub->unit, __FUNCTION__));
+	ASSERT(wl);
+	ASSERT(!wl->monitor_dev);
+
+	if ((dev = wl_alloc_linux_if(wlif)) == NULL) {
+		WL_ERROR(("wl%d: %s: wl_alloc_linux_if failed\n", wl->pub->unit, __FUNCTION__));
+		goto done;
+	}
+
+	ASSERT(strlen(wlif->name) > 0);
+#if __GNUC__ < 8
+	strncpy(wlif->dev->name, wlif->name, strlen(wlif->name));
+#else
+	// Should have been:
+	// strncpy(wlif->dev->name, wlif->name, sizeof(wlif->dev->name) - 1);
+	// wlif->dev->name[sizeof(wlif->dev->name) - 1] = '\0';
+	memcpy(wlif->dev->name, wlif->name, strlen(wlif->name));
+#endif
+
+	wl->monitor_dev = dev;
+	if (wl->monitor_type == 1)
+		dev->type = ARPHRD_IEEE80211_PRISM;
+	else
+		dev->type = ARPHRD_IEEE80211_RADIOTAP;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0)
+	bcopy(wl->dev->dev_addr, dev->dev_addr, ETHER_ADDR_LEN);
+#else
+	dev_addr_mod(dev, 0, wl->dev->dev_addr, ETHER_ADDR_LEN);
+#endif
+
+#if defined(WL_USE_NETDEV_OPS)
+	dev->netdev_ops = &wl_netdev_monitor_ops;
+#else
+	dev->hard_start_xmit = wl_monitor_start;
+	dev->do_ioctl = wl_ioctl;
+	dev->get_stats = wl_get_stats;
+#endif 
+
+	if (register_netdev(dev)) {
+		WL_ERROR(("wl%d: %s, register_netdev failed for %s\n",
+			wl->pub->unit, __FUNCTION__, wl->monitor_dev->name));
+		wl->monitor_dev = NULL;
+		goto done;
+	}
+	wlif->dev_registed = TRUE;
+
+done:
+	MFREE(wl->osh, task, sizeof(wl_task_t));
+	atomic_dec(&wl->callbacks);
+}
+
+static void
+_wl_del_monitor(wl_task_t *task)
+{
+	wl_info_t *wl = (wl_info_t *) task->context;
+
+	ASSERT(wl);
+	ASSERT(wl->monitor_dev);
+
+	WL_TRACE(("wl%d: _wl_del_monitor\n", wl->pub->unit));
+
+	wl_free_if(wl, WL_DEV_IF(wl->monitor_dev));
+	wl->monitor_dev = NULL;
+
+	MFREE(wl->osh, task, sizeof(wl_task_t));
+	atomic_dec(&wl->callbacks);
+}
+
+void
+wl_set_monitor(wl_info_t *wl, int val)
+{
+	const char *devname;
+	wl_if_t *wlif;
+
+	WL_TRACE(("wl%d: wl_set_monitor: val %d\n", wl->pub->unit, val));
+	if ((val && wl->monitor_dev) || (!val && !wl->monitor_dev)) {
+		WL_ERROR(("%s: Mismatched params, return\n", __FUNCTION__));
+		return;
+	}
+
+	if (!val) {
+		(void) wl_schedule_task(wl, _wl_del_monitor, wl);
+		return;
+	}
+
+	if (val >= 1 && val <= 3) {
+		wl->monitor_type = val;
+	} else {
+		WL_ERROR(("monitor type %d not supported\n", val));
+		ASSERT(0);
+	}
+
+	wlif = wl_alloc_if(wl, WL_IFTYPE_MON, wl->pub->unit, NULL);
+	if (!wlif) {
+		WL_ERROR(("wl%d: %s: alloc wlif failed\n", wl->pub->unit, __FUNCTION__));
+		return;
+	}
+
+	if (wl->monitor_type == 1)
+		devname = "prism";
+	else
+		devname = "radiotap";
+	sprintf(wlif->name, "%s%d", devname, wl->pub->unit);
+
+	if (wl_schedule_task(wl, _wl_add_monitor_if, wlif)) {
+		MFREE(wl->osh, wlif, sizeof(wl_if_t));
+		return;
+	}
+}
+
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15)
+const char *
+print_tainted()
+{
+	return "";
+}
+#endif 
+
+struct net_device *
+wl_netdev_get(wl_info_t *wl)
+{
+	return wl->dev;
+}
+
+int
+wl_set_pktlen(osl_t *osh, void *p, int len)
+{
+	PKTSETLEN(osh, p, len);
+	return len;
+}
+
+void *
+wl_get_pktbuffer(osl_t *osh, int len)
+{
+	return (PKTGET(osh, len, FALSE));
+}
+
+uint
+wl_buf_to_pktcopy(osl_t *osh, void *p, uchar *buf, int len, uint offset)
+{
+	if (PKTLEN(osh, p) < len + offset)
+		return 0;
+	bcopy(buf, (char *)PKTDATA(osh, p) + offset, len);
+	return len;
+}
+
+#if defined(WL_CONFIG_RFKILL)     
+
+static int
+wl_set_radio_block(void *data, bool blocked)
+{
+	wl_info_t *wl = data;
+	uint32 radioval;
+
+	WL_TRACE(("%s: kernel set blocked = %d\n", __FUNCTION__, blocked));
+
+	radioval = WL_RADIO_SW_DISABLE << 16 | blocked;
+
+	WL_LOCK(wl);
+
+	if (wlc_set(wl->wlc, WLC_SET_RADIO, radioval) < 0) {
+		WL_ERROR(("%s: SET_RADIO failed\n", __FUNCTION__));
+		return 1;
+	}
+
+	WL_UNLOCK(wl);
+
+	return 0;
+}
+
+static const struct rfkill_ops bcmwl_rfkill_ops = {
+	.set_block = wl_set_radio_block
+};
+
+static int
+wl_init_rfkill(wl_info_t *wl)
+{
+	int status;
+
+	snprintf(wl->wl_rfkill.rfkill_name, sizeof(wl->wl_rfkill.rfkill_name),
+	"brcmwl-%d", wl->pub->unit);
+
+	wl->wl_rfkill.rfkill = rfkill_alloc(wl->wl_rfkill.rfkill_name, &wl->dev->dev,
+	RFKILL_TYPE_WLAN, &bcmwl_rfkill_ops, wl);
+
+	if (!wl->wl_rfkill.rfkill) {
+		WL_ERROR(("%s: RFKILL: Failed to allocate rfkill\n", __FUNCTION__));
+		return -ENOMEM;
+	}
+
+	if (wlc_get(wl->wlc, WLC_GET_RADIO, &status) < 0) {
+		WL_ERROR(("%s: WLC_GET_RADIO failed\n", __FUNCTION__));
+		return 1;
+	}
+
+	rfkill_init_sw_state(wl->wl_rfkill.rfkill, status);
+
+	if (rfkill_register(wl->wl_rfkill.rfkill)) {
+		WL_ERROR(("%s: rfkill_register failed! \n", __FUNCTION__));
+		rfkill_destroy(wl->wl_rfkill.rfkill);
+		return 2;
+	}
+
+	WL_ERROR(("%s: rfkill registered\n", __FUNCTION__));
+	wl->wl_rfkill.registered = TRUE;
+	return 0;
+}
+
+static void
+wl_uninit_rfkill(wl_info_t *wl)
+{
+	if (wl->wl_rfkill.registered) {
+		rfkill_unregister(wl->wl_rfkill.rfkill);
+		rfkill_destroy(wl->wl_rfkill.rfkill);
+		wl->wl_rfkill.registered = FALSE;
+		wl->wl_rfkill.rfkill = NULL;
+	}
+}
+
+static void
+wl_report_radio_state(wl_info_t *wl)
+{
+	WL_TRACE(("%s: report radio state %d\n", __FUNCTION__, wl->last_phyind));
+
+	rfkill_set_hw_state(wl->wl_rfkill.rfkill, wl->last_phyind != 0);
+}
+
+#endif 
+
+static int
+wl_linux_watchdog(void *ctx)
+{
+	wl_info_t *wl = (wl_info_t *) ctx;
+	struct net_device_stats *stats = NULL;
+	uint id;
+	wl_if_t *wlif;
+	wlc_if_stats_t wlcif_stats;
+#ifdef USE_IW
+	struct iw_statistics *wstats = NULL;
+	int phy_noise;
+#endif
+	if (wl == NULL)
+		return -1;
+
+	if (wl->if_list) {
+		for (wlif = wl->if_list; wlif != NULL; wlif = wlif->next) {
+			memset(&wlcif_stats, 0, sizeof(wlc_if_stats_t));
+			wlc_wlcif_stats_get(wl->wlc, wlif->wlcif, &wlcif_stats);
+
+			if (wl->pub->up) {
+				ASSERT(wlif->stats_id < 2);
+
+				id = 1 - wlif->stats_id;
+				stats = &wlif->stats_watchdog[id];
+				if (stats) {
+					stats->rx_packets = WLCNTVAL(wlcif_stats.rxframe);
+					stats->tx_packets = WLCNTVAL(wlcif_stats.txframe);
+					stats->rx_bytes = WLCNTVAL(wlcif_stats.rxbyte);
+					stats->tx_bytes = WLCNTVAL(wlcif_stats.txbyte);
+					stats->rx_errors = WLCNTVAL(wlcif_stats.rxerror);
+					stats->tx_errors = WLCNTVAL(wlcif_stats.txerror);
+					stats->collisions = 0;
+					stats->rx_length_errors = 0;
+
+					stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
+					stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc);
+					stats->rx_frame_errors = 0;
+					stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
+					stats->rx_missed_errors = 0;
+					stats->tx_fifo_errors = 0;
+				}
+
+#ifdef USE_IW
+				wstats = &wlif->wstats_watchdog[id];
+				if (wstats) {
+#if WIRELESS_EXT > 11
+					wstats->discard.nwid = 0;
+					wstats->discard.code = WLCNTVAL(wl->pub->_cnt->rxundec);
+					wstats->discard.fragment = WLCNTVAL(wlcif_stats.rxfragerr);
+					wstats->discard.retries = WLCNTVAL(wlcif_stats.txfail);
+					wstats->discard.misc = WLCNTVAL(wl->pub->_cnt->rxrunt) +
+						WLCNTVAL(wl->pub->_cnt->rxgiant);
+					wstats->miss.beacon = 0;
+#endif 
+				}
+#endif 
+
+				wlif->stats_id = id;
+			}
+#ifdef USE_IW
+			if (!wlc_get(wl->wlc, WLC_GET_PHY_NOISE, &phy_noise))
+				wlif->phy_noise = phy_noise;
+#endif 
+
+		}
+	}
+
+	return 0;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+static int
+wl_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+{
+	wl_info_t * wl = (wl_info_t *)data;
+#else
+static ssize_t
+wl_proc_read(struct file *filp, char __user *buffer, size_t length, loff_t *offp)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0))
+	wl_info_t * wl = PDE_DATA(file_inode(filp));
+#else
+	wl_info_t * wl = pde_data(file_inode(filp));
+#endif
+#endif
+	int bcmerror, len;
+	int to_user = 0;
+	char tmp[8];
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+	if (offset > 0) {
+		*eof = 1;
+		return 0;
+	}
+#else
+	if (*offp > 0) { 
+		return 0; 
+	}
+#endif
+
+	WL_LOCK(wl);
+	bcmerror = wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL);
+	WL_UNLOCK(wl);
+
+	if (bcmerror != BCME_OK) {
+		WL_ERROR(("%s: GET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
+		return -EIO;
+	}
+
+	len = snprintf(tmp, ARRAY_SIZE(tmp), "%d\n", to_user);
+	tmp[ARRAY_SIZE(tmp) - 1] = '\0';
+	if ((len < 0) || (len >= ARRAY_SIZE(tmp))) {
+		WL_ERROR(("%s: tmp array not big enough %d > %zu", __FUNCTION__, len, ARRAY_SIZE(tmp)));
+		return -ERANGE;
+	}
+	if (length < len) {
+		WL_ERROR(( "%s: user buffer is too small (%d < %d)", __FUNCTION__, (int)length, len));
+		return -EMSGSIZE;
+	}
+	if (copy_to_user(buffer, tmp, len) != 0) {
+		WL_ERROR(( "%s: unable to copy data!", __FUNCTION__));
+		return -EFAULT;
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+	*offp += len;
+#endif
+
+	return len;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+static int
+wl_proc_write(struct file *filp, const char *buff, unsigned long length, void *data)
+{
+	wl_info_t * wl = (wl_info_t *)data;
+#else
+static ssize_t
+wl_proc_write(struct file *filp, const char __user *buff, size_t length, loff_t *offp)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0))
+	wl_info_t * wl = PDE_DATA(file_inode(filp));
+#else
+	wl_info_t * wl = pde_data(file_inode(filp));
+#endif
+#endif
+	int from_user = 0;
+	int bcmerror;
+
+	if (length == 0 || length > 2) {
+
+		WL_ERROR(("%s: Invalid data length\n", __FUNCTION__));
+		return -EIO;
+	}
+	if (copy_from_user(&from_user, buff, 1)) {
+		WL_ERROR(("%s: copy from user failed\n", __FUNCTION__));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+		return -EIO;
+#else
+		return -EFAULT;
+#endif
+	}
+
+	if (from_user >= 0x30)
+		from_user -= 0x30;
+
+	WL_LOCK(wl);
+	bcmerror = wlc_ioctl(wl->wlc, WLC_SET_MONITOR, &from_user, sizeof(int), NULL);
+	WL_UNLOCK(wl);
+
+	if (bcmerror != BCME_OK) {
+		WL_ERROR(("%s: SET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
+		return -EIO;
+	}
+	return length;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
+static const struct file_operations wl_fops = {
+	.owner	= THIS_MODULE,
+	.read	= wl_proc_read,
+	.write	= wl_proc_write,
+#else
+static const struct proc_ops wl_fops = {
+	.proc_read	= wl_proc_read,
+	.proc_write	= wl_proc_write,
+#endif
+};
+#endif
+
+static int
+wl_reg_proc_entry(wl_info_t *wl)
+{
+	char tmp[32];
+	sprintf(tmp, "%s%d", HYBRID_PROC, wl->pub->unit);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+	if ((wl->proc_entry = create_proc_entry(tmp, 0644, NULL)) == NULL) {
+		WL_ERROR(("%s: create_proc_entry %s failed\n", __FUNCTION__, tmp));
+#else
+	if ((wl->proc_entry = proc_create_data(tmp, 0644, NULL, &wl_fops, wl)) == NULL) {
+		WL_ERROR(("%s: proc_create_data %s failed\n", __FUNCTION__, tmp));
+#endif
+		ASSERT(0);
+		return -1;
+	}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+	wl->proc_entry->read_proc = wl_proc_read;
+	wl->proc_entry->write_proc = wl_proc_write;
+	wl->proc_entry->data = wl;
+#endif
+	return 0;
+}
+uint32 wl_pcie_bar1(struct wl_info *wl, uchar** addr)
+{
+	*addr = wl->bar1_addr;
+	return (wl->bar1_size);
+}
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_linux.h
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_linux.h	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wl_linux.h	(revision 5)
@@ -0,0 +1,198 @@
+/*
+ * wl_linux.c exported functions and definitions
+ *
+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: wl_linux.h 369548 2012-11-19 09:01:01Z $
+ */
+
+#ifndef _wl_linux_h_
+#define _wl_linux_h_
+
+#include <wlc_types.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
+#include <wlc_pub.h>
+#endif
+
+typedef struct wl_timer {
+	struct timer_list 	timer;
+	struct wl_info 		*wl;
+	void 				(*fn)(void *);
+	void				*arg; 
+	uint 				ms;
+	bool 				periodic;
+	bool 				set;
+	struct wl_timer 	*next;
+#ifdef BCMDBG
+	char* 				name; 
+	uint32				ticks;	
+#endif
+} wl_timer_t;
+
+typedef struct wl_task {
+	struct work_struct work;
+	void *context;
+} wl_task_t;
+
+#define WL_IFTYPE_BSS	1 
+#define WL_IFTYPE_WDS	2 
+#define WL_IFTYPE_MON	3 
+
+struct wl_if {
+#ifdef USE_IW
+	wl_iw_t		iw;		
+#endif 
+	struct wl_if *next;
+	struct wl_info *wl;		
+	struct net_device *dev;		
+	struct wlc_if *wlcif;		
+	uint subunit;			
+	bool dev_registed;		
+	int  if_type;			
+	char name[IFNAMSIZ];		
+	struct net_device_stats stats;  
+	uint    stats_id;               
+	struct net_device_stats stats_watchdog[2]; 
+
+#ifdef USE_IW
+	struct iw_statistics wstats_watchdog[2];
+	struct iw_statistics wstats;
+	int             phy_noise;
+#endif 
+};
+
+struct rfkill_stuff {
+	struct rfkill *rfkill;
+	char rfkill_name[32];
+	char registered;
+};
+
+struct wl_info {
+	uint		unit;		
+	wlc_pub_t	*pub;		
+	void		*wlc;		
+	osl_t		*osh;		
+	struct net_device *dev;		
+
+	struct semaphore sem;		
+	spinlock_t	lock;		
+	spinlock_t	isr_lock;	
+
+	uint		bcm_bustype;	
+	bool		piomode;	
+	void *regsva;			
+	wl_if_t *if_list;		
+	atomic_t callbacks;		
+	struct wl_timer *timers;	
+	struct tasklet_struct tasklet;	
+	struct tasklet_struct tx_tasklet; 
+
+#if 0 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+	struct napi_struct napi;
+#endif 
+
+	struct net_device *monitor_dev;	
+	uint		monitor_type;	
+	bool		resched;	
+	uint32		pci_psstate[16];	
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+#define NUM_GROUP_KEYS 4
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+	struct lib80211_crypto_ops *tkipmodops;
+#else
+	struct ieee80211_crypto_ops *tkipmodops;	
+#endif
+	struct ieee80211_tkip_data  *tkip_ucast_data;
+	struct ieee80211_tkip_data  *tkip_bcast_data[NUM_GROUP_KEYS];
+#endif 
+
+	bool		txq_dispatched;	
+	spinlock_t	txq_lock;	
+	struct sk_buff	*txq_head;	
+	struct sk_buff	*txq_tail;	
+	int		txq_cnt;	
+
+	wl_task_t	txq_task;	
+	wl_task_t	multicast_task;	
+
+	wl_task_t	wl_dpc_task;	
+	bool		all_dispatch_mode;
+
+#if defined(WL_CONFIG_RFKILL)
+	struct rfkill_stuff wl_rfkill;
+	mbool last_phyind;
+#endif 
+
+	uint processed;		
+	struct proc_dir_entry *proc_entry;	
+	uchar* bar1_addr;
+	uint32 bar1_size;
+};
+
+#define HYBRID_PROC   "brcm_monitor"
+
+#if defined(WL_ALL_PASSIVE_ON)
+#define WL_ALL_PASSIVE_ENAB(wl)	1
+#else
+#define WL_ALL_PASSIVE_ENAB(wl)	(!(wl)->all_dispatch_mode)
+#endif 
+
+#define WL_LOCK(wl) \
+do { \
+	if (WL_ALL_PASSIVE_ENAB(wl)) \
+		down(&(wl)->sem); \
+	else \
+		spin_lock_bh(&(wl)->lock); \
+} while (0)
+
+#define WL_UNLOCK(wl) \
+do { \
+	if (WL_ALL_PASSIVE_ENAB(wl)) \
+		up(&(wl)->sem); \
+	else \
+		spin_unlock_bh(&(wl)->lock); \
+} while (0)
+
+#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags);} while (0)
+#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags);} while (0)
+
+#define INT_LOCK(wl, flags)	spin_lock_irqsave(&(wl)->isr_lock, flags)
+#define INT_UNLOCK(wl, flags)	spin_unlock_irqrestore(&(wl)->isr_lock, flags)
+
+typedef struct wl_info wl_info_t;
+
+#ifndef PCI_D0
+#define PCI_D0		0
+#endif
+
+#ifndef PCI_D3hot
+#define PCI_D3hot	3
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+extern irqreturn_t wl_isr(int irq, void *dev_id);
+#else
+extern irqreturn_t wl_isr(int irq, void *dev_id, struct pt_regs *ptregs);
+#endif
+
+extern int __devinit wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+extern void wl_free(wl_info_t *wl);
+extern int  wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
+extern int  wlc_ioctl_internal(struct net_device *dev, int cmd, void *buf, int len);
+#endif
+extern struct net_device * wl_netdev_get(wl_info_t *wl);
+
+#endif 
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wlc_pub.h
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wlc_pub.h	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys/wlc_pub.h	(revision 5)
@@ -0,0 +1,930 @@
+/*
+ * Common (OS-independent) definitions for
+ * Broadcom 802.11abg Networking Device Driver
+ *
+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: wlc_pub.h 458427 2014-02-26 23:12:38Z $
+ */
+
+#ifndef _wlc_pub_h_
+#define _wlc_pub_h_
+
+#include <wlc_types.h>
+#include <wlc_utils.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
+#include <siutils.h>
+#endif
+#include "proto/802.11.h"
+#include "proto/bcmevent.h"
+
+#define	MAX_TIMERS	(34 + WLC_MAXMFPS + WLC_MAXDLS_TIMERS + (2 * WLC_MAXDPT))
+
+#define	WLC_NUMRATES	16	
+#define	MAXMULTILIST	32	
+#define	D11_PHY_HDR_LEN	6	
+
+#define	PHY_TYPE_A	0	
+#define	PHY_TYPE_G	2	
+#define	PHY_TYPE_N	4	
+#define	PHY_TYPE_LP	5	
+#define	PHY_TYPE_SSN	6	
+#define	PHY_TYPE_HT	7	
+#define	PHY_TYPE_LCN	8	
+#define	PHY_TYPE_LCNXN	9	
+
+#define WLC_10_MHZ	10	
+#define WLC_20_MHZ	20	
+#define WLC_40_MHZ	40	
+#define WLC_80_MHZ	80	
+#define WLC_160_MHZ	160	
+
+#define CHSPEC_WLC_BW(chanspec)(CHSPEC_IS160(chanspec) ? WLC_160_MHZ : \
+				CHSPEC_IS80(chanspec) ? WLC_80_MHZ : \
+				CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \
+				CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \
+							WLC_10_MHZ)
+
+#define	WLC_RSSI_MINVAL		-200	
+#define	WLC_RSSI_NO_SIGNAL	-91	
+#define	WLC_RSSI_VERY_LOW	-80	
+#define	WLC_RSSI_LOW		-70	
+#define	WLC_RSSI_GOOD		-68	
+#define	WLC_RSSI_VERY_GOOD	-58	
+#define	WLC_RSSI_EXCELLENT	-57	
+
+#define	PREFSZ			160
+#define WLPREFHDRS(h, sz)	OSL_PREF_RANGE_ST((h), (sz))
+
+struct wlc_info;
+struct wlc_hw_info;
+struct wlc_bsscfg;
+struct wlc_if;
+
+typedef struct wlc_tunables {
+	int ntxd;	
+	int nrxd;	
+	int rxbufsz;			
+	int nrxbufpost;			
+	int maxscb;			
+	int ampdunummpdu2streams;	
+	int ampdunummpdu3streams;	
+	int maxpktcb;			
+	int maxdpt;			
+	int maxucodebss;		
+	int maxucodebss4;		
+	int maxbss;			
+	int datahiwat;			
+	int ampdudatahiwat;		
+	int rxbnd;			
+	int txsbnd;			
+	int pktcbnd;			
+	int dngl_mem_restrict_rxdma;	
+	int rpctxbufpost;
+	int pkt_maxsegs;
+	int maxscbcubbies;		
+	int maxbsscfgcubbies;		
+	int max_notif_servers;		
+	int max_notif_clients;		
+	int max_mempools;		
+	int maxtdls;			
+	int amsdu_resize_buflen;	
+	int ampdu_pktq_size;		
+	int ampdu_pktq_fav_size;	
+	int ntxd_large;	
+	int nrxd_large;	
+	int wlfcfifocreditac0;		
+	int wlfcfifocreditac1;		
+	int wlfcfifocreditac2;		
+	int wlfcfifocreditac3;		
+	int wlfcfifocreditbcmc;		
+	int wlfcfifocreditother;	
+	int scan_settle_time;		
+	int wlfc_fifo_cr_pending_thresh_ac_bk;	
+	int wlfc_fifo_cr_pending_thresh_ac_be;	
+	int wlfc_fifo_cr_pending_thresh_ac_vi;	
+	int wlfc_fifo_cr_pending_thresh_ac_vo;	
+	int ampdunummpdu1stream;	
+} wlc_tunables_t;
+
+typedef struct wlc_rateset {
+	uint	count;			
+	uint8	rates[WLC_NUMRATES];	
+	uint8	htphy_membership;	
+	uint8	mcs[MCSSET_LEN];	
+	uint16  vht_mcsmap;		
+} wlc_rateset_t;
+
+typedef void *wlc_pkt_t;
+
+typedef struct wlc_event {
+	wl_event_msg_t	event;		
+	struct ether_addr *addr;	
+	struct wlc_if	*wlcif;		
+	void		*data;		
+	struct wlc_event *next;		
+} wlc_event_t;
+
+typedef struct wlc_bss_info
+{
+	struct ether_addr BSSID;	
+	uint16		flags;		
+	uint8		SSID_len;	
+	uint8		SSID[32];	
+	int16		RSSI;		
+	int16		SNR;		
+	uint16		beacon_period;	
+	uint16		atim_window;	
+	chanspec_t	chanspec;	
+	int8		infra;		
+	wlc_rateset_t	rateset;	
+	uint8		dtim_period;	
+	int8		phy_noise;	
+	uint16		capability;	
+	struct dot11_bcn_prb *bcn_prb;	
+	uint16		bcn_prb_len;	
+	uint8		wme_qosinfo;	
+	struct rsn_parms wpa;
+	struct rsn_parms wpa2;
+	uint16		qbss_load_aac;	
+
+	uint8		qbss_load_chan_free;	
+	uint8		mcipher;	
+	uint8		wpacfg;		
+	uint16		mdid;		
+	uint16		flags2;		
+	uint32		vht_capabilities;
+	uint16		vht_rxmcsmap;
+	uint16		vht_txmcsmap;
+} wlc_bss_info_t;
+
+#define WLC_BSS_54G             0x0001  
+#define WLC_BSS_RSSI_ON_CHANNEL 0x0002  
+#define WLC_BSS_WME             0x0004  
+#define WLC_BSS_BRCM            0x0008  
+#define WLC_BSS_WPA             0x0010  
+#define WLC_BSS_HT              0x0020  
+#define WLC_BSS_40MHZ           0x0040  
+#define WLC_BSS_WPA2            0x0080  
+#define WLC_BSS_BEACON          0x0100  
+#define WLC_BSS_40INTOL         0x0200  
+#define WLC_BSS_SGI_20          0x0400  
+#define WLC_BSS_SGI_40          0x0800  
+#define WLC_BSS_CACHE           0x2000  
+#define WLC_BSS_FBT             0x8000  
+
+#define WLC_BSS_OVERDS_FBT      0x0001  
+#define WLC_BSS_VHT             0x0002  
+#define WLC_BSS_80MHZ           0x0004  
+#define WLC_BSS_SGI_80			0x0008	
+
+#define WLC_ENOIOCTL	1 
+#define WLC_EINVAL	2 
+#define WLC_ETOOSMALL	3 
+#define WLC_ETOOBIG	4 
+#define WLC_ERANGE	5 
+#define WLC_EDOWN	6 
+#define WLC_EUP		7 
+#define WLC_ENOMEM	8 
+#define WLC_EBUSY	9 
+
+#define IOVF_BSSCFG_STA_ONLY	(1<<0)	
+#define IOVF_BSSCFG_AP_ONLY	(1<<1)	
+#define IOVF_BSS_SET_DOWN (1<<2)	
+
+#define IOVF_MFG	(1<<3)  
+#define IOVF_WHL	(1<<4)	
+#define IOVF_NTRL	(1<<5)	
+
+#define IOVF_SET_UP	(1<<6)	
+#define IOVF_SET_DOWN	(1<<7)	
+#define IOVF_SET_CLK	(1<<8)	
+#define IOVF_SET_BAND	(1<<9)	
+
+#define IOVF_GET_UP	(1<<10)	
+#define IOVF_GET_DOWN	(1<<11)	
+#define IOVF_GET_CLK	(1<<12)	
+#define IOVF_GET_BAND	(1<<13)	
+#define IOVF_OPEN_ALLOW	(1<<14)	
+
+#define IOVF_BMAC_IOVAR	(1<<15) 
+
+#define BAR0_INVALID		(1 << 0)
+#define VENDORID_INVALID	(1 << 1)
+#define NOCARD_PRESENT		(1 << 2)
+#define PHY_PLL_ERROR		(1 << 3)
+#define DEADCHIP_ERROR		(1 << 4)
+#define MACSPEND_TIMOUT		(1 << 5)
+#define MACSPEND_WOWL_TIMOUT	(1 << 6)
+#define DMATX_ERROR		(1 << 7)
+#define DMARX_ERROR		(1 << 8)
+#define DESCRIPTOR_ERROR	(1 << 9)
+#define CARD_NOT_POWERED	(1 << 10)
+
+#define WL_HEALTH_LOG(w, s)	do {} while (0)
+
+typedef int (*watchdog_fn_t)(void *handle);
+typedef int (*up_fn_t)(void *handle);
+typedef int (*down_fn_t)(void *handle);
+typedef int (*dump_fn_t)(void *handle, struct bcmstrbuf *b);
+
+typedef int (*iovar_fn_t)(void *handle, const bcm_iovar_t *vi, uint32 actionid,
+	const char *name, void *params, uint plen, void *arg, int alen,
+	int vsize, struct wlc_if *wlcif);
+
+#define WLC_IOCF_BSSCFG_STA_ONLY	(1<<0)	
+#define WLC_IOCF_BSSCFG_AP_ONLY	(1<<1)	
+
+#define WLC_IOCF_MFG	(1<<2)  
+
+#define WLC_IOCF_DRIVER_UP	(1<<3)	
+#define WLC_IOCF_DRIVER_DOWN	(1<<4)	
+#define WLC_IOCF_CORE_CLK	(1<<5)	
+#define WLC_IOCF_FIXED_BAND	(1<<6)	
+#define WLC_IOCF_OPEN_ALLOW	(1<<7)	
+
+typedef int (*wlc_ioctl_fn_t)(void *handle, int cmd, void *arg, int len, struct wlc_if *wlcif);
+
+typedef struct wlc_ioctl_cmd_s {
+	uint16 cmd;			
+	uint16 flags;			
+	int min_len;			
+} wlc_ioctl_cmd_t;
+
+typedef struct wlc_pub {
+	void		*wlc;
+	struct ether_addr	cur_etheraddr;	
+	uint		unit;			
+	uint		corerev;		
+	osl_t		*osh;			
+	si_t		*sih_obsolete;		
+	char		*vars_obsolete;		
+	uint		vars_size_obsolete;	
+	bool		up;			
+	bool		hw_off;			
+	wlc_tunables_t *tunables;		
+	bool		hw_up;			
+	bool		_piomode;		 
+	uint		_nbands;		
+	uint		now;			
+
+	bool		promisc;		
+	bool		delayed_down;		
+	bool		_ap;			
+	bool		_apsta;			
+	bool		_assoc_recreate;	
+	int		_wme;			
+	uint8		_mbss;			
+	bool		associated;		
+
+	bool            phytest_on;             
+	bool		bf_preempt_4306;	
+
+	bool		_wowl;			
+	bool		_wowl_active;		
+	bool		_ampdu_tx;		
+	bool		_ampdu_rx;		
+	bool		_amsdu_tx;		
+	bool		_cac;			
+	uint		_spect_management;	
+	uint8		_n_enab;		
+	bool		_n_reqd;		
+
+	uint8		_vht_enab;		
+
+	int8		_coex;			
+	bool		_priofc;		
+	bool		phy_bw40_capable;	
+	bool		phy_bw80_capable;	
+
+	uint32		wlfeatureflag;		
+	int			psq_pkts_total;		
+
+	uint16		txmaxpkts;		
+
+	uint32		swdecrypt;		
+
+	int 		bcmerror;		
+
+	mbool		radio_disabled;		
+	mbool		last_radio_disabled;	
+	bool		radio_active;		
+	uint16		roam_time_thresh;	
+	bool		align_wd_tbtt;		
+	uint16		boardrev;		
+	uint8		sromrev;		
+	uint32		boardflags;		
+	uint32		boardflags2;		
+
+	wl_cnt_t	*_cnt;			
+	wl_wme_cnt_t	*_wme_cnt;		
+
+	uint8		_ndis_cap;		
+	bool		_extsta;		
+	bool		_pkt_filter;		
+	bool		phy_11ncapable;		
+	bool		_fbt;			
+	pktpool_t	*pktpool;		
+	uint8		_ampdumac;	
+	bool		_wleind;
+	bool		_sup_enab;
+	uint		driverrev;		
+
+	bool		_11h;
+	bool		_11d;
+#ifdef WLCNTRY
+	bool		_autocountry;
+#endif
+	uint32		health;
+	uint8		d11tpl_phy_hdr_len; 
+	uint		wsec_max_rcmta_keys;
+	uint		max_addrma_idx;
+	uint16		m_seckindxalgo_blk;
+	uint		m_seckindxalgo_blk_sz;
+	uint16		m_coremask_blk;
+	uint16		m_coremask_blk_wowl;
+#ifdef WL_BEAMFORMING
+	bool		_txbf;
+#endif 
+
+	bool		wet_tunnel;	
+	int		_ol;			
+
+	uint16		vht_features;		
+
+	bool		_ampdu_hostreorder;
+
+	int8		_pktc;			
+	bool		_tdls_support;		
+	bool		_okc;
+	bool		_p2po;			
+	bool		_anqpo;			
+	bool		_wl_rxearlyrc;
+	bool		_tiny_pktjoin;
+	si_t		*sih;			
+	char		*vars;			
+	uint		vars_size;		
+	bool		_proxd;			
+
+	bool		_arpoe_support;
+	bool		_11u;
+
+	bool 		_lpc_algo;
+	bool		_relmcast;		
+	bool		_relmcast_support;	
+
+	bool		_l2_filter;		
+
+	uint		bcn_tmpl_len;		
+#ifdef WL_OFFLOADSTATS
+	uint32		offld_cnt_received[4];
+	uint32		offld_cnt_consumed[4];
+#endif 
+#ifdef WL_INTERRUPTSTATS
+	uint32		intr_cnt[32];
+#endif 
+
+#ifdef TCPKAOE
+	bool		_icmpoe;		
+	bool		_tcp_keepalive;		
+#endif 
+	bool _olpc;				
+} wlc_pub_t;
+
+typedef struct	wl_rxsts {
+	uint	pkterror;		
+	uint	phytype;		
+	chanspec_t chanspec;		
+	uint16	datarate;		
+	uint8	mcs;			
+	uint8	htflags;		
+	uint	antenna;		
+	uint	pktlength;		
+	uint32	mactime;		
+	uint	sq;			
+	int32	signal;			
+	int32	noise;			
+	uint	preamble;		
+	uint	encoding;		
+	uint	nfrmtype;		
+	struct wl_if *wlif;		
+	uint8	nss;			
+	uint8   coding;
+	uint16	aid;			
+	uint8	gid;			
+	uint8   bw;			
+	uint16	vhtflags;		
+	uint8	bw_nonht;		
+	uint32	ampdu_counter;		
+} wl_rxsts_t;
+
+typedef struct	wl_txsts {
+	uint	pkterror;		
+	uint	phytype;		
+	chanspec_t chanspec;		
+	uint16	datarate;		
+	uint8	mcs;			
+	uint8	htflags;		
+	uint	antenna;		
+	uint	pktlength;		
+	uint32	mactime;		
+	uint	preamble;		
+	uint	encoding;		
+	uint	nfrmtype;		
+	uint	txflags;		
+	uint	retries;		
+	struct wl_if *wlif;		
+} wl_txsts_t;
+
+typedef struct wlc_if_stats {
+
+	uint32	txframe;		
+	uint32	txbyte;			
+	uint32	txerror;		
+	uint32  txnobuf;		
+	uint32  txrunt;			
+	uint32  txfail;			
+
+	uint32	rxframe;		
+	uint32	rxbyte;			
+	uint32	rxerror;		
+	uint32	rxnobuf;		
+	uint32  rxrunt;			
+	uint32  rxfragerr;		
+
+	uint32	txretry;		
+	uint32	txretrie;		
+	uint32	txfrmsnt;		
+	uint32	txmulti;		
+	uint32	txfrag;			
+
+	uint32	rxmulti;		
+
+} wlc_if_stats_t;
+
+#define WL_RXS_CRC_ERROR		0x00000001 
+#define WL_RXS_RUNT_ERROR		0x00000002 
+#define WL_RXS_ALIGN_ERROR		0x00000004 
+#define WL_RXS_OVERSIZE_ERROR		0x00000008 
+#define WL_RXS_WEP_ICV_ERROR		0x00000010 
+#define WL_RXS_WEP_ENCRYPTED		0x00000020 
+#define WL_RXS_PLCP_SHORT		0x00000040 
+#define WL_RXS_DECRYPT_ERR		0x00000080 
+#define WL_RXS_OTHER_ERR		0x80000000 
+
+#define WL_RXS_PHY_A			0x00000000 
+#define WL_RXS_PHY_B			0x00000001 
+#define WL_RXS_PHY_G			0x00000002 
+#define WL_RXS_PHY_N			0x00000004 
+
+#define WL_RXS_ENCODING_UNKNOWN		0x00000000
+#define WL_RXS_ENCODING_DSSS_CCK	0x00000001 
+#define WL_RXS_ENCODING_OFDM		0x00000002 
+#define WL_RXS_ENCODING_HT		0x00000003 
+#define WL_RXS_ENCODING_VHT		0x00000004 
+
+#define WL_RXS_UNUSED_STUB		0x0		
+#define WL_RXS_PREAMBLE_SHORT		0x00000001	
+#define WL_RXS_PREAMBLE_LONG		0x00000002	
+#define WL_RXS_PREAMBLE_HT_MM		0x00000003	
+#define WL_RXS_PREAMBLE_HT_GF		0x00000004	
+
+#define WL_RXS_HTF_BW_MASK		0x07
+#define WL_RXS_HTF_40			0x01
+#define WL_RXS_HTF_20L			0x02
+#define WL_RXS_HTF_20U			0x04
+#define WL_RXS_HTF_SGI			0x08
+#define WL_RXS_HTF_STBC_MASK		0x30
+#define WL_RXS_HTF_STBC_SHIFT		4
+#define WL_RXS_HTF_LDPC			0x40
+
+#define WL_RXS_VHTF_STBC		0x01
+#define WL_RXS_VHTF_TXOP_PS		0x02
+#define WL_RXS_VHTF_SGI			0x04
+#define WL_RXS_VHTF_SGI_NSYM_DA		0x08
+#define WL_RXS_VHTF_LDPC_EXTRA		0x10
+#define WL_RXS_VHTF_BF			0x20
+#define WL_RXS_VHTF_DYN_BW_NONHT 0x40
+
+#define WL_RXS_VHTF_CODING_LDCP		0x01
+
+#define WL_RXS_VHT_BW_20		0
+#define WL_RXS_VHT_BW_40		1
+#define WL_RXS_VHT_BW_20L		2
+#define WL_RXS_VHT_BW_20U		3
+#define WL_RXS_VHT_BW_80		4
+#define WL_RXS_VHT_BW_40L		5
+#define WL_RXS_VHT_BW_40U		6
+#define WL_RXS_VHT_BW_20LL		7
+#define WL_RXS_VHT_BW_20LU		8
+#define WL_RXS_VHT_BW_20UL		9
+#define WL_RXS_VHT_BW_20UU		10
+
+#define WL_RXS_NFRM_AMPDU_FIRST		0x00000001 
+#define WL_RXS_NFRM_AMPDU_SUB		0x00000002 
+#define WL_RXS_NFRM_AMSDU_FIRST		0x00000004 
+#define WL_RXS_NFRM_AMSDU_SUB		0x00000008 
+#define WL_RXS_NFRM_AMPDU_NONE		0x00000100 
+
+#define WL_TXS_TXF_FAIL		0x01	
+#define WL_TXS_TXF_CTS		0x02	
+#define WL_TXS_TXF_RTSCTS 	0x04	
+
+#define BPRESET_ENAB(pub)	(0)
+
+#define	AP_ENAB(pub)	(0)
+
+#define APSTA_ENAB(pub)	(0)
+
+#define PSTA_ENAB(pub)	(0)
+
+#if defined(PKTC_DONGLE)
+#define PKTC_ENAB(pub)	((pub)->_pktc)
+#else
+#define PKTC_ENAB(pub)	(0)
+#endif
+
+#if defined(WL_BEAMFORMING)
+	#if defined(WL_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
+		#define TXBF_ENAB(pub)		((pub)->_txbf)
+	#elif defined(WLTXBF_DISABLED)
+		#define TXBF_ENAB(pub)		(0)
+	#else
+		#define TXBF_ENAB(pub)		(1)
+	#endif
+#else
+	#define TXBF_ENAB(pub)			(0)
+#endif 
+
+#define STA_ONLY(pub)	(!AP_ENAB(pub))
+#define AP_ONLY(pub)	(AP_ENAB(pub) && !APSTA_ENAB(pub))
+
+	#define PROP_TXSTATUS_ENAB(pub)		0
+
+#define WLOFFLD_CAP(wlc)	((wlc)->ol != NULL)
+#define WLOFFLD_ENAB(pub)	((pub)->_ol)
+#define WLOFFLD_BCN_ENAB(pub)	((pub)->_ol & OL_BCN_ENAB)
+#define WLOFFLD_ARP_ENAB(pub)	((pub)->_ol & OL_ARP_ENAB)
+#define WLOFFLD_ND_ENAB(pub)	((pub)->_ol & OL_ND_ENAB)
+#define WLOFFLD_ARM_TX(pub)	((pub)->_ol & OL_ARM_TX_ENAB)
+
+#define WOWL_ENAB(pub) ((pub)->_wowl)
+#define WOWL_ACTIVE(pub) ((pub)->_wowl_active)
+
+	#define DPT_ENAB(pub) 0
+
+	#define TDLS_SUPPORT(pub)		(0)
+	#define TDLS_ENAB(pub)			(0)
+
+#define WLDLS_ENAB(pub) 0
+
+#ifdef WL_OKC
+	#if defined(WL_ENAB_RUNTIME_CHECK)
+#define OKC_ENAB(pub) ((pub)->_okc)
+	#elif defined(WL_OKC_DISABLED)
+		#define OKC_ENAB(pub)		(0)
+#else
+		#define OKC_ENAB(pub)		((pub)->_okc)
+#endif
+#else
+	#define OKC_ENAB(pub)			(0)
+#endif 
+
+#define WLBSSLOAD_ENAB(pub)	(0)
+
+	#define MCNX_ENAB(pub) 0
+
+	#define P2P_ENAB(pub) 0
+
+	#define MCHAN_ENAB(pub) (0)
+	#define MCHAN_ACTIVE(pub) (0)
+
+	#define MQUEUE_ENAB(pub) (0)
+
+	#define BTA_ENAB(pub) (0)
+
+#define PIO_ENAB(pub) 0
+
+#define CAC_ENAB(pub) ((pub)->_cac)
+
+#define COEX_ACTIVE(wlc) 0
+#define COEX_ENAB(pub) 0
+
+#define	RXIQEST_ENAB(pub)	(0)
+
+#define EDCF_ENAB(pub) (WME_ENAB(pub))
+#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub))
+
+#define PRIOFC_ENAB(pub) ((pub)->_priofc)
+
+#define MONITOR_ENAB(wlc)	((wlc)->monitor != 0)
+
+#define PROMISC_ENAB(wlc_pub)	(wlc_pub)->promisc
+
+#define WLC_SENDUP_MGMT_ENAB(cfg)	0
+
+	#define TOE_ENAB(pub)			(0)
+
+	#define ARPOE_SUPPORT(pub)		(0)
+	#define ARPOE_ENAB(pub)			(0)
+#define ICMPOE_ENAB(pub) 0
+
+	#define NWOE_ENAB(pub)			(0)
+
+#define TRAFFIC_MGMT_ENAB(pub) 0
+
+	#define L2_FILTER_ENAB(pub)		(0)
+
+#define NET_DETECT_ENAB(pub) 0
+
+#ifdef PACKET_FILTER
+#define PKT_FILTER_ENAB(pub) 	((pub)->_pkt_filter)
+#else
+#define PKT_FILTER_ENAB(pub)	0
+#endif
+
+#ifdef P2PO
+	#if defined(WL_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
+		#define P2PO_ENAB(pub) ((pub)->_p2po)
+	#elif defined(P2PO_DISABLED)
+		#define P2PO_ENAB(pub)	(0)
+	#else
+		#define P2PO_ENAB(pub)	(1)
+	#endif
+#else
+	#define P2PO_ENAB(pub) 0
+#endif 
+
+#ifdef ANQPO
+	#if defined(WL_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
+		#define ANQPO_ENAB(pub) ((pub)->_anqpo)
+	#elif defined(ANQPO_DISABLED)
+		#define ANQPO_ENAB(pub)	(0)
+	#else
+		#define ANQPO_ENAB(pub)	(1)
+	#endif
+#else
+	#define ANQPO_ENAB(pub) 0
+#endif 
+
+#define ASSOC_RECREATE_ENAB(pub) 0
+
+#define WLFBT_ENAB(pub)		(0)
+
+#if 0 && (NDISVER >= 0x0620)
+#define WIN7_AND_UP_OS(pub)	((pub)->_ndis_cap)
+#else
+#define WIN7_AND_UP_OS(pub)	0
+#endif
+
+	#define NDOE_ENAB(pub) (0)
+
+	#define WLEXTSTA_ENAB(pub)	0
+
+	#define IBSS_PEER_GROUP_KEY_ENAB(pub) (0)
+
+	#define IBSS_PEER_DISCOVERY_EVENT_ENAB(pub) (0)
+
+	#define IBSS_PEER_MGMT_ENAB(pub) (0)
+
+	#if defined(WL_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
+		#define WLEIND_ENAB(pub) ((pub)->_wleind)
+	#elif defined(WLEIND_DISABLED)
+		#define WLEIND_ENAB(pub) (0)
+	#else
+		#define WLEIND_ENAB(pub) (1)
+	#endif
+
+	#define CCX_ENAB(pub) 0
+
+	#define BCMAUTH_PSK_ENAB(pub) 0
+
+	#if defined(WL_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
+		#define SUP_ENAB(pub)	((pub)->_sup_enab)
+	#elif defined(BCMSUP_PSK_DISABLED)
+		#define SUP_ENAB(pub)	(0)
+	#else
+		#define SUP_ENAB(pub)	(1)
+	#endif
+
+#define WLC_PREC_BMP_ALL		MAXBITVAL(WLC_PREC_COUNT)
+
+#define WLC_PREC_BMP_AC_BE	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) |	\
+				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) |	\
+				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) |	\
+				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
+#define WLC_PREC_BMP_AC_BK	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) |	\
+				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) |	\
+				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) |	\
+				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
+#define WLC_PREC_BMP_AC_VI	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) |	\
+				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) |	\
+				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) |	\
+				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
+#define WLC_PREC_BMP_AC_VO	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) |	\
+				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) |	\
+				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) |	\
+				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
+
+#define WME_ENAB(pub) ((pub)->_wme != OFF)
+#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO)
+
+#ifdef WLCNTRY
+#define WLC_AUTOCOUNTRY_ENAB(wlc) ((wlc)->pub->_autocountry)
+#else
+#define WLC_AUTOCOUNTRY_ENAB(wlc) FALSE
+#endif
+
+#define WL11D_ENAB(wlc)	((wlc)->pub->_11d)
+
+#define WL11H_ENAB(wlc)	((wlc)->pub->_11h)
+
+#define WL11U_ENAB(wlc)	FALSE
+
+#define WLPROBRESP_SW_ENAB(wlc)	FALSE
+
+#define LPC_ENAB(wlc)	(FALSE)
+
+#if defined(WLOLPC)
+#define OLPC_ENAB(wlc)	((wlc)->pub->_olpc)
+#else
+#define OLPC_ENAB(wlc)	(FALSE)
+#endif 
+
+#ifdef WL_RELMCAST
+	#if defined(WL_ENAB_RUNTIME_CHECK)
+		#define RMC_SUPPORT(pub)	((pub)->_relmcast_support)
+		#define RMC_ENAB(pub)		((pub)->_relmcast)
+	#elif defined(WL_RELMCAST_DISABLED)
+		#define RMC_SUPPORT(pub)	(0)
+		#define RMC_ENAB(pub)		(0)
+	#else
+		#define RMC_SUPPORT(pub)	(1)
+		#define RMC_ENAB(pub)		((pub)->_relmcast)
+	#endif
+#else
+	#define RMC_SUPPORT(pub)		(0)
+	#define RMC_ENAB(pub)			(0)
+#endif 
+
+#define WLC_USE_COREFLAGS	0xffffffff	
+
+#define WLC_UPDATE_STATS(wlc)	1	
+#define WLCNTINCR(a)		((a)++)	
+#define WLCNTCONDINCR(c, a)	do { if (c) (a)++; } while (0)	
+#define WLCNTDECR(a)		((a)--)	
+#define WLCNTADD(a,delta)	((a) += (delta)) 
+#define WLCNTSET(a,value)	((a) = (value)) 
+#define WLCNTVAL(a)		(a)	
+
+#if !defined(RXCHAIN_PWRSAVE) && !defined(RADIO_PWRSAVE)
+#define WLPWRSAVERXFADD(wlc, v)
+#define WLPWRSAVERXFINCR(wlc)
+#define WLPWRSAVETXFINCR(wlc)
+#define WLPWRSAVERXFVAL(wlc)	0
+#define WLPWRSAVETXFVAL(wlc)	0
+#endif
+
+struct wlc_dpc_info {
+	uint processed;
+};
+
+extern void *wlc_attach(void *wl, uint16 vendor, uint16 device, uint unit, bool piomode,
+	osl_t *osh, void *regsva, uint bustype, void *btparam, uint *perr);
+extern uint wlc_detach(struct wlc_info *wlc);
+extern int  wlc_up(struct wlc_info *wlc);
+extern uint wlc_down(struct wlc_info *wlc);
+
+extern int wlc_set(struct wlc_info *wlc, int cmd, int arg);
+extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg);
+extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg);
+extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg);
+extern bool wlc_chipmatch(uint16 vendor, uint16 device);
+extern void wlc_init(struct wlc_info *wlc);
+extern void wlc_reset(struct wlc_info *wlc);
+#ifdef MCAST_REGEN
+extern int32 wlc_mcast_reverse_translation(struct ether_header *eh);
+#endif 
+
+extern void wlc_intrson(struct wlc_info *wlc);
+extern uint32 wlc_intrsoff(struct wlc_info *wlc);
+extern void wlc_intrsrestore(struct wlc_info *wlc, uint32 macintmask);
+extern bool wlc_intrsupd(struct wlc_info *wlc);
+extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc);
+extern bool wlc_dpc(struct wlc_info *wlc, bool bounded, struct wlc_dpc_info *dpc);
+
+extern bool wlc_sendpkt(struct wlc_info *wlc, void *sdu, struct wlc_if *wlcif);
+extern bool wlc_send80211_specified(wlc_info_t *wlc, void *sdu, uint32 rspec, struct wlc_if *wlcif);
+extern bool wlc_send80211_raw(struct wlc_info *wlc, wlc_if_t *wlcif, void *p, uint ac);
+extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, int p_len, void *arg,
+	int len, bool set, struct wlc_if *wlcif);
+extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif);
+
+extern void wlc_statsupd(struct wlc_info *wlc);
+
+extern wlc_pub_t *wlc_pub(void *wlc);
+
+extern void tcm_sem_enter(wlc_info_t *wlc);
+extern void tcm_sem_exit(wlc_info_t *wlc);
+extern void tcm_sem_cleanup(wlc_info_t *wlc);
+
+extern int wlc_module_register(wlc_pub_t *pub, const bcm_iovar_t *iovars,
+                               const char *name, void *hdl, iovar_fn_t iovar_fn,
+                               watchdog_fn_t watchdog_fn, up_fn_t up_fn, down_fn_t down_fn);
+extern int wlc_module_unregister(wlc_pub_t *pub, const char *name, void *hdl);
+extern int wlc_module_add_ioctl_fn(wlc_pub_t *pub, void *hdl,
+                                   wlc_ioctl_fn_t ioctl_fn,
+                                   int num_cmds, const wlc_ioctl_cmd_t *ioctls);
+extern int wlc_module_remove_ioctl_fn(wlc_pub_t *pub, void *hdl);
+
+#define WLC_RPCTX_PARAMS        32
+
+extern void wlc_wlcif_stats_get(wlc_info_t *wlc, wlc_if_t *wlcif, wlc_if_stats_t *wlcif_stats);
+extern wlc_if_t *wlc_wlcif_get_by_index(wlc_info_t *wlc, uint idx);
+
+#if defined(BCMDBG)
+
+#define WLC_PERF_STATS_ISR			0x01
+#define WLC_PERF_STATS_DPC			0x02
+#define WLC_PERF_STATS_TMR_DPC		0x04
+#define WLC_PERF_STATS_PRB_REQ		0x08
+#define WLC_PERF_STATS_PRB_RESP		0x10
+#define WLC_PERF_STATS_BCN_ISR		0x20
+#define WLC_PERF_STATS_BCNS			0x40
+
+void wlc_update_perf_stats(wlc_info_t *wlc, uint32 mask);
+void wlc_update_isr_stats(wlc_info_t *wlc, uint32 macintstatus);
+#endif 
+
+#define WLC_REPLAY_CNTRS_VALUE	WPA_CAP_4_REPLAY_CNTRS
+
+#if WLC_REPLAY_CNTRS_VALUE == WPA_CAP_16_REPLAY_CNTRS
+#define PRIO2IVIDX(prio)	(prio)
+#elif WLC_REPLAY_CNTRS_VALUE == WPA_CAP_4_REPLAY_CNTRS
+#define PRIO2IVIDX(prio)	WME_PRIO2AC(prio)
+#else
+#error "Neither WPA_CAP_4_REPLAY_CNTRS nor WPA_CAP_16_REPLAY_CNTRS is used"
+#endif 
+
+#define GPIO_2_PA_CTRL_5G_0		0x4 
+
+#ifdef WL_INTERRUPTSTATS
+typedef enum {
+	nMI_MACSSPNDD = 0,	
+	nMI_BCNTPL,		
+	nMI_TBTT,		
+	nMI_BCNSUCCESS,		
+	nMI_BCNCANCLD,		
+	nMI_ATIMWINEND,		
+	nMI_PMQ,		
+	nMI_NSPECGEN_0,		
+	nMI_NSPECGEN_1,		
+	nMI_MACTXERR,		
+	nMI_NSPECGEN_3,		
+	nMI_PHYTXERR,		
+	nMI_PME,		
+	nMI_GP0,		
+	nMI_GP1,		
+	nMI_DMAINT,		
+	nMI_TXSTOP,		
+	nMI_CCA,		
+	nMI_BG_NOISE,		
+	nMI_DTIM_TBTT,		
+	nMI_PRQ,		
+	nMI_PWRUP,		
+	nMI_BT_RFACT_STUCK,	
+	nMI_BT_PRED_REQ,	
+	nMI_NOTUSED,
+	nMI_P2P,		
+	nMI_DMATX,		
+	nMI_TSSI_LIMIT,		
+	nMI_RFDISABLE,		
+	nMI_TFS,		
+	nMI_PHYCHANGED,		
+	nMI_TO			
+} intr_enum;
+
+#define WLCINC_INTRCNT(intr)	(wlc->pub->intr_cnt[(intr)]++)
+#else
+#define WLCINC_INTRCNT(intr)
+#endif 
+
+#if defined(CONFIG_WL) || defined(CONFIG_WL_MODULE)
+#define WL_RTR()	TRUE
+#else
+#define WL_RTR()	FALSE
+#endif 
+
+#endif 
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys	(revision 5)

Property changes on: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl/sys
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl	(revision 5)

Property changes on: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src/wl
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src	(revision 5)

Property changes on: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new/src
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new	(revision 5)

Property changes on: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/broadcom-wl-x86-6.30.223.271-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/create.patch.sh
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/create.patch.sh	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=6.30.223.271
+
+tar --files-from=file.list -xJvf ../broadcom-wl-x86-$VERSION.tar.xz
+mv broadcom-wl-x86-$VERSION broadcom-wl-x86-$VERSION-orig
+
+cp -rf ./broadcom-wl-x86-$VERSION-new ./broadcom-wl-x86-$VERSION
+
+diff --unified -Nr  broadcom-wl-x86-$VERSION-orig  broadcom-wl-x86-$VERSION > broadcom-wl-x86-$VERSION-x86.patch
+
+mv broadcom-wl-x86-$VERSION-x86.patch ../patches
+
+rm -rf ./broadcom-wl-x86-$VERSION
+rm -rf ./broadcom-wl-x86-$VERSION-orig

Property changes on: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/file.list
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/file.list	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch/file.list	(revision 5)
@@ -0,0 +1,8 @@
+broadcom-wl-x86-6.30.223.271/src/shared/linux_osl.c
+broadcom-wl-x86-6.30.223.271/src/wl/sys/wl_cfg80211_hybrid.c
+broadcom-wl-x86-6.30.223.271/src/wl/sys/wl_cfg80211_hybrid.h
+broadcom-wl-x86-6.30.223.271/src/wl/sys/wl_iw.c
+broadcom-wl-x86-6.30.223.271/src/wl/sys/wl_iw.h
+broadcom-wl-x86-6.30.223.271/src/wl/sys/wl_linux.c
+broadcom-wl-x86-6.30.223.271/src/wl/sys/wl_linux.h
+broadcom-wl-x86-6.30.223.271/src/wl/sys/wlc_pub.h
Index: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch
===================================================================
--- drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch	(revision 5)

Property changes on: drivers/wireless/broadcom-wl-x86/create-6.30.223.271-x86-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless/broadcom-wl-x86/patches/README
===================================================================
--- drivers/wireless/broadcom-wl-x86/patches/README	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/patches/README	(revision 5)
@@ -0,0 +1,6 @@
+
+/* begin *
+
+   TODO: Leave some comment here.
+
+ * end */
Index: drivers/wireless/broadcom-wl-x86/patches
===================================================================
--- drivers/wireless/broadcom-wl-x86/patches	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86/patches	(revision 5)

Property changes on: drivers/wireless/broadcom-wl-x86/patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless/broadcom-wl-x86
===================================================================
--- drivers/wireless/broadcom-wl-x86	(nonexistent)
+++ drivers/wireless/broadcom-wl-x86	(revision 5)

Property changes on: drivers/wireless/broadcom-wl-x86
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers/wireless
===================================================================
--- drivers/wireless	(nonexistent)
+++ drivers/wireless	(revision 5)

Property changes on: drivers/wireless
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: drivers
===================================================================
--- drivers	(nonexistent)
+++ drivers	(revision 5)

Property changes on: drivers
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: firmware/Makefile
===================================================================
--- firmware/Makefile	(nonexistent)
+++ firmware/Makefile	(revision 5)
@@ -0,0 +1,13 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+SOURCE_REQUIRES += ALL_DIRS
+
+
+include ../../../build-system/core.mk
+
+
+download_clean:
+	@true
+
+.PHONY: download_clean
Index: firmware/armbian-firmware/Makefile
===================================================================
--- firmware/armbian-firmware/Makefile	(nonexistent)
+++ firmware/armbian-firmware/Makefile	(revision 5)
@@ -0,0 +1,47 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/hal/firmware/armbian-firmware
+
+versions    = 20210505
+pkgname     = armbian-firmware
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: firmware/armbian-firmware
===================================================================
--- firmware/armbian-firmware	(nonexistent)
+++ firmware/armbian-firmware	(revision 5)

Property changes on: firmware/armbian-firmware
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: firmware/broadcom-bt-firmware/Makefile
===================================================================
--- firmware/broadcom-bt-firmware/Makefile	(nonexistent)
+++ firmware/broadcom-bt-firmware/Makefile	(revision 5)
@@ -0,0 +1,47 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/hal/firmware/broadcom-bt-firmware
+
+versions    = 12.0.1.1105.3
+pkgname     = broadcom-bt-firmware
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: firmware/broadcom-bt-firmware
===================================================================
--- firmware/broadcom-bt-firmware	(nonexistent)
+++ firmware/broadcom-bt-firmware	(revision 5)

Property changes on: firmware/broadcom-bt-firmware
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: firmware/kernel-firmware/Makefile
===================================================================
--- firmware/kernel-firmware/Makefile	(nonexistent)
+++ firmware/kernel-firmware/Makefile	(revision 5)
@@ -0,0 +1,47 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/hal/firmware/kernel-firmware
+
+versions    = 20221012
+pkgname     = kernel-firmware
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: firmware/kernel-firmware
===================================================================
--- firmware/kernel-firmware	(nonexistent)
+++ firmware/kernel-firmware	(revision 5)

Property changes on: firmware/kernel-firmware
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: firmware
===================================================================
--- firmware	(nonexistent)
+++ firmware	(revision 5)

Property changes on: firmware
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: .
===================================================================
--- .	(nonexistent)
+++ .	(revision 5)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~