--- amd64.orig/src/wl/sys/wl_linux.c	2012-05-24 10:48:28.000000000 +0400
+++ amd64/src/wl/sys/wl_linux.c	2012-10-23 05:24:43.000000000 +0400
@@ -2,15 +2,21 @@
  * Linux-specific portion of
  * Broadcom 802.11abg Networking Device Driver
  *
- * Copyright (C) 2010, Broadcom Corporation
- * All Rights Reserved.
+ * Copyright (C) 2011, Broadcom Corporation. All Rights Reserved.
  * 
- * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
- * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
- * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ * 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,v 1.524.2.40.2.15 2011-02-09 02:28:28 Exp $
+ * $Id: wl_linux.c 280943 2011-08-31 21:37:04Z $
  */
 
 #define LINUX_PORT
@@ -37,6 +43,7 @@
 #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	
 
@@ -57,7 +64,7 @@
 #include <wlioctl.h>
 #include <wlc_key.h>
 
-typedef const struct si_pub	si_t;
+typedef const struct si_pub si_t;
 
 #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"
@@ -77,10 +84,6 @@
 
 #include <wl_linux.h>
 
-#ifdef WL_THREAD
-#include <linux/kthread.h>
-#endif 
-
 #if defined(USE_CFG80211)
 #include <wl_cfg80211.h>
 #endif
@@ -90,20 +93,6 @@
 
 static int wl_monitor_start(struct sk_buff *skb, struct net_device *dev);
 
-#ifdef WL_ALL_PASSIVE
-static void wl_start_txqwork(struct wl_task *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);
-#else
-
-#endif 
-
 static int wl_reg_proc_entry(wl_info_t *wl);
 
 static int wl_linux_watchdog(void *ctx);
@@ -139,15 +128,11 @@
 	u8 rx_hdr[16], tx_hdr[16];
 };
 
-#define	WL_INFO(dev)		((wl_info_t*)(WL_DEV_IF(dev)->wl))	
+#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);
-#ifdef WL_THREAD
-static int wl_start_wlthread(struct sk_buff *skb, struct net_device *dev);
-#else
 static int BCMFASTPATH wl_start(struct sk_buff *skb, struct net_device *dev);
-#endif
 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);
@@ -155,24 +140,13 @@
 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);
-#ifdef NAPI_POLL
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
-static int wl_poll(struct napi_struct *napi, int budget);
-#else
-static int wl_poll(struct net_device *dev, int *budget);
-#endif 
-#else 
 static void wl_dpc(ulong data);
-#endif 
 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);
-#ifdef WL_THREAD
-static int wl_start_enqueue_wlthread(wl_info_t *wl, struct sk_buff *skb);
-#endif 
 #if defined(BCMDBG)
 static int wl_dump(wl_info_t *wl, struct bcmstrbuf *b);
-#endif 
+#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);
@@ -185,27 +159,13 @@
 static void wl_report_radio_state(wl_info_t *wl);
 #endif
 
-static struct pci_device_id wl_id_table[] = {
-	{ PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4313, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4315, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4328, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4329, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x432a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x432b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x432c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x432d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0xA99D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4358, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x4359, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x435a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
-	{ PCI_VENDOR_ID_BROADCOM, 0x0576, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
+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);
 
 #ifdef BCMDBG
@@ -217,15 +177,10 @@
 module_param(phymsglevel, int, 0);
 #endif 
 
-#if defined(WL_ALL_PASSIVE)
-
-#ifdef WLP2P
-static int passivemode = 1;
-module_param(passivemode, int, 1);
-#else
-static int passivemode = 0;
-module_param(passivemode, int, 0);
-#endif 
+#ifdef WL_LIMIT_TXQ
+#define WL_TXQ_THRESH	0
+static int wl_txq_thresh = WL_TXQ_THRESH;
+module_param(wl_txq_thresh, int, 0);
 #endif 
 
 static int oneonly = 0;
@@ -234,7 +189,7 @@
 static int piomode = 0;
 module_param(piomode, int, 0);
 
-static int instance_base = 0;	
+static int instance_base = 0; 
 module_param(instance_base, int, 0);
 
 #if defined(BCMDBG)
@@ -259,53 +214,69 @@
 #define BRCM_WLAN_IFNAME eth%d
 #endif
 
-static char name[IFNAMSIZ] = quote_str(BRCM_WLAN_IFNAME);
+static char intf_name[IFNAMSIZ] = quote_str(BRCM_WLAN_IFNAME);
 
-module_param_string(name, name, IFNAMSIZ, 0);
+module_param_string(intf_name, intf_name, IFNAMSIZ, 0);
 
 #define WL_RADIOTAP_BRCM_SNS	0x01
 #define WL_RADIOTAP_BRCM_MCS	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 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
 
 struct wl_radiotap_legacy {
-	struct ieee80211_radiotap_header	ieee_radiotap;
-	uint32       tsft_h;
-	uint32       tsft_l;
-	uint8        flags;
-	uint8        rate;
-	uint16       channel_freq;
-	uint16       channel_flags;
-	uint8        signal;
-	uint8        noise;
-	uint8        antenna;
-} __attribute__((__packed__));
+	struct ieee80211_radiotap_header ieee_radiotap;
+	uint32 tsft_l;
+	uint32 tsft_h;
+	uint8 flags;
+	uint8 rate;
+	uint16 channel_freq;
+	uint16 channel_flags;
+	uint8 signal;
+	uint8 noise;
+	uint8 antenna;
+} __attribute__ ((__packed__));
+
+struct wl_radiotap_ht_brcm {
+	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));
 
 struct wl_radiotap_ht {
-	struct ieee80211_radiotap_header        ieee_radiotap;
-	uint32_t				it_present_ext;
-	uint32_t	pad1;
-	uint32		tsft_h;
-	uint32		tsft_l;
-	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));
+	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));
 
 #define WL_RADIOTAP_PRESENT_LEGACY			\
 	((1 << IEEE80211_RADIOTAP_TSFT) |		\
@@ -316,7 +287,7 @@
 	 (1 << IEEE80211_RADIOTAP_FLAGS) |		\
 	 (1 << IEEE80211_RADIOTAP_ANTENNA))
 
