Le mardi 23 octobre 2012 06:34:06, Jasmine Hassan a écrit :
Hi,
> When attempting to make an upstream tarball out of the dkms package,
> similar to the upstream tarball of broadcom-sta-5.100.82.112, I
> noticed the dkms pacakge only includes an x86_64 binary, so that
> cannot replace the current broadcom-sta package (which has an i386
> binary). So, I must separately maintain this amd64 driver for
> bcm43142, on private repo, at least temporarily. Should I open an ITP?
I think you should not do that because this driver doesn't seem to be only for
this chipset but an enhanced version of the broadcom-sta driver which support
recent chipsets (see attached diff, in particular wl_id_table declaration).
I'll be pleased to upload the new version of the broadcom-sta driver when it's
released (including i386 binary).
Anyway this can't be done before Wheezy release.
Cheers,
--
Cyril Lacoux
--- 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;