-#define WL_RADIOTAP_PRESENT_HT				\
+#define WL_RADIOTAP_PRESENT_HT_BRCM			\
 	((1 << IEEE80211_RADIOTAP_TSFT) |		\
 	 (1 << IEEE80211_RADIOTAP_FLAGS) |		\
 	 (1 << IEEE80211_RADIOTAP_CHANNEL) |		\
@@ -326,12 +297,21 @@
 	 (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))
+
 #ifndef ARPHRD_IEEE80211_RADIOTAP
 #define ARPHRD_IEEE80211_RADIOTAP 803
 #endif
 
-#ifndef	SRCBASE
-#define	SRCBASE "."
+#ifndef SRCBASE
+#define SRCBASE "."
 #endif
 
 #if WIRELESS_EXT >= 19 || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
@@ -344,33 +324,6 @@
 	.get_drvinfo = wl_get_driver_info
 };
 #endif 
-#ifdef WL_THREAD
-static int wl_thread_dpc_wlthread(void *data)
-{
-	wl_info_t *wl = (wl_info_t *) data;
-
-	current->flags |= PF_NOFREEZE;
-
-	while (1) {
-		wait_event_interruptible_timeout
-		(wl->thread_wqh,
-			skb_queue_len(&wl->rpc_queue) ||
-			skb_queue_len(&wl->tx_queue),
-			1);
-
-		if (kthread_should_stop())
-			break;
-
-		wl_rpcq_dispatch_wlthread(wl);
-		wl_start_txqwork_wlthread(wl);
-	}
-
-	skb_queue_purge(&wl->tx_queue);
-	skb_queue_purge(&wl->rpc_queue);
-
-	return 0;
-}
-#endif 
 
 #if defined(WL_USE_NETDEV_OPS)
 
@@ -378,11 +331,7 @@
 {
 	.ndo_open = wl_open,
 	.ndo_stop = wl_close,
-#ifdef WL_THREAD
-	.ndo_start_xmit = wl_start_wlthread,
-#else
 	.ndo_start_xmit = wl_start,
-#endif
 	.ndo_get_stats = wl_get_stats,
 	.ndo_set_mac_address = wl_set_mac_address,
 	.ndo_set_multicast_list = wl_set_multicast_list,
@@ -397,40 +346,20 @@
 };
 #endif 
 
-static
-void wl_if_setup(struct net_device *dev)
+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;
-#ifdef WL_THREAD
-	dev->hard_start_xmit = wl_start_wlthread;
-#else
 	dev->hard_start_xmit = wl_start;
-#endif
 	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 NAPI_POLL
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
-	{
-		struct wl_info *wl = WL_INFO(dev);
-
-		netif_napi_add(dev, &wl->napi, wl_poll, 64);
-		napi_enable(&wl->napi);
-	}
-#else
-	dev->poll = wl_poll;
-	dev->weight = 64;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)
-	netif_poll_enable(dev);
-#endif 
-#endif  
-#endif 
 
 #ifdef USE_IW
 #if WIRELESS_EXT < 19
@@ -439,15 +368,11 @@
 #if WIRELESS_EXT > 12
 	dev->wireless_handlers = (struct iw_handler_def *) &wl_iw_handler_def;
 #endif
-#if WIRELESS_EXT >= 19 || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
-	dev->ethtool_ops = &wl_ethtool_ops;
-#endif
 #endif 
 
-#if defined(USE_CFG80211) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+#if WIRELESS_EXT >= 19 || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
 	dev->ethtool_ops = &wl_ethtool_ops;
-#endif 
-
+#endif
 }
 
 static wl_info_t *
@@ -490,22 +415,6 @@
 	wl->unit = unit;
 	atomic_set(&wl->callbacks, 0);
 
-#ifdef WL_ALL_PASSIVE
-	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;
-		wl->txq_dispatched = FALSE;
-		wl->txq_head = wl->txq_tail = NULL;
-
-		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;
-	}
-#endif  
-
 	wlif = wl_alloc_if(wl, WL_IFTYPE_BSS, unit, NULL);
 	if (!wlif) {
 		WL_ERROR(("wl%d: wl_alloc_if failed\n", unit));
@@ -551,15 +460,12 @@
 	spin_lock_init(&wl->isr_lock);
 
 	if (WL_ALL_PASSIVE_ENAB(wl)) {
-#ifdef WL_ALL_PASSIVE
-		spin_lock_init(&wl->txq_lock);
-#endif 
 		sema_init(&wl->sem, 1);
 	}
 
 	if (!(wl->wlc = wlc_attach((void *) wl, vendor, device, unit, wl->piomode,
 		osh, wl->regsva, wl->bcm_bustype, btparam, &err))) {
-		printf("%s: %s driver failed with code %d\n", dev->name, EPI_VERSION_STR, err);
+		printf("wl driver %s failed with code %d\n", EPI_VERSION_STR, err);
 		goto fail;
 	}
 	wl->pub = wlc_pub(wl->wlc);
@@ -575,24 +481,21 @@
 	wlc_iovar_setint(wl->wlc, "qtxpower", 23 * 4);
 
 #ifdef BCMDBG
-	if (macaddr != NULL) {  
-		int err;
+	if (macaddr != NULL) { 
+		int dbg_err;
 
 		WL_ERROR(("wl%d: setting MAC ADDRESS %s\n", unit, macaddr));
 		bcm_ether_atoe(macaddr, &local_ea);
 
-		err = wlc_iovar_op(wl->wlc, "cur_etheraddr", NULL, 0, &local_ea,
+		dbg_err = wlc_iovar_op(wl->wlc, "cur_etheraddr", NULL, 0, &local_ea,
 			ETHER_ADDR_LEN, IOV_SET, NULL);
-		if (err)
+		if (dbg_err)
 			WL_ERROR(("wl%d: Error setting MAC ADDRESS\n", unit));
 	}
-#endif	
+#endif 
 	bcopy(&wl->pub->cur_etheraddr, dev->dev_addr, ETHER_ADDR_LEN);
 
-#ifndef NAPI_POLL
-
 	tasklet_init(&wl->tasklet, wl_dpc, (ulong)wl);
-#endif
 
 	{
 		if (request_irq(irq, wl_isr, IRQF_SHARED, dev->name, wl)) {
@@ -621,6 +524,7 @@
 		goto fail;
 	}
 #else
+
 	if (wl->bcm_bustype == PCI_BUS) {
 		struct pci_dev *pci_dev = (struct pci_dev *)btparam;
 		if (pci_dev != NULL)
@@ -674,23 +578,11 @@
 		WL_ERROR(("wl%d: Error setting infra_mode to infrastructure\n", unit));
 	}
 
-#ifdef DEFAULT_EAPVER_AP
-
-	if (wlc_iovar_setint(wl->wlc, "sup_wpa2_eapver", -1)) {
-		WL_ERROR(("wl%d: Error setting sup_wpa2_eapver \n", unit));
-	}
-	if (wlc_iovar_setint(wl->wlc, "sup_m3sec_ok", 1)) {
-		WL_ERROR(("wl%d: Error setting sup_m3sec_ok \n", unit));
-	}
-#endif 
-#ifdef DISABLE_HT_RATE_FOR_WEP_TKIP
-
-	if (wlc_iovar_setint(wl->wlc, "ht_wsec_restrict", 0x3)) {
-		WL_ERROR(("wl%d: Error setting ht_wsec_restrict \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;
 	}
-#endif 
-
-	wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, NULL);
 
 #ifdef BCMDBG
 	wlc_dump_register(wl->pub, "wl", (dump_fn_t)wl_dump, (void *)wl);
@@ -724,22 +616,22 @@
 	uint32 val;
 
 	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));
+		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 != 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));
+			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)));
+			pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)));
 		return (-ENODEV);
 	}
 	pci_set_master(pdev);
@@ -792,7 +684,7 @@
 
 	if (!wl) {
 		WL_ERROR(("wl: wl_resume: pci_get_drvdata failed\n"));
-	        return -ENODEV;
+		return -ENODEV;
 	}
 
 	err = pci_set_power_state(pdev, PCI_D0);
@@ -852,10 +744,6 @@
 	id_table:	wl_id_table,
 	};
 
-#define	wl_read_nvram_file() do {} while (0)
-
-#define usbap_parse_nvram()	do {} while (0)
-
 static int __init
 wl_module_init(void)
 {
@@ -865,7 +753,7 @@
 	if (msglevel != 0xdeadbeef)
 		wl_msg_level = msglevel;
 	else {
-		char *var = getvar(NULL, "wl_msglevel");
+		const char *var = getvar(NULL, "wl_msglevel");
 		if (var)
 			wl_msg_level = bcm_strtoul(var, NULL, 0);
 	}
@@ -873,7 +761,7 @@
 	if (msglevel2 != 0xdeadbeef)
 		wl_msg_level2 = msglevel2;
 	else {
-		char *var = getvar(NULL, "wl_msglevel2");
+		const char *var = getvar(NULL, "wl_msglevel2");
 		if (var)
 			wl_msg_level2 = bcm_strtoul(var, NULL, 0);
 	}
@@ -884,21 +772,23 @@
 		if (phymsglevel != 0xdeadbeef)
 			phyhal_msg_level = phymsglevel;
 		else {
-			char *var = getvar(NULL, "phy_msglevel");
+			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);
 	}
-#if defined(WL_ALL_PASSIVE)
+#endif 
+#ifdef WL_LIMIT_TXQ
 	{
-		char *var = getvar(NULL, "wl_dispatch_mode");
+		char *var = getvar(NULL, "wl_txq_thresh");
 		if (var)
-			passivemode = bcm_strtoul(var, NULL, 0);
-		printf("%s: dhssivemode set to 0x%x\n", __FUNCTION__, passivemode);
+			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
 	}
 #endif 
-#endif 
 
 	if (!(error = pci_module_init(&wl_pci_driver)))
 		return (0);
@@ -933,37 +823,22 @@
 	wl_uninit_rfkill(wl);
 #endif
 
-#ifdef NAPI_POLL
-	clear_bit(__LINK_STATE_START, &wl->dev->state);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
-	napi_disable(&wl->napi);
-#elif  LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)
-	netif_poll_disable(wl->dev);
-#endif 	
-#endif 
-
 	if (wl->dev) {
 		wl_free_if(wl, WL_DEV_IF(wl->dev));
 		wl->dev = NULL;
 	}
 
-#ifndef NAPI_POLL
-
 	tasklet_kill(&wl->tasklet);
-#endif
 	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;
@@ -1011,11 +886,6 @@
 	}
 #endif 
 
-#ifdef WL_ALL_PASSIVE
-	if (WL_ALL_PASSIVE_ENAB(wl))
-		wl_txq_free(wl);
-#endif 
-
 	MFREE(osh, wl, sizeof(wl_info_t));
 
 	if (MALLOCED(osh)) {
@@ -1041,7 +911,7 @@
 
 	WL_LOCK(wl);
 	WL_APSTA_UPDN(("wl%d: (%s): wl_open() -> wl_up()\n",
-	               wl->pub->unit, wl->dev->name));
+		wl->pub->unit, wl->dev->name));
 
 	error = wl_up(wl);
 	if (!error) {
@@ -1058,8 +928,7 @@
 		return -1;
 	}
 #endif
-
-	return (error? -ENODEV: 0);
+	return (error? -ENODEV : 0);
 }
 
 static int
@@ -1073,7 +942,6 @@
 #if defined(USE_CFG80211)
 	wl_cfg80211_down(dev);
 #endif
-
 	wl = WL_INFO(dev);
 
 	WL_TRACE(("wl%d: wl_close\n", wl->pub->unit));
@@ -1125,6 +993,8 @@
 
 	if (wlif == NULL)
 		dev = wl->dev;
+	else if (!wlif->dev_registed)
+		return;
 	else
 		dev = wlif->dev;
 
@@ -1162,7 +1032,7 @@
 }
 
 static struct wl_if *
-wl_alloc_if(wl_info_t *wl, int iftype, uint subunit, struct wlc_if* wlcif)
+wl_alloc_if(wl_info_t *wl, int iftype, uint subunit, struct wlc_if *wlcif)
 {
 	struct net_device *dev;
 	wl_if_t *wlif;
@@ -1171,7 +1041,7 @@
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29))
 	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)));
+			(wl->pub)?wl->pub->unit:subunit, MALLOCED(wl->osh)));
 		return NULL;
 	}
 	bzero(wlif, sizeof(wl_if_t));
@@ -1181,20 +1051,23 @@
 	if (!(dev = MALLOC(wl->osh, sizeof(struct net_device)))) {
 		MFREE(wl->osh, wlif, 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)));
+			(wl->pub)?wl->pub->unit:subunit, MALLOCED(wl->osh)));
 		return NULL;
 	}
 	bzero(dev, sizeof(struct net_device));
 	ether_setup(dev);
-	strncpy(dev->name, name, IFNAMSIZ);
+
+	strncpy(dev->name, intf_name, IFNAMSIZ-1);
+	dev->name[IFNAMSIZ-1] = '\0';
+
 #else
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
 
-	dev = alloc_netdev(sizeof(wl_if_t), name, ether_setup);
+	dev = alloc_netdev(sizeof(wl_if_t), intf_name, ether_setup);
 	wlif = netdev_priv(dev);
 	if (!dev) {
 #else
-	dev = alloc_netdev(0, name, ether_setup);
+	dev = alloc_netdev(0, intf_name, ether_setup);
 	if (!dev) {
 		MFREE(wl->osh, wlif, sizeof(wl_if_t));
 #endif 
@@ -1237,8 +1110,7 @@
 	}
 
 #if defined(USE_CFG80211)
-	if (wlif->if_type != WL_IFTYPE_MON)
-		wl_cfg80211_detach(wlif->dev);
+	wl_cfg80211_detach(wlif->dev);
 #endif
 
 	p = wl->if_list;
@@ -1258,8 +1130,8 @@
 		free_netdev(wlif->dev);
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
 		return;
-#endif	
-#endif	
+#endif 
+#endif 
 	}
 	MFREE(wl->osh, wlif, sizeof(wl_if_t));
 }
@@ -1353,10 +1225,6 @@
 		}
 	}
 
-#ifdef NAPI_POLL
-	set_bit(__LINK_STATE_START, &wl->dev->state);
-#endif 
-
 	return (error);
 }
 
@@ -1386,16 +1254,6 @@
 
 	WL_UNLOCK(wl);
 
-#ifdef WL_ALL_PASSIVE
-	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
-#endif 
 	{
 
 		SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
@@ -1430,8 +1288,9 @@
 {
 	wl_info_t *wl = WL_INFO(dev);
 	bzero(info, sizeof(struct ethtool_drvinfo));
-	sprintf(info->driver, "wl%d", wl->pub->unit);
-	strcpy(info->version, EPI_VERSION_STR);
+	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
@@ -1533,12 +1392,6 @@
 
 	WL_TRACE(("wl%d: wl_ioctl: cmd 0x%x\n", wl->pub->unit, cmd));
 
-#ifdef CONFIG_PREEMPT
-	if (preempt_count())
-		WL_ERROR(("wl%d: wl_ioctl: cmd = 0x%x, preempt_count=%d\n",
-			wl->pub->unit, cmd, preempt_count()));
-#endif
-
 #ifdef USE_IW
 
 	if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
@@ -1731,17 +1584,6 @@
 {
 	if (!WL_ALL_PASSIVE_ENAB((wl_info_t *)WL_INFO(dev)))
 		_wl_set_multicast_list(dev);
-#ifdef WL_ALL_PASSIVE
-	else {
-		wl_info_t *wl = WL_INFO(dev);
-		wl->multicast_task.context = dev;
-
-		if (schedule_work(&wl->multicast_task.work)) {
-
-			atomic_inc(&wl->callbacks);
-		}
-	}
-#endif 
 }
 
 static void
@@ -1750,7 +1592,7 @@
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
 	struct dev_mc_list *mclist;
 #else
-	struct netdev_hw_addr   *ha;
+	struct netdev_hw_addr *ha;
 	int num;
 #endif
 	wl_info_t *wl;
@@ -1791,7 +1633,7 @@
 				i = 0;
 				break;
 			}
-			bcopy(ha->addr,  &maclist->ea[i++], ETHER_ADDR_LEN);
+			bcopy(ha->addr, &maclist->ea[i++], ETHER_ADDR_LEN);
 		}
 #endif 
 		maclist->count = i;
@@ -1830,24 +1672,7 @@
 		if (wantdpc) {
 
 			ASSERT(wl->resched == FALSE);
-#ifdef NAPI_POLL
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
-			napi_schedule(&wl->napi);
-#else
-			netif_rx_schedule(wl->dev);
-#endif 
-#else 
-#ifdef WL_ALL_PASSIVE
-			if (WL_ALL_PASSIVE_ENAB(wl)) {
-				if (schedule_work(&wl->wl_dpc_task.work))
-					atomic_inc(&wl->callbacks);
-				else
-					ASSERT(0);
-			} else
-#endif 
 			tasklet_schedule(&wl->tasklet);
-#endif 
 		}
 	}
 
@@ -1856,37 +1681,18 @@
 	return IRQ_RETVAL(ours);
 }
 
-#ifdef NAPI_POLL
-static int BCMFASTPATH
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
-wl_poll(struct napi_struct *napi, int budget)
-#else
-wl_poll(struct net_device *dev, int *budget)
-#endif 
-#else 
 static void BCMFASTPATH
 wl_dpc(ulong data)
-#endif 
 {
 	wl_info_t *wl;
 
-#ifdef NAPI_POLL
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
-	wl = (wl_info_t *)container_of(napi, wl_info_t, napi);
-	wl->pub->tunables->rxbnd = min(RXBND, budget);
-#else
-	wl = WL_INFO(dev);
-	wl->pub->tunables->rxbnd = min(RXBND, *budget);
-	ASSERT(wl->pub->tunables->rxbnd <= dev->quota);
-#endif 	
-#else 
-
 	wl = (wl_info_t *)data;
 
 	WL_LOCK(wl);
-#endif 
 
 	if (wl->pub->up) {
+		wlc_dpc_info_t dpci = {0};
+
 		if (wl->resched) {
 			unsigned long flags = 0;
 			INT_LOCK(wl, flags);
@@ -1894,98 +1700,26 @@
 			INT_UNLOCK(wl, flags);
 		}
 
-		wl->resched = wlc_dpc(wl->wlc, TRUE);
+		wl->resched = wlc_dpc(wl->wlc, TRUE, &dpci);
+
+		wl->processed = dpci.processed;
 	}
 
 	if (!wl->pub->up) {
-#ifdef WL_ALL_PASSIVE
-
-		if ((WL_ALL_PASSIVE_ENAB(wl))) {
-			atomic_dec(&wl->callbacks);
-		}
-#endif 
 		goto done;
 	}
 
-#ifndef NAPI_POLL
-#ifdef WL_ALL_PASSIVE
-	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);
-	}
-#else 
 	if (wl->resched)
 		tasklet_schedule(&wl->tasklet);
 	else {
 
 		wl_intrson(wl);
 	}
-#endif 
 
 done:
 	WL_UNLOCK(wl);
 	return;
-#else 
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
-	WL_TRACE(("wl%d: wl_poll: rxbnd %d budget %d processed %d\n",
-		wl->pub->unit, wl->pub->rxbnd, budget, wl->pub->processed));
-
-	ASSERT(wl->pub->processed <= wl->pub->tunables->rxbnd);
-
-	if (!wl->resched) {
-		napi_complete(&wl->napi);
-
-		wl_intrson(wl);
-	}
-	return wl->pub->processed;
-done:
-	return 0;
-
-#else 
-	WL_TRACE(("wl%d: wl_poll: rxbnd %d quota %d budget %d processed %d\n",
-	          wl->pub->unit, wl->pub->rxbnd, dev->quota,
-	          *budget, wl->pub->processed));
-
-	ASSERT(wl->pub->processed <= wl->pub->tunables->rxbnd);
-
-	*budget -= wl->pub->processed;
-	dev->quota -= wl->pub->processed;
-
-	if (wl->resched)
-
-		return 1;
-
-	netif_rx_complete(dev);
-
-	wl_intrson(wl);
-done:
-	return 0;
-#endif 
-#endif 
-}
-
-#if defined(WL_ALL_PASSIVE)
-static void
-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;
 }
-#endif 
 
 static inline int32
 wl_ctf_forward(wl_info_t *wl, struct sk_buff *skb)
@@ -2018,7 +1752,7 @@
 	}
 
 	skb->protocol = eth_type_trans(skb, skb->dev);
-	if (!ISALIGNED((uintptr)skb->data, 4)) {
+	if (!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));
@@ -2027,17 +1761,13 @@
 		}
 		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((uintptr)skb->data, 4));
+		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));
 
-#ifdef NAPI_POLL
-	netif_receive_skb(skb);
-#else 
 	netif_rx(skb);
-#endif 
 }
 
 void
@@ -2057,8 +1787,8 @@
 	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));
+		wl->dev->name, wl->dev, (uint)netif_queue_stopped(wl->dev),
+		atomic_read(&wl->callbacks), MALLOCED(wl->osh));
 
 	p = wl->if_list;
 	if (p)
@@ -2076,7 +1806,7 @@
 
 	return 0;
 }
-#endif	
+#endif 
 
 static void
 wl_link_up(wl_info_t *wl, char *ifname)
@@ -2100,7 +1830,6 @@
 #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:
@@ -2135,7 +1864,6 @@
 {
 }
 
-#ifndef WL_THREAD
 static int BCMFASTPATH
 wl_start(struct sk_buff *skb, struct net_device *dev)
 {
@@ -2150,124 +1878,9 @@
 
 	if (!WL_ALL_PASSIVE_ENAB(wl))
 		return wl_start_int(wl, wlif, skb);
-#ifdef WL_ALL_PASSIVE
-	else {
-		skb->prev = NULL;
-
-		TXQ_LOCK(wl);
-		if (wl->txq_head == NULL)
-			wl->txq_head = skb;
-		else {
-			wl->txq_tail->prev = skb;
-		}
-		wl->txq_tail = skb;
-
-		if (wl->txq_dispatched == FALSE) {
-			wl->txq_dispatched = TRUE;
-
-			if (schedule_work(&wl->txq_task.work)) {
-				atomic_inc(&wl->callbacks);
-			} else {
-				WL_ERROR(("wl%d: wl_start/schedule_work failed\n", wl->pub->unit));
-				wl->txq_dispatched = FALSE;
-			}
-		}
-
-		TXQ_UNLOCK(wl);
-	}
-#endif 
 
 	return (0);
 }
-#endif 
-
-#ifdef WL_ALL_PASSIVE
-static void
-wl_start_txqwork(struct wl_task *task)
-{
-	wl_info_t *wl = (wl_info_t *)task->context;
-	struct sk_buff *skb;
-	uint count = 0;
-
-	WL_TRACE(("wl%d: wl_start_txqwork\n", wl->pub->unit));
-
-	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;
-		TXQ_UNLOCK(wl);
-
-		wl_start_int(wl, WL_DEV_IF(skb->dev), skb);
-
-		if (++count >= 10)
-			break;
-
-		TXQ_LOCK(wl);
-	}
-
-	if (count >= 10) {
-		if (!schedule_work(&wl->txq_task.work)) {
-			WL_ERROR(("wl%d: wl_start/schedule_work failed\n", wl->pub->unit));
-			atomic_dec(&wl->callbacks);
-		}
-	} else {
-		wl->txq_dispatched = FALSE;
-		TXQ_UNLOCK(wl);
-		atomic_dec(&wl->callbacks);
-	}
-
-	return;
-}
-
-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;
-		PKTFREE(wl->osh, skb, TRUE);
-	}
-
-	wl->txq_tail = NULL;
-}
-#endif 
-
-#ifdef WL_ALL_PASSIVE
-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);
-}
-#endif 
 
 static void
 wl_timer(ulong data)
@@ -2276,10 +1889,6 @@
 
 	if (!WL_ALL_PASSIVE_ENAB(t->wl))
 		_wl_timer(t);
-#ifdef WL_ALL_PASSIVE
-	else
-		wl_schedule_task(t->wl, wl_timer_task, t);
-#endif 	
 }
 
 static void
@@ -2312,7 +1921,7 @@
 }
 
 wl_timer_t *
-wl_init_timer(wl_info_t *wl, void (*fn)(void *arg), void *arg, const char *name)
+wl_init_timer(wl_info_t *wl, void (*fn)(void *arg), void *arg, const char *tname)
 {
 	wl_timer_t *t;
 
@@ -2320,7 +1929,7 @@
 
 	if (t == NULL) {
 		WL_ERROR(("wl%d: wl_init_timer: out of memory, malloced %d bytes\n",
-		          wl->unit, MALLOCED(wl->osh)));
+			wl->unit, MALLOCED(wl->osh)));
 		return 0;
 	}
 
@@ -2336,8 +1945,8 @@
 	wl->timers = t;
 
 #ifdef BCMDBG
-	if ((t->name = MALLOC(wl->osh, strlen(name) + 1)))
-		strcpy(t->name, name);
+	if ((t->name = MALLOC(wl->osh, strlen(tname) + 1)))
+		strcpy(t->name, tname);
 #endif
 
 	return t;
@@ -2433,7 +2042,7 @@
 	if (!wl->monitor_dev)
 		return;
 
-	if (wl->monitor_type == ARPHRD_IEEE80211_PRISM) {
+	if (wl->monitor_type == 1) {
 		p80211msg_t *phdr;
 
 		len = sizeof(p80211msg_t) + oskb->len - D11_PHY_HDR_LEN;
@@ -2502,18 +2111,19 @@
 		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 == ARPHRD_IEEE80211_RADIOTAP) {
+	}
+	else if (wl->monitor_type == 2) {
 		int channel_frequency;
 		uint16 channel_flags;
 		uint8 flags;
 		uint16 rtap_len;
-		struct dot11_header * mac_header;
+		struct dot11_header *mac_header;
 		uint16 fc;
 
-		if (rxsts->datarate != 0)
+		if (rxsts->phytype != WL_RXS_PHY_N)
 			rtap_len = sizeof(struct wl_radiotap_legacy);
 		else
-			rtap_len = sizeof(struct wl_radiotap_ht);
+			rtap_len = sizeof(struct wl_radiotap_ht_brcm);
 
 		len = rtap_len + (oskb->len - D11_PHY_HDR_LEN);
 		if ((skb = dev_alloc_skb(len)) == NULL)
@@ -2522,12 +2132,12 @@
 		skb_put(skb, len);
 
 		if (CHSPEC_IS2G(rxsts->chanspec)) {
-			channel_flags = IEEE80211_CHAN_2GHZ;
-			channel_frequency = wf_channel2mhz(CHSPEC_CHANNEL(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;
-			channel_frequency = wf_channel2mhz(CHSPEC_CHANNEL(rxsts->chanspec),
+			channel_flags = IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM;
+			channel_frequency = wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
 			                                   WF_CHAN_FACTOR_5_G);
 		}
 
@@ -2548,7 +2158,7 @@
 		if (rxsts->pkterror & WL_RXS_CRC_ERROR)
 			flags |= IEEE80211_RADIOTAP_F_BADFCS;
 
-		if (rxsts->datarate != 0) {
+		if (rxsts->phytype != WL_RXS_PHY_N) {
 			struct wl_radiotap_legacy *rtl = (struct wl_radiotap_legacy*)skb->data;
 
 			rtl->ieee_radiotap.it_version = 0;
@@ -2557,6 +2167,7 @@
 			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);
@@ -2565,16 +2176,17 @@
 			rtl->noise = (int8)rxsts->noise;
 			rtl->antenna = rxsts->antenna;
 		} else {
-			struct wl_radiotap_ht *rtht = (struct wl_radiotap_ht*)skb->data;
+			struct wl_radiotap_ht_brcm *rtht = (struct wl_radiotap_ht_brcm *)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->ieee_radiotap.it_present = HTOL32(WL_RADIOTAP_PRESENT_HT_BRCM);
 			rtht->it_present_ext = HTOL32(WL_RADIOTAP_BRCM_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);
@@ -2582,22 +2194,21 @@
 			rtht->signal = (int8)rxsts->signal;
 			rtht->noise = (int8)rxsts->noise;
 			rtht->antenna = rxsts->antenna;
-
 			rtht->pad3 = 0;
+
 			memcpy(rtht->vend_oui, "\x00\x10\x18", 3);
 			rtht->vend_sns = WL_RADIOTAP_BRCM_SNS;
 			rtht->vend_skip_len = 2;
-
 			rtht->mcs = rxsts->mcs;
 			rtht->htflags = 0;
 			if (rxsts->htflags & WL_RXS_HTF_40)
-				   rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_40;
+				rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_40;
 			if (rxsts->htflags & WL_RXS_HTF_SGI)
-				   rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_SGI;
+				rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_SGI;
 			if (rxsts->preamble & WL_RXS_PREAMBLE_HT_GF)
-				   rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_GF;
+				rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_GF;
 			if (rxsts->htflags & WL_RXS_HTF_LDPC)
-				   rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_LDPC;
+				rtht->htflags |= IEEE80211_RADIOTAP_HTMOD_LDPC;
 			rtht->htflags |=
 				(rxsts->htflags & WL_RXS_HTF_STBC_MASK) <<
 				IEEE80211_RADIOTAP_HTMOD_STBC_SHIFT;
@@ -2606,6 +2217,120 @@
 		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)
+			rtap_len = sizeof(struct wl_radiotap_legacy);
+		else
+			rtap_len = sizeof(struct wl_radiotap_ht);
+
+		len = rtap_len + (oskb->len - D11_PHY_HDR_LEN);
+		if ((skb = dev_alloc_skb(len)) == NULL)
+			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 = ntoh16(mac_header->fc);
+
+		flags = IEEE80211_RADIOTAP_F_FCS;
+
+		if (rxsts->preamble == WL_RXS_PREAMBLE_SHORT)
+			flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+		if (fc & (FC_WEP >> FC_WEP_SHIFT))
+			flags |= IEEE80211_RADIOTAP_F_WEP;
+
+		if (fc & (FC_MOREFRAG >> FC_MOREFRAG_SHIFT))
+			flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+		if (rxsts->pkterror & WL_RXS_CRC_ERROR)
+			flags |= IEEE80211_RADIOTAP_F_BADFCS;
+
+		if (rxsts->phytype != WL_RXS_PHY_N) {
+			struct wl_radiotap_legacy *rtl = (struct wl_radiotap_legacy*)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;
+		} else {
+			struct wl_radiotap_ht *rtht = (struct wl_radiotap_ht *)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->tsft_l = htol32(rxsts->mactime);
+			rtht->tsft_h = 0;
+			rtht->flags = flags;
+			rtht->pad1 = 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->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_index = rxsts->mcs;
+			rtht->mcs_flags = 0;
+			if (rxsts->htflags & WL_RXS_HTF_40) {
+				rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_40;
+			} else if (CHSPEC_IS40(rxsts->chanspec)) {
+				if (CHSPEC_SB_UPPER(rxsts->chanspec))
+					rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20U;
+				else
+					rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20L;
+			} else
+				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;
+			}
+		}
+
+		pdata = skb->data + rtap_len;
+		bcopy(oskb->data + D11_PHY_HDR_LEN, pdata, oskb->len - D11_PHY_HDR_LEN);
+	}
+
+	if (skb == NULL) return;
 
 	skb->dev = wl->monitor_dev;
 	skb->dev->last_rx = jiffies;
@@ -2618,11 +2343,7 @@
 	skb->pkt_type = PACKET_OTHERHOST;
 	skb->protocol = htons(ETH_P_80211_RAW);
 
-#ifdef NAPI_POLL
-	netif_receive_skb(skb);
-#else 
 	netif_rx(skb);
-#endif 
 }
 
 static int
@@ -2660,10 +2381,12 @@
 
 	bcopy(wl->dev->dev_addr, dev->dev_addr, ETHER_ADDR_LEN);
 	dev->flags = wl->dev->flags;
-	dev->type = wl->monitor_type;
-	if (wl->monitor_type == ARPHRD_IEEE80211_PRISM) {
+	if (wl->monitor_type == 1) {
+		dev->type = ARPHRD_IEEE80211_PRISM;
 		sprintf(dev->name, "prism%d", wl->pub->unit);
-	} else {
+	}
+	else {
+		dev->type = ARPHRD_IEEE80211_RADIOTAP;
 		sprintf(dev->name, "radiotap%d", wl->pub->unit);
 	}
 
@@ -2721,10 +2444,8 @@
 	WL_TRACE(("wl%d: wl_set_monitor: val %d\n", wl->pub->unit, val));
 
 	if (val && !wl->monitor_dev) {
-		if (val == 1)
-			wl->monitor_type = ARPHRD_IEEE80211_PRISM;
-		else if (val == 2)
-			wl->monitor_type = ARPHRD_IEEE80211_RADIOTAP;
+		if (val >= 1 && val <= 3)
+			wl->monitor_type = val;
 		else {
 			WL_ERROR(("monitor type %d not supported\n", val));
 			ASSERT(0);
@@ -2742,7 +2463,7 @@
 {
 	return "";
 }
-#endif	
+#endif 
 
 struct net_device *
 wl_netdev_get(wl_info_t *wl)
@@ -2873,7 +2594,7 @@
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
 	bool group_key = FALSE;
-	uchar	rxseq[IW_ENCODE_SEQ_MAX_SIZE];
+	uchar rxseq[IW_ENCODE_SEQ_MAX_SIZE];
 
 	if (key->len != 0) {
 		WL_WSEC(("%s: Key Length is Not zero\n", __FUNCTION__));
@@ -2979,7 +2700,7 @@
 #endif 
 }
 
-#if defined(WL_CONFIG_RFKILL)   
+#if defined(WL_CONFIG_RFKILL)     
 
 static int
 wl_set_radio_block(void *data, bool blocked)
@@ -2987,6 +2708,8 @@
 	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);
@@ -3002,7 +2725,7 @@
 }
 
 static const struct rfkill_ops bcmwl_rfkill_ops = {
-	.set_block = wl_set_radio_block,
+	.set_block = wl_set_radio_block
 };
 
 static int
@@ -3053,6 +2776,7 @@
 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);
 }
@@ -3143,7 +2867,7 @@
 }
 
 static int
-wl_proc_write(struct file *filp, const char __user *buff, unsigned long length, void *data)
+wl_proc_write(struct file *filp, const char *buff, unsigned long length, void *data)
 {
 	wl_info_t * wl = (wl_info_t *)data;
 	int from_user = 0;
