aboutsummaryrefslogtreecommitdiffstats
path: root/package/broadcom-wl
diff options
context:
space:
mode:
Diffstat (limited to 'package/broadcom-wl')
-rw-r--r--package/broadcom-wl/Makefile41
-rw-r--r--package/broadcom-wl/files/lib/wifi/broadcom.sh26
-rw-r--r--package/broadcom-wl/src/driver/Makefile5
-rw-r--r--package/broadcom-wl/src/driver/bcmutils.c2306
-rw-r--r--package/broadcom-wl/src/driver/bcmutils.h582
-rw-r--r--package/broadcom-wl/src/driver/hnddma.c3164
-rw-r--r--package/broadcom-wl/src/driver/hnddma.h12
-rw-r--r--package/broadcom-wl/src/driver/linux_osl.c952
-rw-r--r--package/broadcom-wl/src/driver/linux_osl.h322
-rw-r--r--package/broadcom-wl/src/driver/patchtable.pl61
-rw-r--r--package/broadcom-wl/src/driver/pktq.h97
-rw-r--r--package/broadcom-wl/src/driver/proto/802.11.h1387
-rw-r--r--package/broadcom-wl/src/driver/proto/802.11e.h123
-rw-r--r--package/broadcom-wl/src/driver/proto/802.1d.h38
-rw-r--r--package/broadcom-wl/src/driver/proto/802.3.h20
-rw-r--r--package/broadcom-wl/src/driver/proto/bcmarp.h60
-rw-r--r--package/broadcom-wl/src/driver/proto/bcmdhcp.h36
-rw-r--r--package/broadcom-wl/src/driver/proto/bcmeth.h101
-rw-r--r--package/broadcom-wl/src/driver/proto/bcmevent.h166
-rw-r--r--package/broadcom-wl/src/driver/proto/bcmip.h152
-rw-r--r--package/broadcom-wl/src/driver/proto/bcmtcp.h68
-rw-r--r--package/broadcom-wl/src/driver/proto/bcmudp.h48
-rw-r--r--package/broadcom-wl/src/driver/proto/eap.h45
-rw-r--r--package/broadcom-wl/src/driver/proto/eapol.h179
-rw-r--r--package/broadcom-wl/src/driver/proto/ethernet.h175
-rw-r--r--package/broadcom-wl/src/driver/proto/vlan.h52
-rw-r--r--package/broadcom-wl/src/driver/proto/wpa.h158
-rw-r--r--package/broadcom-wl/src/driver/sbhnddma.h4
-rw-r--r--package/broadcom-wl/src/wlc/wlc.c225
-rw-r--r--package/broadcom-wl/src/wlcompat/Makefile3
-rw-r--r--package/broadcom-wl/src/wlcompat/wlcompat.c26
31 files changed, 8017 insertions, 2617 deletions
diff --git a/package/broadcom-wl/Makefile b/package/broadcom-wl/Makefile
index 8c68e8e817..b60d184fcf 100644
--- a/package/broadcom-wl/Makefile
+++ b/package/broadcom-wl/Makefile
@@ -10,13 +10,15 @@ include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=broadcom-wl
-PKG_VERSION:=4.80.53.0
+PKG_VERSION:=4.150.10.5
PKG_RELEASE:=1
WLC_VERSION:=0.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://downloads.openwrt.org/sources
-PKG_MD5SUM:=a7d8dde3ce474c361143b83e1d9890b1
+PKG_MD5SUM:=0c6ba9687114c6b598e8019e262d9a60
+
+WL_WEXT=1
include $(INCLUDE_DIR)/package.mk
@@ -107,7 +109,7 @@ endef
define Package/wl
$(call Package/broadcom-wl/Default)
TITLE:=Proprietary Broadcom wl driver config utility
- DEPENDS+=+brcm-compat-ldso
+# DEPENDS+=+brcm-compat-ldso
endef
define Package/wl/description
@@ -118,7 +120,7 @@ endef
define Package/nas
$(call Package/broadcom-wl/Default)
DEPENDS+= +nvram
- DEPENDS+= +brcm-compat-ldso
+# DEPENDS+= +brcm-compat-ldso
TITLE:=Proprietary Broadcom WPA/WPA2 authenticator
endef
@@ -127,20 +129,6 @@ define Package/nas/description
proprietary Broadcom wl driver.
endef
-
-define install_template
- $(INSTALL_DIR) $(1)/lib/modules/$(LINUX_VERSION)
- $(INSTALL_DATA) $(PKG_BUILD_DIR)/driver/wl$(2).o.patch $(1)/lib/modules/$(LINUX_VERSION)/
-endef
-
-define KernelPackage/brcm-wl/install
- $(call install_template,$(1),)
-endef
-
-define KernelPackage/brcm-wl_mimo/install
- $(call install_template,$(1),_mimo)
-endef
-
MAKE_KMOD := $(MAKE) -C "$(LINUX_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
@@ -149,7 +137,6 @@ MAKE_KMOD := $(MAKE) -C "$(LINUX_DIR)" \
define Build/Prepare
$(call Build/Prepare/Default)
- mv $(PKG_BUILD_DIR)/kmod $(PKG_BUILD_DIR)/driver
$(CP) src/* $(PKG_BUILD_DIR)/
endef
@@ -164,10 +151,12 @@ define Build/Compile
modules
$(MAKE_KMOD) \
SUBDIRS="$(PKG_BUILD_DIR)/wlcompat" \
+ $(if $(WL_WEXT),WL_WEXT=1) \
modules
$(MAKE_KMOD) \
SUBDIRS="$(PKG_BUILD_DIR)/wlcompat" \
DEBUG=1 \
+ $(if $(WL_WEXT),WL_WEXT=1) \
modules
# Compile wlc
@@ -175,10 +164,12 @@ define Build/Compile
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS)" \
all
- $(NO_TRACE_MAKE) -C compat-ldso -f build.mk PKG_INSTALL_DIR="$(PKG_BUILD_DIR)" BUILD_DIR="$(PKG_BUILD_DIR)"
- $(SED) 's,ld-uClibc.so.0,ld-uClibc.brcm,' \
- $(PKG_BUILD_DIR)/wl \
- $(PKG_BUILD_DIR)/nas
+ $(TARGET_CC) -o $(PKG_BUILD_DIR)/nas $(PKG_BUILD_DIR)/nas_exe.o -L$(STAGING_DIR)/usr/lib -lnvram
+ $(TARGET_CC) -o $(PKG_BUILD_DIR)/wl $(PKG_BUILD_DIR)/wl_exe.o
+# $(NO_TRACE_MAKE) -C compat-ldso -f build.mk PKG_INSTALL_DIR="$(PKG_BUILD_DIR)"
+# $(SED) 's,ld-uClibc.so.0,ld-uClibc.brcm,' \
+# $(PKG_BUILD_DIR)/wl \
+# $(PKG_BUILD_DIR)/nas
endef
define Package/brcm-compat-ldso/install
@@ -198,8 +189,6 @@ define Package/wl/install
endef
define Package/nas/install
- $(INSTALL_DIR) $(1)/usr/lib
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/libbcmcrypto.so $(1)/usr/lib/
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nas $(1)/usr/sbin/
ln -sf nas $(1)/usr/sbin/nas4not
@@ -208,7 +197,7 @@ endef
$(eval $(call KernelPackage,brcm-wl))
$(eval $(call KernelPackage,brcm-wl-mimo))
-$(eval $(call BuildPackage,brcm-compat-ldso))
+#$(eval $(call BuildPackage,brcm-compat-ldso))
$(eval $(call KernelPackage,wlcompat))
$(eval $(call KernelPackage,wlcompat-debug))
$(eval $(call BuildPackage,wlc))
diff --git a/package/broadcom-wl/files/lib/wifi/broadcom.sh b/package/broadcom-wl/files/lib/wifi/broadcom.sh
index d9b2220e3f..2e6f2e8e42 100644
--- a/package/broadcom-wl/files/lib/wifi/broadcom.sh
+++ b/package/broadcom-wl/files/lib/wifi/broadcom.sh
@@ -52,7 +52,7 @@ scan_broadcom() {
case "$adhoc:$sta:$apmode" in
1*)
ap=0
- mssid=0
+ mssid=
infra=0
;;
:1:1)
@@ -62,7 +62,7 @@ scan_broadcom() {
:1:)
wet=1
ap=0
- mssid=0
+ mssid=
;;
::)
radio=0
@@ -158,11 +158,11 @@ enable_broadcom() {
config_get k "$vif" key$knr
[ -n "$k" ] || continue
[ "$defkey" = "$knr" ] && def="=" || def=""
- append vif_pre_up "wepkey $def$knr,$k" "$N"
+ append vif_do_up "wepkey $def$knr,$k" "$N"
done
;;
"");;
- *) append vif_pre_up "wepkey =1,$key" "$N";;
+ *) append vif_do_up "wepkey =1,$key" "$N";;
esac
;;
*psk*|*PSK*)
@@ -191,17 +191,15 @@ enable_broadcom() {
nasopts="-r \"\$${vif}_key\" -h $server -p $port"
;;
esac
- append vif_post_up "wsec $wsec" "$N"
- append vif_post_up "wpa_auth $auth" "$N"
- append vif_post_up "wsec_restrict $wsec_r" "$N"
- append vif_post_up "eap_restrict $eap_r" "$N"
+ append vif_do_up "wsec $wsec" "$N"
+ append vif_do_up "wpa_auth $auth" "$N"
+ append vif_do_up "wsec_restrict $wsec_r" "$N"
+ append vif_do_up "eap_restrict $eap_r" "$N"
config_get ssid "$vif" ssid
append vif_post_up "vlan_mode 0" "$N"
append vif_post_up "ssid $ssid" "$N"
- case "$mode" in
- sta|adhoc) append vif_do_up "ssid $ssid" "$N";;
- esac
+ append vif_do_up "ssid $ssid" "$N"
append vif_post_up "enabled 1" "$N"
@@ -221,8 +219,8 @@ enable_broadcom() {
[ "$mode" = "sta" ] && {
nas_mode="-S"
[ -z "$bridge" ] || {
- append vif_pre_up "supplicant 1" "$N"
- append vif_pre_up "passphrase $key" "$N"
+ append vif_post_up "supplicant 1" "$N"
+ append vif_post_up "passphrase $key" "$N"
use_nas=0
}
@@ -236,7 +234,7 @@ enable_broadcom() {
$ifdown
ap $ap
-mssid $mssid
+${mssid:+mssid $mssid}
apsta $apsta
infra $infra
${wet:+wet 1}
diff --git a/package/broadcom-wl/src/driver/Makefile b/package/broadcom-wl/src/driver/Makefile
index 0a16bdcec0..c75795a554 100644
--- a/package/broadcom-wl/src/driver/Makefile
+++ b/package/broadcom-wl/src/driver/Makefile
@@ -23,9 +23,6 @@ obj-m := $(O_TARGET)
wl_mod$(MOD_NAME).o: wl_apsta$(MOD_NAME).o
perl -ne 's,eth%d,wl%d\x00,g,print' < $< > $@
-wl$(MOD_NAME).o.patch: wl$(MOD_NAME).o
- $(OBJDUMP) -d $< | perl patchtable.pl > $@
-
-modules: wl$(MOD_NAME).o.patch
+modules: wl$(MOD_NAME).o
include $(TOPDIR)/Rules.make
diff --git a/package/broadcom-wl/src/driver/bcmutils.c b/package/broadcom-wl/src/driver/bcmutils.c
index 7592f230ad..88337d60c7 100644
--- a/package/broadcom-wl/src/driver/bcmutils.c
+++ b/package/broadcom-wl/src/driver/bcmutils.c
@@ -1,730 +1,1590 @@
/*
- * Misc useful OS-independent routines.
+ * Driver O/S-independent utility routines
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#include <typedefs.h>
#include <bcmdefs.h>
#include <stdarg.h>
+#include "bcmutils.h"
#include <osl.h>
-#include "linux_osl.h"
-#include "pktq.h"
-#include <bcmutils.h>
#include <sbutils.h>
#include <bcmnvram.h>
#include <bcmendian.h>
#include <bcmdevs.h>
-#include "bcmip.h"
-
-#define ETHER_TYPE_8021Q 0x8100
-#define ETHER_TYPE_IP 0x0800
-#define VLAN_PRI_SHIFT 13
-#define VLAN_PRI_MASK 7
-
-
-struct ether_header {
- uint8 ether_dhost[6];
- uint8 ether_shost[6];
- uint16 ether_type;
-} __attribute__((packed));
-
-
-struct ethervlan_header {
- uint8 ether_dhost[6];
- uint8 ether_shost[6];
- uint16 vlan_type; /* 0x8100 */
- uint16 vlan_tag; /* priority, cfi and vid */
- uint16 ether_type;
-};
+#include "proto/ethernet.h"
+#include "proto/vlan.h"
+#include "proto/bcmip.h"
+#include "proto/bcmtcp.h"
+#include "proto/802.1d.h"
+
+#ifdef BCMPERFSTATS
+#include <bcmperf.h>
+#endif
+
+#if 0
+/* nvram vars cache */
+static char *nvram_vars = NULL;
+static int vars_len = -1;
+#endif
/* copy a pkt buffer chain into a buffer */
uint
-pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf)
+pktcopy (osl_t * osh, void *p, uint offset, int len, uchar * buf)
{
- uint n, ret = 0;
-
- if (len < 0)
- len = 4096; /* "infinite" */
-
- /* skip 'offset' bytes */
- for (; p && offset; p = PKTNEXT(osh, p)) {
- if (offset < (uint)PKTLEN(osh, p))
- break;
- offset -= PKTLEN(osh, p);
- }
-
- if (!p)
- return 0;
-
- /* copy the data */
- for (; p && len; p = PKTNEXT(osh, p)) {
- n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
- bcopy(PKTDATA(osh, p) + offset, buf, n);
- buf += n;
- len -= n;
- ret += n;
- offset = 0;
- }
-
- return ret;
+ uint n, ret = 0;
+
+ if (len < 0)
+ len = 4096; /* "infinite" */
+
+ /* skip 'offset' bytes */
+ for (; p && offset; p = PKTNEXT (osh, p))
+ {
+ if (offset < (uint) PKTLEN (osh, p))
+ break;
+ offset -= PKTLEN (osh, p);
+ }
+
+ if (!p)
+ return 0;
+
+ /* copy the data */
+ for (; p && len; p = PKTNEXT (osh, p))
+ {
+ n = MIN ((uint) PKTLEN (osh, p) - offset, (uint) len);
+ bcopy (PKTDATA (osh, p) + offset, buf, n);
+ buf += n;
+ len -= n;
+ ret += n;
+ offset = 0;
+ }
+
+ return ret;
}
/* return total length of buffer chain */
uint
-pkttotlen(osl_t *osh, void *p)
+pkttotlen (osl_t * osh, void *p)
{
- uint total;
+ uint total;
- total = 0;
- for (; p; p = PKTNEXT(osh, p))
- total += PKTLEN(osh, p);
- return (total);
+ total = 0;
+ for (; p; p = PKTNEXT (osh, p))
+ total += PKTLEN (osh, p);
+ return (total);
}
/* return the last buffer of chained pkt */
void *
-pktlast(osl_t *osh, void *p)
+pktlast (osl_t * osh, void *p)
{
- for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p))
- ;
+ for (; PKTNEXT (osh, p); p = PKTNEXT (osh, p))
+ ;
- return (p);
+ return (p);
}
/*
* osl multiple-precedence packet queue
- * hi_prec is always >= the number of the highest non-empty queue
+ * hi_prec is always >= the number of the highest non-empty precedence
*/
void *
-pktq_penq(struct pktq *pq, int prec, void *p)
+pktq_penq (struct pktq *pq, int prec, void *p)
{
- struct pktq_prec *q;
+ struct pktq_prec *q;
- ASSERT(prec >= 0 && prec < pq->num_prec);
- ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
+ ASSERT (prec >= 0 && prec < pq->num_prec);
+ ASSERT (PKTLINK (p) == NULL); /* queueing chains not allowed */
- ASSERT(!pktq_full(pq));
- ASSERT(!pktq_pfull(pq, prec));
+ ASSERT (!pktq_full (pq));
+ ASSERT (!pktq_pfull (pq, prec));
- q = &pq->q[prec];
+ q = &pq->q[prec];
- if (q->head)
- PKTSETLINK(q->tail, p);
- else
- q->head = p;
+ if (q->head)
+ PKTSETLINK (q->tail, p);
+ else
+ q->head = p;
- q->tail = p;
- q->len++;
+ q->tail = p;
+ q->len++;
- pq->len++;
+ pq->len++;
- if (pq->hi_prec < prec)
- pq->hi_prec = (uint8)prec;
+ if (pq->hi_prec < prec)
+ pq->hi_prec = (uint8) prec;
- return p;
+ return p;
}
void *
-pktq_penq_head(struct pktq *pq, int prec, void *p)
+pktq_penq_head (struct pktq *pq, int prec, void *p)
{
- struct pktq_prec *q;
+ struct pktq_prec *q;
- ASSERT(prec >= 0 && prec < pq->num_prec);
- ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
+ ASSERT (prec >= 0 && prec < pq->num_prec);
+ ASSERT (PKTLINK (p) == NULL); /* queueing chains not allowed */
- ASSERT(!pktq_full(pq));
- ASSERT(!pktq_pfull(pq, prec));
+ ASSERT (!pktq_full (pq));
+ ASSERT (!pktq_pfull (pq, prec));
- q = &pq->q[prec];
+ q = &pq->q[prec];
- if (q->head == NULL)
- q->tail = p;
+ if (q->head == NULL)
+ q->tail = p;
- PKTSETLINK(p, q->head);
- q->head = p;
- q->len++;
+ PKTSETLINK (p, q->head);
+ q->head = p;
+ q->len++;
- pq->len++;
+ pq->len++;
- if (pq->hi_prec < prec)
- pq->hi_prec = (uint8)prec;
+ if (pq->hi_prec < prec)
+ pq->hi_prec = (uint8) prec;
- return p;
+ return p;
}
void *
-pktq_pdeq(struct pktq *pq, int prec)
+pktq_pdeq (struct pktq *pq, int prec)
{
- struct pktq_prec *q;
- void *p;
+ struct pktq_prec *q;
+ void *p;
- ASSERT(prec >= 0 && prec < pq->num_prec);
+ ASSERT (prec >= 0 && prec < pq->num_prec);
- q = &pq->q[prec];
+ q = &pq->q[prec];
- if ((p = q->head) == NULL)
- return NULL;
+ if ((p = q->head) == NULL)
+ return NULL;
- if ((q->head = PKTLINK(p)) == NULL)
- q->tail = NULL;
+ if ((q->head = PKTLINK (p)) == NULL)
+ q->tail = NULL;
- q->len--;
+ q->len--;
- pq->len--;
+ pq->len--;
- PKTSETLINK(p, NULL);
+ PKTSETLINK (p, NULL);
- return p;
+ return p;
}
void *
-pktq_pdeq_tail(struct pktq *pq, int prec)
+pktq_pdeq_tail (struct pktq *pq, int prec)
{
- struct pktq_prec *q;
- void *p, *prev;
+ struct pktq_prec *q;
+ void *p, *prev;
- ASSERT(prec >= 0 && prec < pq->num_prec);
+ ASSERT (prec >= 0 && prec < pq->num_prec);
- q = &pq->q[prec];
+ q = &pq->q[prec];
- if ((p = q->head) == NULL)
- return NULL;
+ if ((p = q->head) == NULL)
+ return NULL;
- for (prev = NULL; p != q->tail; p = PKTLINK(p))
- prev = p;
+ for (prev = NULL; p != q->tail; p = PKTLINK (p))
+ prev = p;
- if (prev)
- PKTSETLINK(prev, NULL);
- else
- q->head = NULL;
+ if (prev)
+ PKTSETLINK (prev, NULL);
+ else
+ q->head = NULL;
- q->tail = prev;
- q->len--;
+ q->tail = prev;
+ q->len--;
- pq->len--;
+ pq->len--;
- return p;
+ return p;
}
void
-pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir)
-{
- struct pktq_prec *q;
- void *p;
-
- q = &pq->q[prec];
- p = q->head;
- while (p) {
- q->head = PKTLINK(p);
- PKTSETLINK(p, NULL);
- PKTFREE(osh, p, dir);
- q->len--;
- pq->len--;
- p = q->head;
- }
- ASSERT(q->len == 0);
- q->tail = NULL;
+pktq_pflush (osl_t * osh, struct pktq *pq, int prec, bool dir)
+{
+ struct pktq_prec *q;
+ void *p;
+
+ q = &pq->q[prec];
+ p = q->head;
+ while (p)
+ {
+ q->head = PKTLINK (p);
+ PKTSETLINK (p, NULL);
+ PKTFREE (osh, p, dir);
+ q->len--;
+ pq->len--;
+ p = q->head;
+ }
+ ASSERT (q->len == 0);
+ q->tail = NULL;
}
+#if 0
bool
-pktq_pdel(struct pktq *pq, void *pktbuf, int prec)
+pktq_pdel (struct pktq *pq, void *pktbuf, int prec)
{
- struct pktq_prec *q;
- void *p;
-
- ASSERT(prec >= 0 && prec < pq->num_prec);
+ struct pktq_prec *q;
+ void *p;
- if (!pktbuf)
- return FALSE;
+ ASSERT (prec >= 0 && prec < pq->num_prec);
- q = &pq->q[prec];
+ if (!pktbuf)
+ return FALSE;
- if (q->head == pktbuf) {
- if ((q->head = PKTLINK(pktbuf)) == NULL)
- q->tail = NULL;
- } else {
- for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p))
- ;
- if (p == NULL)
- return FALSE;
+ q = &pq->q[prec];
- PKTSETLINK(p, PKTLINK(pktbuf));
- if (q->tail == pktbuf)
- q->tail = p;
- }
+ if (q->head == pktbuf)
+ {
+ if ((q->head = PKTLINK (pktbuf)) == NULL)
+ q->tail = NULL;
+ }
+ else
+ {
+ for (p = q->head; p && PKTLINK (p) != pktbuf; p = PKTLINK (p))
+ ;
+ if (p == NULL)
+ return FALSE;
+
+ PKTSETLINK (p, PKTLINK (pktbuf));
+ if (q->tail == pktbuf)
+ q->tail = p;
+ }
- q->len--;
- pq->len--;
- PKTSETLINK(pktbuf, NULL);
- return TRUE;
+ q->len--;
+ pq->len--;
+ PKTSETLINK (pktbuf, NULL);
+ return TRUE;
}
+#endif
void
-pktq_init(struct pktq *pq, int num_prec, int max_len)
+pktq_init (struct pktq *pq, int num_prec, int max_len)
{
- int prec;
+ int prec;
- ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC);
+ ASSERT (num_prec > 0 && num_prec <= PKTQ_MAX_PREC);
- bzero(pq, sizeof(*pq));
+ /* pq is variable size; only zero out what's requested */
+ bzero (pq,
+ OFFSETOF (struct pktq, q) + (sizeof (struct pktq_prec) * num_prec));
- pq->num_prec = (uint16)num_prec;
+ pq->num_prec = (uint16) num_prec;
- pq->max = (uint16)max_len;
+ pq->max = (uint16) max_len;
- for (prec = 0; prec < num_prec; prec++)
- pq->q[prec].max = pq->max;
+ for (prec = 0; prec < num_prec; prec++)
+ pq->q[prec].max = pq->max;
+}
+
+int
+pktq_setmax (struct pktq *pq, int max_len)
+{
+ int prec;
+
+ if (!max_len)
+ return pq->max;
+
+ pq->max = (uint16) max_len;
+ for (prec = 0; prec < pq->num_prec; prec++)
+ pq->q[prec].max = pq->max;
+
+ return pq->max;
}
void *
-pktq_deq(struct pktq *pq, int *prec_out)
+pktq_deq (struct pktq *pq, int *prec_out)
{
- struct pktq_prec *q;
- void *p;
- int prec;
+ struct pktq_prec *q;
+ void *p;
+ int prec;
- if (pq->len == 0)
- return NULL;
+ if (pq->len == 0)
+ return NULL;
- while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
- pq->hi_prec--;
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
- q = &pq->q[prec];
+ q = &pq->q[prec];
- if ((p = q->head) == NULL)
- return NULL;
+ if ((p = q->head) == NULL)
+ return NULL;
- if ((q->head = PKTLINK(p)) == NULL)
- q->tail = NULL;
+ if ((q->head = PKTLINK (p)) == NULL)
+ q->tail = NULL;
- q->len--;
+ q->len--;
- pq->len--;
+ pq->len--;
- if (prec_out)
- *prec_out = prec;
+ if (prec_out)
+ *prec_out = prec;
- PKTSETLINK(p, NULL);
+ PKTSETLINK (p, NULL);
- return p;
+ return p;
}
void *
-pktq_deq_tail(struct pktq *pq, int *prec_out)
+pktq_deq_tail (struct pktq *pq, int *prec_out)
{
- struct pktq_prec *q;
- void *p, *prev;
- int prec;
+ struct pktq_prec *q;
+ void *p, *prev;
+ int prec;
- if (pq->len == 0)
- return NULL;
+ if (pq->len == 0)
+ return NULL;
- for (prec = 0; prec < pq->hi_prec; prec++)
- if (pq->q[prec].head)
- break;
+ for (prec = 0; prec < pq->hi_prec; prec++)
+ if (pq->q[prec].head)
+ break;
- q = &pq->q[prec];
+ q = &pq->q[prec];
- if ((p = q->head) == NULL)
- return NULL;
+ if ((p = q->head) == NULL)
+ return NULL;
- for (prev = NULL; p != q->tail; p = PKTLINK(p))
- prev = p;
+ for (prev = NULL; p != q->tail; p = PKTLINK (p))
+ prev = p;
- if (prev)
- PKTSETLINK(prev, NULL);
- else
- q->head = NULL;
+ if (prev)
+ PKTSETLINK (prev, NULL);
+ else
+ q->head = NULL;
- q->tail = prev;
- q->len--;
+ q->tail = prev;
+ q->len--;
- pq->len--;
+ pq->len--;
- if (prec_out)
- *prec_out = prec;
+ if (prec_out)
+ *prec_out = prec;
- PKTSETLINK(p, NULL);
+ PKTSETLINK (p, NULL);
- return p;
+ return p;
}
+#if 0
void *
-pktq_peek(struct pktq *pq, int *prec_out)
+pktq_peek (struct pktq *pq, int *prec_out)
{
- int prec;
+ int prec;
- if (pq->len == 0)
- return NULL;
+ if (pq->len == 0)
+ return NULL;
- while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
- pq->hi_prec--;
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
- if (prec_out)
- *prec_out = prec;
+ if (prec_out)
+ *prec_out = prec;
- return (pq->q[prec].head);
+ return (pq->q[prec].head);
}
+#endif
void *
-pktq_peek_tail(struct pktq *pq, int *prec_out)
+pktq_peek_tail (struct pktq *pq, int *prec_out)
{
- int prec;
+ int prec;
- if (pq->len == 0)
- return NULL;
+ if (pq->len == 0)
+ return NULL;
- for (prec = 0; prec < pq->hi_prec; prec++)
- if (pq->q[prec].head)
- break;
+ for (prec = 0; prec < pq->hi_prec; prec++)
+ if (pq->q[prec].head)
+ break;
- if (prec_out)
- *prec_out = prec;
+ if (prec_out)
+ *prec_out = prec;
- return (pq->q[prec].tail);
+ return (pq->q[prec].tail);
}
void
-pktq_flush(osl_t *osh, struct pktq *pq, bool dir)
+pktq_flush (osl_t * osh, struct pktq *pq, bool dir)
{
- int prec;
- for (prec = 0; prec < pq->num_prec; prec++)
- pktq_pflush(osh, pq, prec, dir);
- ASSERT(pq->len == 0);
+ int prec;
+ for (prec = 0; prec < pq->num_prec; prec++)
+ pktq_pflush (osh, pq, prec, dir);
+ ASSERT (pq->len == 0);
}
/* Return sum of lengths of a specific set of precedences */
int
-pktq_mlen(struct pktq *pq, uint prec_bmp)
+pktq_mlen (struct pktq *pq, uint prec_bmp)
{
- int prec, len;
+ int prec, len;
- len = 0;
+ len = 0;
- for (prec = 0; prec <= pq->hi_prec; prec++)
- if (prec_bmp & (1 << prec))
- len += pq->q[prec].len;
+ for (prec = 0; prec <= pq->hi_prec; prec++)
+ if (prec_bmp & (1 << prec))
+ len += pq->q[prec].len;
- return len;
+ return len;
}
/* Priority dequeue from a specific set of precedences */
void *
-pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out)
+pktq_mdeq (struct pktq *pq, uint prec_bmp, int *prec_out)
{
- struct pktq_prec *q;
- void *p;
- int prec;
+ struct pktq_prec *q;
+ void *p;
+ int prec;
- if (pq->len == 0)
- return NULL;
+ if (pq->len == 0)
+ return NULL;
- while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
- pq->hi_prec--;
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
- while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
- if (prec-- == 0)
- return NULL;
+ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
+ if (prec-- == 0)
+ return NULL;
- q = &pq->q[prec];
+ q = &pq->q[prec];
- if ((p = q->head) == NULL)
- return NULL;
+ if ((p = q->head) == NULL)
+ return NULL;
- if ((q->head = PKTLINK(p)) == NULL)
- q->tail = NULL;
+ if ((q->head = PKTLINK (p)) == NULL)
+ q->tail = NULL;
- q->len--;
+ q->len--;
- if (prec_out)
- *prec_out = prec;
+ if (prec_out)
+ *prec_out = prec;
- pq->len--;
+ pq->len--;
- PKTSETLINK(p, NULL);
+ PKTSETLINK (p, NULL);
- return p;
+ return p;
}
-char*
-bcmstrcat(char *dest, const char *src)
+const unsigned char bcm_ctype[] = {
+ _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, /* 0-7 */
+ _BCM_C, _BCM_C | _BCM_S, _BCM_C | _BCM_S, _BCM_C | _BCM_S, _BCM_C | _BCM_S,
+ _BCM_C | _BCM_S, _BCM_C,
+ _BCM_C, /* 8-15 */
+ _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, /* 16-23 */
+ _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, /* 24-31 */
+ _BCM_S | _BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 32-39 */
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 40-47 */
+ _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, /* 48-55 */
+ _BCM_D, _BCM_D, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 56-63 */
+ _BCM_P, _BCM_U | _BCM_X, _BCM_U | _BCM_X, _BCM_U | _BCM_X, _BCM_U | _BCM_X,
+ _BCM_U | _BCM_X,
+ _BCM_U | _BCM_X, _BCM_U, /* 64-71 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 72-79 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 80-87 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 88-95 */
+ _BCM_P, _BCM_L | _BCM_X, _BCM_L | _BCM_X, _BCM_L | _BCM_X, _BCM_L | _BCM_X,
+ _BCM_L | _BCM_X,
+ _BCM_L | _BCM_X, _BCM_L, /* 96-103 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 104-111 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 112-119 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_C, /* 120-127 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */
+ _BCM_S | _BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
+ _BCM_U, _BCM_U,
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U,
+ _BCM_U, _BCM_U,
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
+ _BCM_L, _BCM_L,
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L,
+ _BCM_L, _BCM_L,
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
+};
+
+ulong BCMROMFN (bcm_strtoul) (char *cp, char **endp, uint base)
{
- strcpy(&dest[strlen(dest)], src);
- return (dest);
+ ulong result, value;
+ bool minus;
+
+ minus = FALSE;
+
+ while (bcm_isspace (*cp))
+ cp++;
+
+ if (cp[0] == '+')
+ cp++;
+ else if (cp[0] == '-')
+ {
+ minus = TRUE;
+ cp++;
+ }
+
+ if (base == 0)
+ {
+ if (cp[0] == '0')
+ {
+ if ((cp[1] == 'x') || (cp[1] == 'X'))
+ {
+ base = 16;
+ cp = &cp[2];
+ }
+ else
+ {
+ base = 8;
+ cp = &cp[1];
+ }
+ }
+ else
+ base = 10;
+ }
+ else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X')))
+ {
+ cp = &cp[2];
+ }
+
+ result = 0;
+
+ while (bcm_isxdigit (*cp) &&
+ (value =
+ bcm_isdigit (*cp) ? *cp - '0' : bcm_toupper (*cp) - 'A' + 10) <
+ base)
+ {
+ result = result * base + value;
+ cp++;
+ }
+
+ if (minus)
+ result = (ulong) (result * -1);
+
+ if (endp)
+ *endp = (char *) cp;
+
+ return (result);
}
-char*
-bcm_ether_ntoa(struct ether_addr *ea, char *buf)
+#if 0
+int BCMROMFN (bcm_atoi) (char *s)
{
- sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
- ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff,
- ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff);
- return (buf);
+ return (int) bcm_strtoul (s, NULL, 10);
}
+/* return pointer to location of substring 'needle' in 'haystack' */
+char *BCMROMFN (bcmstrstr) (char *haystack, char *needle)
+{
+ int len, nlen;
+ int i;
+
+ if ((haystack == NULL) || (needle == NULL))
+ return (haystack);
+
+ nlen = strlen (needle);
+ len = strlen (haystack) - nlen + 1;
+
+ for (i = 0; i < len; i++)
+ if (memcmp (needle, &haystack[i], nlen) == 0)
+ return (&haystack[i]);
+ return (NULL);
+}
+
+char *BCMROMFN (bcmstrcat) (char *dest, const char *src)
+{
+ strcpy (&dest[strlen (dest)], src);
+ return (dest);
+}
+
+char *BCMROMFN (bcmstrncat) (char *dest, const char *src, uint size)
+{
+ char *endp;
+ char *p;
+
+ p = dest + strlen (dest);
+ endp = p + size;
+
+ while (p != endp && (*p++ = *src++) != '\0')
+ ;
+
+ return (dest);
+}
+#endif
+
/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
+int BCMROMFN (bcm_ether_atoe) (char *p, struct ether_addr * ea)
+{
+ int i = 0;
+
+ for (;;)
+ {
+ ea->octet[i++] = (char) bcm_strtoul (p, &p, 16);
+ if (!*p++ || i == 6)
+ break;
+ }
+
+ return (i == 6);
+}
+
+#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER)
+/* registry routine buffer preparation utility functions:
+ * parameter order is like strncpy, but returns count
+ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2)
+ */
+ulong
+wchar2ascii (char *abuf, ushort * wbuf, ushort wbuflen, ulong abuflen)
+{
+ ulong copyct = 1;
+ ushort i;
+
+ if (abuflen == 0)
+ return 0;
+
+ /* wbuflen is in bytes */
+ wbuflen /= sizeof (ushort);
+
+ for (i = 0; i < wbuflen; ++i)
+ {
+ if (--abuflen == 0)
+ break;
+ *abuf++ = (char) *wbuf++;
+ ++copyct;
+ }
+ *abuf = '\0';
+
+ return copyct;
+}
+#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */
+
+#if 0
+char *
+bcm_ether_ntoa (struct ether_addr *ea, char *buf)
+{
+ snprintf (buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+ ea->octet[0] & 0xff, ea->octet[1] & 0xff, ea->octet[2] & 0xff,
+ ea->octet[3] & 0xff, ea->octet[4] & 0xff, ea->octet[5] & 0xff);
+ return (buf);
+}
+
+char *
+bcm_ip_ntoa (struct ipv4_addr *ia, char *buf)
+{
+ snprintf (buf, 16, "%d.%d.%d.%d",
+ ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]);
+ return (buf);
+}
+void
+bcm_mdelay (uint ms)
+{
+ uint i;
+
+ for (i = 0; i < ms; i++)
+ {
+ OSL_DELAY (1000);
+ }
+}
+#endif
+
+#if 0
+
+/*
+ * Search the name=value vars for a specific one and return its value.
+ * Returns NULL if not found.
+ */
+char *
+getvar (char *vars, const char *name)
+{
+#ifdef _MINOSL_
+ return NULL;
+#else
+ char *s;
+ int len;
+
+ if (!name)
+ return NULL;
+
+ len = strlen (name);
+ if (len == 0)
+ return NULL;
+
+ /* first look in vars[] */
+ for (s = vars; s && *s;)
+ {
+ /* CSTYLED */
+ if ((bcmp (s, name, len) == 0) && (s[len] == '='))
+ return (&s[len + 1]);
+
+ while (*s++)
+ ;
+ }
+
+ /* then query nvram */
+ return (nvram_get (name));
+#endif /* _MINOSL_ */
+}
+
+/*
+ * Search the vars for a specific one and return its value as
+ * an integer. Returns 0 if not found.
+ */
int
-bcm_ether_atoe(char *p, struct ether_addr *ea)
+getintvar (char *vars, const char *name)
+{
+#ifdef _MINOSL_
+ return 0;
+#else
+ char *val;
+
+ if ((val = getvar (vars, name)) == NULL)
+ return (0);
+
+ return (bcm_strtoul (val, NULL, 0));
+#endif /* _MINOSL_ */
+}
+
+
+/* Search for token in comma separated token-string */
+static int
+findmatch (char *string, char *name)
{
- int i = 0;
+ uint len;
+ char *c;
+
+ len = strlen (name);
+ /* CSTYLED */
+ while ((c = strchr (string, ',')) != NULL)
+ {
+ if (len == (uint) (c - string) && !strncmp (string, name, len))
+ return 1;
+ string = c + 1;
+ }
+
+ return (!strcmp (string, name));
+}
- for (;;) {
- ea->octet[i++] = (char) bcm_strtoul(p, &p, 16);
- if (!*p++ || i == 6)
- break;
+/* Return gpio pin number assigned to the named pin
+ *
+ * Variable should be in format:
+ *
+ * gpio<N>=pin_name,pin_name
+ *
+ * This format allows multiple features to share the gpio with mutual
+ * understanding.
+ *
+ * 'def_pin' is returned if a specific gpio is not defined for the requested functionality
+ * and if def_pin is not used by others.
+ */
+uint
+getgpiopin (char *vars, char *pin_name, uint def_pin)
+{
+ char name[] = "gpioXXXX";
+ char *val;
+ uint pin;
+
+ /* Go thru all possibilities till a match in pin name */
+ for (pin = 0; pin < GPIO_NUMPINS; pin++)
+ {
+ snprintf (name, sizeof (name), "gpio%d", pin);
+ val = getvar (vars, name);
+ if (val && findmatch (val, pin_name))
+ return pin;
+ }
+
+ if (def_pin != GPIO_PIN_NOTDEFINED)
+ {
+ /* make sure the default pin is not used by someone else */
+ snprintf (name, sizeof (name), "gpio%d", def_pin);
+ if (getvar (vars, name))
+ {
+ def_pin = GPIO_PIN_NOTDEFINED;
}
+ }
+
+ return def_pin;
+}
+#endif
+
+#ifdef BCMPERFSTATS
- return (i == 6);
+#define LOGSIZE 256 /* should be power of 2 to avoid div below */
+static struct
+{
+ uint cycles;
+ char *fmt;
+ uint a1;
+ uint a2;
+} logtab[LOGSIZE];
+
+/* last entry logged */
+static uint logi = 0;
+/* next entry to read */
+static uint readi = 0;
+
+void
+bcm_perf_enable ()
+{
+ BCMPERF_ENABLE_INSTRCOUNT ();
+ BCMPERF_ENABLE_ICACHE_MISS ();
+ BCMPERF_ENABLE_ICACHE_HIT ();
}
-/* Takes an Ethernet frame and sets out-of-bound PKTPRIO
- * Also updates the inplace vlan tag if requested
+void
+bcmlog (char *fmt, uint a1, uint a2)
+{
+ static uint last = 0;
+ uint cycles, i;
+ OSL_GETCYCLES (cycles);
+
+ i = logi;
+
+ logtab[i].cycles = cycles - last;
+ logtab[i].fmt = fmt;
+ logtab[i].a1 = a1;
+ logtab[i].a2 = a2;
+
+ logi = (i + 1) % LOGSIZE;
+ last = cycles;
+}
+
+
+void
+bcmstats (char *fmt)
+{
+ static uint last = 0;
+ static uint32 ic_miss = 0;
+ static uint32 instr_count = 0;
+ uint32 ic_miss_cur;
+ uint32 instr_count_cur;
+ uint cycles, i;
+
+ OSL_GETCYCLES (cycles);
+ BCMPERF_GETICACHE_MISS (ic_miss_cur);
+ BCMPERF_GETINSTRCOUNT (instr_count_cur);
+
+ i = logi;
+
+ logtab[i].cycles = cycles - last;
+ logtab[i].a1 = ic_miss_cur - ic_miss;
+ logtab[i].a2 = instr_count_cur - instr_count;
+ logtab[i].fmt = fmt;
+
+ logi = (i + 1) % LOGSIZE;
+
+ last = cycles;
+ instr_count = instr_count_cur;
+ ic_miss = ic_miss_cur;
+}
+
+
+void
+bcmdumplog (char *buf, int size)
+{
+ char *limit, *line;
+ int j = 0;
+ int num;
+
+ limit = buf + size - 80;
+ *buf = '\0';
+
+ num = logi - readi;
+
+ if (num < 0)
+ num += LOGSIZE;
+
+ /* print in chronological order */
+
+ for (j = 0; j < num && (buf < limit); readi = (readi + 1) % LOGSIZE, j++)
+ {
+ if (logtab[readi].fmt == NULL)
+ continue;
+ line = buf;
+ buf += sprintf (buf, "%d\t", logtab[readi].cycles);
+ buf +=
+ sprintf (buf, logtab[readi].fmt, logtab[readi].a1, logtab[readi].a2);
+ buf += sprintf (buf, "\n");
+ }
+
+}
+
+
+/*
+ * Dump one log entry at a time.
+ * Return index of next entry or -1 when no more .
*/
+int
+bcmdumplogent (char *buf, uint i)
+{
+ bool hit;
+
+ /*
+ * If buf is NULL, return the starting index,
+ * interpreting i as the indicator of last 'i' entries to dump.
+ */
+ if (buf == NULL)
+ {
+ i = ((i > 0) && (i < (LOGSIZE - 1))) ? i : (LOGSIZE - 1);
+ return ((logi - i) % LOGSIZE);
+ }
+
+ *buf = '\0';
+
+ ASSERT (i < LOGSIZE);
+
+ if (i == logi)
+ return (-1);
+
+ hit = FALSE;
+ for (; (i != logi) && !hit; i = (i + 1) % LOGSIZE)
+ {
+ if (logtab[i].fmt == NULL)
+ continue;
+ buf += sprintf (buf, "%d: %d\t", i, logtab[i].cycles);
+ buf += sprintf (buf, logtab[i].fmt, logtab[i].a1, logtab[i].a2);
+ buf += sprintf (buf, "\n");
+ hit = TRUE;
+ }
+
+ return (i);
+}
+
+#endif /* BCMPERFSTATS */
+
+#ifdef BCMDBG
+/* pretty hex print a pkt buffer chain */
void
-pktsetprio(void *pkt, bool update_vtag)
+prpkt (const char *msg, osl_t * osh, void *p0)
{
- struct ether_header *eh;
- struct ethervlan_header *evh;
- uint8 *pktdata;
- int priority = 0;
+ void *p;
- pktdata = (uint8 *) PKTDATA(NULL, pkt);
- ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16)));
+ if (msg && (msg[0] != '\0'))
+ printf ("%s:\n", msg);
- eh = (struct ether_header *) pktdata;
+ for (p = p0; p; p = PKTNEXT (osh, p))
+ prhex (NULL, PKTDATA (osh, p), PKTLEN (osh, p));
+}
+#endif /* BCMDBG */
- if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) {
- uint16 vlan_tag;
- int vlan_prio, dscp_prio = 0;
+/* Takes an Ethernet frame and sets out-of-bound PKTPRIO.
+ * Also updates the inplace vlan tag if requested.
+ * For debugging, it returns an indication of what it did.
+ */
+uint
+pktsetprio (void *pkt, bool update_vtag)
+{
+ struct ether_header *eh;
+ struct ethervlan_header *evh;
+ uint8 *pktdata;
+ int priority = 0;
+ int rc = 0;
- evh = (struct ethervlan_header *)eh;
+ pktdata = (uint8 *) PKTDATA (NULL, pkt);
+ ASSERT (ISALIGNED ((uintptr) pktdata, sizeof (uint16)));
- vlan_tag = ntoh16(evh->vlan_tag);
- vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
+ eh = (struct ether_header *) pktdata;
- if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) {
- uint8 *ip_body = pktdata + sizeof(struct ethervlan_header);
- uint8 tos_tc = IP_TOS(ip_body);
- dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
- }
+ if (ntoh16 (eh->ether_type) == ETHER_TYPE_8021Q)
+ {
+ uint16 vlan_tag;
+ int vlan_prio, dscp_prio = 0;
+
+ evh = (struct ethervlan_header *) eh;
- /* DSCP priority gets precedence over 802.1P (vlan tag) */
- priority = (dscp_prio != 0) ? dscp_prio : vlan_prio;
-
- /*
- * If the DSCP priority is not the same as the VLAN priority,
- * then overwrite the priority field in the vlan tag, with the
- * DSCP priority value. This is required for Linux APs because
- * the VLAN driver on Linux, overwrites the skb->priority field
- * with the priority value in the vlan tag
- */
- if (update_vtag && (priority != vlan_prio)) {
- vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT);
- vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT;
- evh->vlan_tag = hton16(vlan_tag);
+ vlan_tag = ntoh16 (evh->vlan_tag);
+ vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
+
+ if (ntoh16 (evh->ether_type) == ETHER_TYPE_IP)
+ {
+ uint8 *ip_body = pktdata + sizeof (struct ethervlan_header);
+ uint8 tos_tc = IP_TOS (ip_body);
+ dscp_prio = (int) (tos_tc >> IPV4_TOS_PREC_SHIFT);
+ if ((IP_VER (ip_body) == IP_VER_4)
+ && (IPV4_PROT (ip_body) == IP_PROT_TCP))
+ {
+ int ip_len;
+ int src_port;
+ bool src_port_exc;
+ uint8 *tcp_hdr;
+
+ ip_len = IPV4_PAYLOAD_LEN (ip_body);
+ tcp_hdr = IPV4_NO_OPTIONS_PAYLOAD (ip_body);
+ src_port = TCP_SRC_PORT (tcp_hdr);
+ src_port_exc = (src_port == 10110) || (src_port == 10120) ||
+ (src_port == 10130) || (src_port == 10140);
+
+ if ((ip_len == 40) && src_port_exc && TCP_IS_ACK (tcp_hdr))
+ {
+ dscp_prio = 7;
}
- } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) {
- uint8 *ip_body = pktdata + sizeof(struct ether_header);
- uint8 tos_tc = IP_TOS(ip_body);
- priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
+ }
}
- ASSERT(priority >= 0 && priority <= MAXPRIO);
- PKTSETPRIO(pkt, priority);
+ /* DSCP priority gets precedence over 802.1P (vlan tag) */
+ if (dscp_prio != 0)
+ {
+ priority = dscp_prio;
+ rc |= PKTPRIO_VDSCP;
+ }
+ else
+ {
+ priority = vlan_prio;
+ rc |= PKTPRIO_VLAN;
+ }
+ /*
+ * If the DSCP priority is not the same as the VLAN priority,
+ * then overwrite the priority field in the vlan tag, with the
+ * DSCP priority value. This is required for Linux APs because
+ * the VLAN driver on Linux, overwrites the skb->priority field
+ * with the priority value in the vlan tag
+ */
+ if (update_vtag && (priority != vlan_prio))
+ {
+ vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT);
+ vlan_tag |= (uint16) priority << VLAN_PRI_SHIFT;
+ evh->vlan_tag = hton16 (vlan_tag);
+ rc |= PKTPRIO_UPD;
+ }
+ }
+ else if (ntoh16 (eh->ether_type) == ETHER_TYPE_IP)
+ {
+ uint8 *ip_body = pktdata + sizeof (struct ether_header);
+ uint8 tos_tc = IP_TOS (ip_body);
+ priority = (int) (tos_tc >> IPV4_TOS_PREC_SHIFT);
+ rc |= PKTPRIO_DSCP;
+ if ((IP_VER (ip_body) == IP_VER_4)
+ && (IPV4_PROT (ip_body) == IP_PROT_TCP))
+ {
+ int ip_len;
+ int src_port;
+ bool src_port_exc;
+ uint8 *tcp_hdr;
+
+ ip_len = IPV4_PAYLOAD_LEN (ip_body);
+ tcp_hdr = IPV4_NO_OPTIONS_PAYLOAD (ip_body);
+ src_port = TCP_SRC_PORT (tcp_hdr);
+ src_port_exc = (src_port == 10110) || (src_port == 10120) ||
+ (src_port == 10130) || (src_port == 10140);
+
+ if ((ip_len == 40) && src_port_exc && TCP_IS_ACK (tcp_hdr))
+ {
+ priority = 7;
+ }
+ }
+ }
+
+ ASSERT (priority >= 0 && priority <= MAXPRIO);
+ PKTSETPRIO (pkt, priority);
+ return (rc | priority);
}
static char bcm_undeferrstr[BCME_STRLEN];
static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
-/* Convert the Error codes into related Error strings */
+/* Convert the error codes into related error strings */
const char *
-bcmerrorstr(int bcmerror)
+bcmerrorstr (int bcmerror)
+{
+ /* check if someone added a bcmerror code but forgot to add errorstring */
+ ASSERT (ABS (BCME_LAST) == (ARRAYSIZE (bcmerrorstrtable) - 1));
+
+ if (bcmerror > 0 || bcmerror < BCME_LAST)
+ {
+ snprintf (bcm_undeferrstr, BCME_STRLEN, "Undefined error %d", bcmerror);
+ return bcm_undeferrstr;
+ }
+
+ ASSERT (strlen (bcmerrorstrtable[-bcmerror]) < BCME_STRLEN);
+
+ return bcmerrorstrtable[-bcmerror];
+}
+
+#if 0
+static void BCMINITFN (bcm_nvram_refresh) (char *flash)
{
- int abs_bcmerror;
+ int i;
+ int ret = 0;
+
+ ASSERT (flash);
+
+ /* default "empty" vars cache */
+ bzero (flash, 2);
+
+ if ((ret = nvram_getall (flash, NVRAM_SPACE)))
+ return;
+
+ /* determine nvram length */
+ for (i = 0; i < NVRAM_SPACE; i++)
+ {
+ if (flash[i] == '\0' && flash[i + 1] == '\0')
+ break;
+ }
- abs_bcmerror = ABS(bcmerror);
+ if (i > 1)
+ vars_len = i + 2;
+ else
+ vars_len = 0;
+}
+#endif
+
+#ifdef BCMDBG_PKT /* pkt logging for debugging */
+/* Add a packet to the pktlist */
+void
+pktlist_add (pktlist_info_t * pktlist, void *pkt)
+{
+ uint i;
+ ASSERT (pktlist->count < PKTLIST_SIZE);
+
+ /* Verify the packet is not already part of the list */
+ for (i = 0; i < pktlist->count; i++)
+ {
+ if (pktlist->list[i] == pkt)
+ ASSERT (0);
+ }
+ pktlist->list[pktlist->count] = pkt;
+ pktlist->count++;
+ return;
+}
- /* check if someone added a bcmerror code but forgot to add errorstring */
- ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1));
- if ((bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) {
- sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror);
- return bcm_undeferrstr;
+/* Remove a packet from the pktlist */
+void
+pktlist_remove (pktlist_info_t * pktlist, void *pkt)
+{
+ uint i;
+ uint num = pktlist->count;
+
+ /* find the index where pkt exists */
+ for (i = 0; i < num; i++)
+ {
+ /* check for the existence of pkt in the list */
+ if (pktlist->list[i] == pkt)
+ {
+ /* replace with the last element */
+ pktlist->list[i] = pktlist->list[num - 1];
+ pktlist->count--;
+ return;
}
+ }
+ ASSERT (0);
+}
+
+/* Dump the pktlist (and the contents of each packet if 'data'
+ * is set). 'buf' should be large enough
+ */
+
+char *
+pktlist_dump (pktlist_info_t * pktlist, char *buf)
+{
+ char *obuf;
+ uint i;
+
+ obuf = buf;
+
+ buf += sprintf (buf, "Packet list dump:\n");
- ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN);
+ for (i = 0; i < (pktlist->count); i++)
+ {
+ buf += sprintf (buf, "0x%p\t", pktlist->list[i]);
- return bcmerrorstrtable[abs_bcmerror];
+#ifdef NOTDEF /* Remove this ifdef to print pkttag and pktdata */
+ if (PKTTAG (pktlist->list[i]))
+ {
+ /* Print pkttag */
+ buf += sprintf (buf, "Pkttag(in hex): ");
+ buf +=
+ bcm_format_hex (buf, PKTTAG (pktlist->list[i]), OSL_PKTTAG_SZ);
+ }
+ buf += sprintf (buf, "Pktdata(in hex): ");
+ buf += bcm_format_hex (buf, PKTDATA (NULL, pktlist->list[i]),
+ PKTLEN (NULL, pktlist->list[i]));
+#endif /* NOTDEF */
+
+ buf += sprintf (buf, "\n");
+ }
+ return obuf;
}
+#endif /* BCMDBG_PKT */
+#if 0
+/* iovar table lookup */
+const bcm_iovar_t *
+bcm_iovar_lookup (const bcm_iovar_t * table, const char *name)
+{
+ const bcm_iovar_t *vi;
+ const char *lookup_name;
+
+ /* skip any ':' delimited option prefixes */
+ lookup_name = strrchr (name, ':');
+ if (lookup_name != NULL)
+ lookup_name++;
+ else
+ lookup_name = name;
+
+ ASSERT (table);
+
+ for (vi = table; vi->name; vi++)
+ {
+ if (!strcmp (vi->name, lookup_name))
+ return vi;
+ }
+ /* ran to end of table */
+
+ return NULL; /* var name not found */
+}
+#endif
int
-bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
-{
- int bcmerror = 0;
-
- /* length check on io buf */
- switch (vi->type) {
- case IOVT_BOOL:
- case IOVT_INT8:
- case IOVT_INT16:
- case IOVT_INT32:
- case IOVT_UINT8:
- case IOVT_UINT16:
- case IOVT_UINT32:
- /* all integers are int32 sized args at the ioctl interface */
- if (len < (int)sizeof(int)) {
- bcmerror = BCME_BUFTOOSHORT;
- }
- break;
+bcm_iovar_lencheck (const bcm_iovar_t * vi, void *arg, int len, bool set)
+{
+ int bcmerror = 0;
+
+ /* length check on io buf */
+ switch (vi->type)
+ {
+ case IOVT_BOOL:
+ case IOVT_INT8:
+ case IOVT_INT16:
+ case IOVT_INT32:
+ case IOVT_UINT8:
+ case IOVT_UINT16:
+ case IOVT_UINT32:
+ /* all integers are int32 sized args at the ioctl interface */
+ if (len < (int) sizeof (int))
+ {
+ bcmerror = BCME_BUFTOOSHORT;
+ }
+ break;
- case IOVT_BUFFER:
- /* buffer must meet minimum length requirement */
- if (len < vi->minlen) {
- bcmerror = BCME_BUFTOOSHORT;
- }
- break;
-
- case IOVT_VOID:
- if (!set) {
- /* Cannot return nil... */
- bcmerror = BCME_UNSUPPORTED;
- } else if (len) {
- /* Set is an action w/o parameters */
- bcmerror = BCME_BUFTOOLONG;
- }
- break;
+ case IOVT_BUFFER:
+ /* buffer must meet minimum length requirement */
+ if (len < vi->minlen)
+ {
+ bcmerror = BCME_BUFTOOSHORT;
+ }
+ break;
- default:
- /* unknown type for length check in iovar info */
- ASSERT(0);
- bcmerror = BCME_UNSUPPORTED;
+ case IOVT_VOID:
+ if (!set)
+ {
+ /* Cannot return nil... */
+ bcmerror = BCME_UNSUPPORTED;
+ }
+ else if (len)
+ {
+ /* Set is an action w/o parameters */
+ bcmerror = BCME_BUFTOOLONG;
}
+ break;
+
+ default:
+ /* unknown type for length check in iovar info */
+ ASSERT (0);
+ bcmerror = BCME_UNSUPPORTED;
+ }
- return bcmerror;
+ return bcmerror;
}
#define CRC_INNER_LOOP(n, c, x) \
- (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
-
-static uint32 crc32_table[256] = {
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
- 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
- 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
- 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
- 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
- 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
- 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
- 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
- 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
- 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
- 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
- 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
- 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
- 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
- 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
- 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
- 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
- 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
- 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
- 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
- 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
- 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
- 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
- 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
- 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
- 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
- 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
- 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
- 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
- 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
- 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
- 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
- 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
- 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
- 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
- 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
- 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
- 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
- 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
- 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
- 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
- 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
- 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
- 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
- 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
- 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
- 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
- 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
- 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
- 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
+
+#if 0
+/*******************************************************************************
+ * crc8
+ *
+ * Computes a crc8 over the input data using the polynomial:
+ *
+ * x^8 + x^7 +x^6 + x^4 + x^2 + 1
+ *
+ * The caller provides the initial value (either CRC8_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data. When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream. When checking, a final
+ * return value of CRC8_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint8 crc8_table[256] = {
+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
};
-uint32
-hndcrc32(
- uint8 *pdata, /* pointer to array of data to process */
- uint nbytes, /* number of input data bytes to process */
- uint32 crc /* either CRC32_INIT_VALUE or previous return value */
-)
+uint8 BCMROMFN (hndcrc8) (uint8 * pdata, /* pointer to array of data to process */
+ uint nbytes, /* number of input data bytes to process */
+ uint8 crc /* either CRC8_INIT_VALUE or previous return value */
+ )
{
- uint8 *pend;
-#ifdef __mips__
- uint8 tmp[4];
- ulong *tptr = (ulong *)tmp;
-
- /* in case the beginning of the buffer isn't aligned */
- pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc);
- nbytes -= (pend - pdata);
- while (pdata < pend)
- CRC_INNER_LOOP(32, crc, *pdata++);
-
- /* handle bulk of data as 32-bit words */
- pend = pdata + (nbytes & 0xfffffffc);
- while (pdata < pend) {
- *tptr = *(ulong *)pdata;
- pdata += sizeof(ulong *);
- CRC_INNER_LOOP(32, crc, tmp[0]);
- CRC_INNER_LOOP(32, crc, tmp[1]);
- CRC_INNER_LOOP(32, crc, tmp[2]);
- CRC_INNER_LOOP(32, crc, tmp[3]);
- }
+ /* hard code the crc loop instead of using CRC_INNER_LOOP macro
+ * to avoid the undefined and unnecessary (uint8 >> 8) operation.
+ */
+ while (nbytes-- > 0)
+ crc = crc8_table[(crc ^ *pdata++) & 0xff];
+
+ return crc;
+}
- /* 1-3 bytes at end of buffer */
- pend = pdata + (nbytes & 0x03);
- while (pdata < pend)
- CRC_INNER_LOOP(32, crc, *pdata++);
+/*******************************************************************************
+ * crc16
+ *
+ * Computes a crc16 over the input data using the polynomial:
+ *
+ * x^16 + x^12 +x^5 + 1
+ *
+ * The caller provides the initial value (either CRC16_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data. When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream. When checking, a final
+ * return value of CRC16_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+static const uint16 crc16_table[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
+ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
+ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
+ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
+ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
+ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
+ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
+ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
+ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
+ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
+ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
+ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
+ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
+ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
+ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
+ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
+ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
+ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
+ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
+ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
+ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
+ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
+ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
+ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
+ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
+ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
+ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
+ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
+ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
+ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
+ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
+ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
+};
+
+uint16 BCMROMFN (hndcrc16) (uint8 * pdata, /* pointer to array of data to process */
+ uint nbytes, /* number of input data bytes to process */
+ uint16 crc /* either CRC16_INIT_VALUE or previous return value */
+ )
+{
+ while (nbytes-- > 0)
+ CRC_INNER_LOOP (16, crc, *pdata++);
+ return crc;
+}
+#endif
+
+static const uint32 crc32_table[256] = {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+};
+
+uint32 BCMROMFN (hndcrc32) (uint8 * pdata, /* pointer to array of data to process */
+ uint nbytes, /* number of input data bytes to process */
+ uint32 crc /* either CRC32_INIT_VALUE or previous return value */
+ )
+{
+ uint8 *pend;
+#ifdef __mips__
+ uint8 tmp[4];
+ ulong *tptr = (ulong *) tmp;
+
+ /* in case the beginning of the buffer isn't aligned */
+ pend = (uint8 *) ((uint) (pdata + 3) & 0xfffffffc);
+ nbytes -= (pend - pdata);
+ while (pdata < pend)
+ CRC_INNER_LOOP (32, crc, *pdata++);
+
+ /* handle bulk of data as 32-bit words */
+ pend = pdata + (nbytes & 0xfffffffc);
+ while (pdata < pend)
+ {
+ *tptr = *(ulong *) pdata;
+ pdata += sizeof (ulong *);
+ CRC_INNER_LOOP (32, crc, tmp[0]);
+ CRC_INNER_LOOP (32, crc, tmp[1]);
+ CRC_INNER_LOOP (32, crc, tmp[2]);
+ CRC_INNER_LOOP (32, crc, tmp[3]);
+ }
+
+ /* 1-3 bytes at end of buffer */
+ pend = pdata + (nbytes & 0x03);
+ while (pdata < pend)
+ CRC_INNER_LOOP (32, crc, *pdata++);
#else
- pend = pdata + nbytes;
- while (pdata < pend)
- CRC_INNER_LOOP(32, crc, *pdata++);
+ pend = pdata + nbytes;
+ while (pdata < pend)
+ CRC_INNER_LOOP (32, crc, *pdata++);
#endif /* __mips__ */
- return crc;
+ return crc;
}
+#ifdef notdef
+#define CLEN 1499 /* CRC Length */
+#define CBUFSIZ (CLEN+4)
+#define CNBUFS 5 /* # of bufs */
+
+void
+testcrc32 (void)
+{
+ uint j, k, l;
+ uint8 *buf;
+ uint len[CNBUFS];
+ uint32 crcr;
+ uint32 crc32tv[CNBUFS] =
+ { 0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110 };
+
+ ASSERT ((buf = MALLOC (CBUFSIZ * CNBUFS)) != NULL);
+
+ /* step through all possible alignments */
+ for (l = 0; l <= 4; l++)
+ {
+ for (j = 0; j < CNBUFS; j++)
+ {
+ len[j] = CLEN;
+ for (k = 0; k < len[j]; k++)
+ *(buf + j * CBUFSIZ + (k + l)) = (j + k) & 0xff;
+ }
+
+ for (j = 0; j < CNBUFS; j++)
+ {
+ crcr = crc32 (buf + j * CBUFSIZ + l, len[j], CRC32_INIT_VALUE);
+ ASSERT (crcr == crc32tv[j]);
+ }
+ }
+
+ MFREE (buf, CBUFSIZ * CNBUFS);
+ return;
+}
+#endif /* notdef */
/*
* Advance from the current 1-byte tag/1-byte length/variable-length value
@@ -732,27 +1592,26 @@ hndcrc32(
* If the current or next TLV is invalid (does not fit in given buffer length),
* NULL is returned.
* *buflen is not modified if the TLV elt parameter is invalid, or is decremented
- * by the TLV paramter's length if it is valid.
+ * by the TLV parameter's length if it is valid.
*/
-bcm_tlv_t *
-bcm_next_tlv(bcm_tlv_t *elt, int *buflen)
+bcm_tlv_t *BCMROMFN (bcm_next_tlv) (bcm_tlv_t * elt, int *buflen)
{
- int len;
+ int len;
- /* validate current elt */
- if (!bcm_valid_tlv(elt, *buflen))
- return NULL;
+ /* validate current elt */
+ if (!bcm_valid_tlv (elt, *buflen))
+ return NULL;
- /* advance to next elt */
- len = elt->len;
- elt = (bcm_tlv_t*)(elt->data + len);
- *buflen -= (2 + len);
+ /* advance to next elt */
+ len = elt->len;
+ elt = (bcm_tlv_t *) (elt->data + len);
+ *buflen -= (2 + len);
- /* validate next elt */
- if (!bcm_valid_tlv(elt, *buflen))
- return NULL;
+ /* validate next elt */
+ if (!bcm_valid_tlv (elt, *buflen))
+ return NULL;
- return elt;
+ return elt;
}
/*
@@ -760,114 +1619,417 @@ bcm_next_tlv(bcm_tlv_t *elt, int *buflen)
* triples, returning a pointer to the substring whose first element
* matches tag
*/
-bcm_tlv_t *
-bcm_parse_tlvs(void *buf, int buflen, uint key)
+bcm_tlv_t *BCMROMFN (bcm_parse_tlvs) (void *buf, int buflen, uint key)
{
- bcm_tlv_t *elt;
- int totlen;
+ bcm_tlv_t *elt;
+ int totlen;
- elt = (bcm_tlv_t*)buf;
- totlen = buflen;
+ elt = (bcm_tlv_t *) buf;
+ totlen = buflen;
- /* find tagged parameter */
- while (totlen >= 2) {
- int len = elt->len;
+ /* find tagged parameter */
+ while (totlen >= 2)
+ {
+ int len = elt->len;
- /* validate remaining totlen */
- if ((elt->id == key) && (totlen >= (len + 2)))
- return (elt);
+ /* validate remaining totlen */
+ if ((elt->id == key) && (totlen >= (len + 2)))
+ return (elt);
- elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
- totlen -= (len + 2);
- }
+ elt = (bcm_tlv_t *) ((uint8 *) elt + (len + 2));
+ totlen -= (len + 2);
+ }
- return NULL;
+ return NULL;
}
+#if 0
/*
* Traverse a string of 1-byte tag/1-byte length/variable-length value
* triples, returning a pointer to the substring whose first element
* matches tag. Stop parsing when we see an element whose ID is greater
* than the target key.
*/
-bcm_tlv_t *
-bcm_parse_ordered_tlvs(void *buf, int buflen, uint key)
+bcm_tlv_t *BCMROMFN (bcm_parse_ordered_tlvs) (void *buf, int buflen, uint key)
{
- bcm_tlv_t *elt;
- int totlen;
+ bcm_tlv_t *elt;
+ int totlen;
+
+ elt = (bcm_tlv_t *) buf;
+ totlen = buflen;
+
+ /* find tagged parameter */
+ while (totlen >= 2)
+ {
+ uint id = elt->id;
+ int len = elt->len;
+
+ /* Punt if we start seeing IDs > than target key */
+ if (id > key)
+ return (NULL);
+
+ /* validate remaining totlen */
+ if ((id == key) && (totlen >= (len + 2)))
+ return (elt);
+
+ elt = (bcm_tlv_t *) ((uint8 *) elt + (len + 2));
+ totlen -= (len + 2);
+ }
+ return NULL;
+}
- elt = (bcm_tlv_t*)buf;
- totlen = buflen;
+#ifdef BCMDBG
+int
+bcm_format_flags (const bcm_bit_desc_t * bd, uint32 flags, char *buf, int len)
+{
+ int i;
+ char *p = buf;
+ char hexstr[16];
+ int slen = 0;
+ uint32 bit;
+ const char *name;
+
+ if (len < 2 || !buf)
+ return 0;
+
+ buf[0] = '\0';
+ len -= 1;
+
+ for (i = 0; flags != 0; i++)
+ {
+ bit = bd[i].bit;
+ name = bd[i].name;
+ if (bit == 0 && flags)
+ {
+ /* print any unnamed bits */
+ sprintf (hexstr, "0x%X", flags);
+ name = hexstr;
+ flags = 0; /* exit loop */
+ }
+ else if ((flags & bit) == 0)
+ continue;
+ slen += strlen (name);
+ if (len < slen)
+ break;
+ if (p != buf)
+ p += sprintf (p, " "); /* btwn flag space */
+ strcat (p, name);
+ p += strlen (name);
+ flags &= ~bit;
+ len -= slen;
+ slen = 1; /* account for btwn flag space */
+ }
+
+ /* indicate the str was too short */
+ if (flags != 0)
+ {
+ if (len == 0)
+ p--; /* overwrite last char */
+ p += sprintf (p, ">");
+ }
+
+ return (int) (p - buf);
+}
- /* find tagged parameter */
- while (totlen >= 2) {
- uint id = elt->id;
- int len = elt->len;
+void
+deadbeef (void *p, uint len)
+{
+ static uint8 meat[] = { 0xde, 0xad, 0xbe, 0xef };
- /* Punt if we start seeing IDs > than target key */
- if (id > key)
- return (NULL);
+ while (len-- > 0)
+ {
+ *(uint8 *) p = meat[((uintptr) p) & 3];
+ p = (uint8 *) p + 1;
+ }
+}
- /* validate remaining totlen */
- if ((id == key) && (totlen >= (len + 2)))
- return (elt);
+/* pretty hex print a contiguous buffer */
+void
+prhex (const char *msg, uchar * buf, uint nbytes)
+{
+ char line[128], *p;
+ uint i;
- elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
- totlen -= (len + 2);
+ if (msg && (msg[0] != '\0'))
+ printf ("%s:\n", msg);
+
+ p = line;
+ for (i = 0; i < nbytes; i++)
+ {
+ if (i % 16 == 0)
+ {
+ p += sprintf (p, " %04d: ", i); /* line prefix */
}
- return NULL;
+ p += sprintf (p, "%02x ", buf[i]);
+ if (i % 16 == 15)
+ {
+ printf ("%s\n", line); /* flush line */
+ p = line;
+ }
+ }
+
+ /* flush last partial line */
+ if (p != line)
+ printf ("%s\n", line);
+}
+
+/* print bytes formatted as hex to a string. return the resulting string length */
+int
+bcm_format_hex (char *str, const void *bytes, int len)
+{
+ int i;
+ char *p = str;
+ const uint8 *src = (const uint8 *) bytes;
+
+ for (i = 0; i < len; i++)
+ {
+ p += sprintf (p, "%02X", *src);
+ src++;
+ }
+ return (int) (p - str);
}
+#endif /* BCMDBG */
-/* Initialization of bcmstrbuf structure */
+/* Produce a human-readable string for boardrev */
+char *
+bcm_brev_str (uint16 brev, char *buf)
+{
+ if (brev < 0x100)
+ snprintf (buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf);
+ else
+ snprintf (buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A',
+ brev & 0xfff);
+
+ return (buf);
+}
+
+#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */
+
+/* dump large strings to console */
void
-bcm_binit(struct bcmstrbuf *b, char *buf, uint size)
+printfbig (char *buf)
{
- b->origsize = b->size = size;
- b->origbuf = b->buf = buf;
+ uint len, max_len;
+ char c;
+
+ len = strlen (buf);
+
+ max_len = BUFSIZE_TODUMP_ATONCE;
+
+ while (len > max_len)
+ {
+ c = buf[max_len];
+ buf[max_len] = '\0';
+ printf ("%s", buf);
+ buf[max_len] = c;
+
+ buf += max_len;
+ len -= max_len;
+ }
+ /* print the remaining string */
+ printf ("%s\n", buf);
+ return;
}
-/* Buffer sprintf wrapper to guard against buffer overflow */
-int
-bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
+/* routine to dump fields in a fileddesc structure */
+uint
+bcmdumpfields (readreg_rtn read_rtn, void *arg0, void *arg1,
+ struct fielddesc * fielddesc_array, char *buf, uint32 bufsize)
+{
+ uint filled_len;
+ int len;
+ struct fielddesc *cur_ptr;
+
+ filled_len = 0;
+ cur_ptr = fielddesc_array;
+
+ while (bufsize > 1)
+ {
+ if (cur_ptr->nameandfmt == NULL)
+ break;
+ len = snprintf (buf, bufsize, cur_ptr->nameandfmt,
+ read_rtn (arg0, arg1, cur_ptr->offset));
+ /* check for snprintf overflow or error */
+ if (len < 0 || (uint32) len >= bufsize)
+ len = bufsize - 1;
+ buf += len;
+ bufsize -= len;
+ filled_len += len;
+ cur_ptr++;
+ }
+ return filled_len;
+}
+#endif
+
+uint
+bcm_mkiovar (char *name, char *data, uint datalen, char *buf, uint buflen)
{
- va_list ap;
- int r;
+ uint len;
- va_start(ap, fmt);
- r = vsnprintf(b->buf, b->size, fmt, ap);
+ len = strlen (name) + 1;
- /* Non Ansi C99 compliant returns -1,
- * Ansi compliant return r >= b->size,
- * bcmstdlib returns 0, handle all
- */
- if ((r == -1) || (r >= (int)b->size) || (r == 0))
- {
- b->size = 0;
- }
- else
+ if ((len + datalen) > buflen)
+ return 0;
+
+ strncpy (buf, name, buflen);
+
+ /* append data onto the end of the name string */
+ memcpy (&buf[len], data, datalen);
+ len += datalen;
+
+ return len;
+}
+
+/* Quarter dBm units to mW
+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+ * Table is offset so the last entry is largest mW value that fits in
+ * a uint16.
+ */
+
+#define QDBM_OFFSET 153 /* Offset for first entry */
+#define QDBM_TABLE_LEN 40 /* Table size */
+
+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+ */
+#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
+
+/* Largest mW value that will round down to the last table entry,
+ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+ */
+#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
+
+static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
+};
+
+uint16 BCMROMFN (bcm_qdbm_to_mw) (uint8 qdbm)
+{
+ uint factor = 1;
+ int idx = qdbm - QDBM_OFFSET;
+
+ if (idx > QDBM_TABLE_LEN)
+ {
+ /* clamp to max uint16 mW value */
+ return 0xFFFF;
+ }
+
+ /* scale the qdBm index up to the range of the table 0-40
+ * where an offset of 40 qdBm equals a factor of 10 mW.
+ */
+ while (idx < 0)
+ {
+ idx += 40;
+ factor *= 10;
+ }
+
+ /* return the mW value scaled down to the correct factor of 10,
+ * adding in factor/2 to get proper rounding.
+ */
+ return ((nqdBm_to_mW_map[idx] + factor / 2) / factor);
+}
+
+uint8 BCMROMFN (bcm_mw_to_qdbm) (uint16 mw)
+{
+ uint8 qdbm;
+ int offset;
+ uint mw_uint = mw;
+ uint boundary;
+
+ /* handle boundary case */
+ if (mw_uint <= 1)
+ return 0;
+
+ offset = QDBM_OFFSET;
+
+ /* move mw into the range of the table */
+ while (mw_uint < QDBM_TABLE_LOW_BOUND)
+ {
+ mw_uint *= 10;
+ offset -= 40;
+ }
+
+ for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++)
+ {
+ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
+ nqdBm_to_mW_map[qdbm]) / 2;
+ if (mw_uint < boundary)
+ break;
+ }
+
+ qdbm += (uint8) offset;
+
+ return (qdbm);
+}
+
+
+uint BCMROMFN (bcm_bitcount) (uint8 * bitmap, uint length)
+{
+ uint bitcount = 0, i;
+ uint8 tmp;
+ for (i = 0; i < length; i++)
+ {
+ tmp = bitmap[i];
+ while (tmp)
{
- b->size -= r;
- b->buf += r;
+ bitcount++;
+ tmp &= (tmp - 1);
}
+ }
+ return bitcount;
+}
- va_end(ap);
- return r;
+/* Initialization of bcmstrbuf structure */
+void
+bcm_binit (struct bcmstrbuf *b, char *buf, uint size)
+{
+ b->origsize = b->size = size;
+ b->origbuf = b->buf = buf;
}
-uint
-bcm_bitcount(uint8 *bitmap, uint length)
-{
- uint bitcount = 0, i;
- uint8 tmp;
- for (i = 0; i < length; i++) {
- tmp = bitmap[i];
- while (tmp) {
- bitcount++;
- tmp &= (tmp - 1);
- }
- }
- return bitcount;
+/* Buffer sprintf wrapper to guard against buffer overflow */
+int
+bcm_bprintf (struct bcmstrbuf *b, const char *fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start (ap, fmt);
+ r = vsnprintf (b->buf, b->size, fmt, ap);
+
+ /* Non Ansi C99 compliant returns -1,
+ * Ansi compliant return r >= b->size,
+ * bcmstdlib returns 0, handle all
+ */
+ if ((r == -1) || (r >= (int) b->size) || (r == 0))
+ {
+ b->size = 0;
+ }
+ else
+ {
+ b->size -= r;
+ b->buf += r;
+ }
+
+ va_end (ap);
+
+ return r;
+}
+
+char *
+bcm_ether_ntoa (struct ether_addr *ea, char *buf)
+{
+ snprintf (buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+ ea->octet[0] & 0xff, ea->octet[1] & 0xff, ea->octet[2] & 0xff,
+ ea->octet[3] & 0xff, ea->octet[4] & 0xff, ea->octet[5] & 0xff);
+ return (buf);
}
diff --git a/package/broadcom-wl/src/driver/bcmutils.h b/package/broadcom-wl/src/driver/bcmutils.h
new file mode 100644
index 0000000000..9dcf08b726
--- /dev/null
+++ b/package/broadcom-wl/src/driver/bcmutils.h
@@ -0,0 +1,582 @@
+/*
+ * Misc useful os-independent macros and functions.
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ * $Id$
+ */
+
+#ifndef _bcmutils_h_
+#define _bcmutils_h_
+#include "linux_osl.h"
+
+/* ctype replacement */
+#define _BCM_U 0x01 /* upper */
+#define _BCM_L 0x02 /* lower */
+#define _BCM_D 0x04 /* digit */
+#define _BCM_C 0x08 /* cntrl */
+#define _BCM_P 0x10 /* punct */
+#define _BCM_S 0x20 /* white space (space/lf/tab) */
+#define _BCM_X 0x40 /* hex digit */
+#define _BCM_SP 0x80 /* hard space (0x20) */
+
+extern const unsigned char bcm_ctype[];
+#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
+
+#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
+#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
+#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
+#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
+#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
+#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
+#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
+#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
+#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
+#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
+#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
+#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
+#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c))
+
+/* Buffer structure for collecting string-formatted data
+* using bcm_bprintf() API.
+* Use bcm_binit() to initialize before use
+*/
+
+struct bcmstrbuf {
+ char *buf; /* pointer to current position in origbuf */
+ unsigned int size; /* current (residual) size in bytes */
+ char *origbuf; /* unmodified pointer to orignal buffer */
+ unsigned int origsize; /* unmodified orignal buffer size in bytes */
+};
+
+/* ** driver-only section ** */
+#include <osl.h>
+
+#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */
+
+
+/* osl multi-precedence packet queue */
+#ifndef PKTQ_LEN_DEFAULT
+#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
+#endif
+#ifndef PKTQ_MAX_PREC
+#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
+#endif
+
+typedef struct pktq_prec {
+ void *head; /* first packet to dequeue */
+ void *tail; /* last packet to dequeue */
+ uint16 len; /* number of queued packets */
+ uint16 max; /* maximum number of queued packets */
+} pktq_prec_t;
+
+
+/* multi-priority pkt queue */
+struct pktq {
+ uint16 num_prec; /* number of precedences in use */
+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
+ uint16 max; /* total max packets */
+ uint16 len; /* total number of packets */
+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
+ struct pktq_prec q[PKTQ_MAX_PREC];
+};
+
+/* simple, non-priority pkt queue */
+struct spktq {
+ uint16 num_prec; /* number of precedences in use (always 1) */
+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
+ uint16 max; /* total max packets */
+ uint16 len; /* total number of packets */
+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
+ struct pktq_prec q[1];
+};
+
+#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
+
+/* forward definition of ether_addr structure used by some function prototypes */
+struct ether_addr;
+
+/* operations on a specific precedence in packet queue */
+
+#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max))
+#define pktq_plen(pq, prec) ((pq)->q[prec].len)
+#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len)
+#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max)
+#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0)
+
+#define pktq_ppeek(pq, prec) ((pq)->q[prec].head)
+#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail)
+
+extern void *pktq_penq(struct pktq *pq, int prec, void *p);
+extern void *pktq_penq_head(struct pktq *pq, int prec, void *p);
+extern void *pktq_pdeq(struct pktq *pq, int prec);
+extern void *pktq_pdeq_tail(struct pktq *pq, int prec);
+/* Empty the queue at particular precedence level */
+extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir);
+/* Remove a specified packet from its queue */
+extern bool pktq_pdel(struct pktq *pq, void *p, int prec);
+
+/* operations on a set of precedences in packet queue */
+
+extern int pktq_mlen(struct pktq *pq, uint prec_bmp);
+extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out);
+
+/* operations on packet queue as a whole */
+
+#define pktq_len(pq) ((int)(pq)->len)
+#define pktq_max(pq) ((int)(pq)->max)
+#define pktq_avail(pq) ((int)((pq)->max - (pq)->len))
+#define pktq_full(pq) ((pq)->len >= (pq)->max)
+#define pktq_empty(pq) ((pq)->len == 0)
+
+/* operations for single precedence queues */
+#define pktenq(pq, p) pktq_penq(((struct pktq *)pq), 0, (p))
+#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)pq), 0, (p))
+#define pktdeq(pq) pktq_pdeq(((struct pktq *)pq), 0)
+#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)pq), 0)
+#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len)
+
+extern void pktq_init(struct pktq *pq, int num_prec, int max_len);
+/* prec_out may be NULL if caller is not interested in return value */
+extern void *pktq_deq(struct pktq *pq, int *prec_out);
+extern void *pktq_deq_tail(struct pktq *pq, int *prec_out);
+extern void *pktq_peek(struct pktq *pq, int *prec_out);
+extern void *pktq_peek_tail(struct pktq *pq, int *prec_out);
+extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); /* Empty the entire queue */
+extern int pktq_setmax(struct pktq *pq, int max_len);
+
+/* externs */
+/* packet */
+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
+extern uint pkttotlen(osl_t *osh, void *p);
+extern void *pktlast(osl_t *osh, void *p);
+
+/* Get priority from a packet and pass it back in scb (or equiv) */
+extern uint pktsetprio(void *pkt, bool update_vtag);
+#define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */
+#define PKTPRIO_VLAN 0x200 /* VLAN prio found */
+#define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */
+#define PKTPRIO_DSCP 0x800 /* DSCP prio found */
+
+/* string */
+extern int BCMROMFN(bcm_atoi)(char *s);
+extern ulong BCMROMFN(bcm_strtoul)(char *cp, char **endp, uint base);
+extern char *BCMROMFN(bcmstrstr)(char *haystack, char *needle);
+extern char *BCMROMFN(bcmstrcat)(char *dest, const char *src);
+extern char *BCMROMFN(bcmstrncat)(char *dest, const char *src, uint size);
+extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen);
+/* ethernet address */
+extern char *bcm_ether_ntoa(struct ether_addr *ea, char *buf);
+extern int BCMROMFN(bcm_ether_atoe)(char *p, struct ether_addr *ea);
+
+/* ip address */
+struct ipv4_addr;
+extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf);
+
+/* delay */
+extern void bcm_mdelay(uint ms);
+/* variable access */
+extern char *getvar(char *vars, const char *name);
+extern int getintvar(char *vars, const char *name);
+extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
+#ifdef BCMDBG
+extern void prpkt(const char *msg, osl_t *osh, void *p0);
+#endif /* BCMDBG */
+#ifdef BCMPERFSTATS
+extern void bcm_perf_enable(void);
+extern void bcmstats(char *fmt);
+extern void bcmlog(char *fmt, uint a1, uint a2);
+extern void bcmdumplog(char *buf, int size);
+extern int bcmdumplogent(char *buf, uint idx);
+#else
+#define bcm_perf_enable()
+#define bcmstats(fmt)
+#define bcmlog(fmt, a1, a2)
+#define bcmdumplog(buf, size) *buf = '\0'
+#define bcmdumplogent(buf, idx) -1
+#endif /* BCMPERFSTATS */
+extern char *bcm_nvram_vars(uint *length);
+extern int bcm_nvram_cache(void *sbh);
+
+/* Support for sharing code across in-driver iovar implementations.
+ * The intent is that a driver use this structure to map iovar names
+ * to its (private) iovar identifiers, and the lookup function to
+ * find the entry. Macros are provided to map ids and get/set actions
+ * into a single number space for a switch statement.
+ */
+
+/* iovar structure */
+typedef struct bcm_iovar {
+ const char *name; /* name for lookup and display */
+ uint16 varid; /* id for switch */
+ uint16 flags; /* driver-specific flag bits */
+ uint16 type; /* base type of argument */
+ uint16 minlen; /* min length for buffer vars */
+} bcm_iovar_t;
+
+/* varid definitions are per-driver, may use these get/set bits */
+
+/* IOVar action bits for id mapping */
+#define IOV_GET 0 /* Get an iovar */
+#define IOV_SET 1 /* Set an iovar */
+
+/* Varid to actionid mapping */
+#define IOV_GVAL(id) ((id)*2)
+#define IOV_SVAL(id) (((id)*2)+IOV_SET)
+#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET)
+
+/* flags are per-driver based on driver attributes */
+
+extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name);
+extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set);
+
+/* Base type definitions */
+#define IOVT_VOID 0 /* no value (implictly set only) */
+#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */
+#define IOVT_INT8 2 /* integer values are range-checked */
+#define IOVT_UINT8 3 /* unsigned int 8 bits */
+#define IOVT_INT16 4 /* int 16 bits */
+#define IOVT_UINT16 5 /* unsigned int 16 bits */
+#define IOVT_INT32 6 /* int 32 bits */
+#define IOVT_UINT32 7 /* unsigned int 32 bits */
+#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */
+#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER)
+
+/* Initializer for IOV type strings */
+#define BCM_IOV_TYPE_INIT { \
+ "void", \
+ "bool", \
+ "int8", \
+ "uint8", \
+ "int16", \
+ "uint16", \
+ "int32", \
+ "uint32", \
+ "buffer", \
+ "" }
+
+#define BCM_IOVT_IS_INT(type) (\
+ (type == IOVT_BOOL) || \
+ (type == IOVT_INT8) || \
+ (type == IOVT_UINT8) || \
+ (type == IOVT_INT16) || \
+ (type == IOVT_UINT16) || \
+ (type == IOVT_INT32) || \
+ (type == IOVT_UINT32))
+
+/* ** driver/apps-shared section ** */
+
+#define BCME_STRLEN 64 /* Max string length for BCM errors */
+#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST))
+
+
+/*
+ * error codes could be added but the defined ones shouldn't be changed/deleted
+ * these error codes are exposed to the user code
+ * when ever a new error code is added to this list
+ * please update errorstring table with the related error string and
+ * update osl files with os specific errorcode map
+*/
+
+#define BCME_OK 0 /* Success */
+#define BCME_ERROR -1 /* Error generic */
+#define BCME_BADARG -2 /* Bad Argument */
+#define BCME_BADOPTION -3 /* Bad option */
+#define BCME_NOTUP -4 /* Not up */
+#define BCME_NOTDOWN -5 /* Not down */
+#define BCME_NOTAP -6 /* Not AP */
+#define BCME_NOTSTA -7 /* Not STA */
+#define BCME_BADKEYIDX -8 /* BAD Key Index */
+#define BCME_RADIOOFF -9 /* Radio Off */
+#define BCME_NOTBANDLOCKED -10 /* Not band locked */
+#define BCME_NOCLK -11 /* No Clock */
+#define BCME_BADRATESET -12 /* BAD Rate valueset */
+#define BCME_BADBAND -13 /* BAD Band */
+#define BCME_BUFTOOSHORT -14 /* Buffer too short */
+#define BCME_BUFTOOLONG -15 /* Buffer too long */
+#define BCME_BUSY -16 /* Busy */
+#define BCME_NOTASSOCIATED -17 /* Not Associated */
+#define BCME_BADSSIDLEN -18 /* Bad SSID len */
+#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */
+#define BCME_BADCHAN -20 /* Bad Channel */
+#define BCME_BADADDR -21 /* Bad Address */
+#define BCME_NORESOURCE -22 /* Not Enough Resources */
+#define BCME_UNSUPPORTED -23 /* Unsupported */
+#define BCME_BADLEN -24 /* Bad length */
+#define BCME_NOTREADY -25 /* Not Ready */
+#define BCME_EPERM -26 /* Not Permitted */
+#define BCME_NOMEM -27 /* No Memory */
+#define BCME_ASSOCIATED -28 /* Associated */
+#define BCME_RANGE -29 /* Not In Range */
+#define BCME_NOTFOUND -30 /* Not Found */
+#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */
+#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */
+#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */
+#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */
+#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */
+#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */
+#define BCME_VERSION -37 /* Incorrect version */
+#define BCME_LAST BCME_VERSION
+
+/* These are collection of BCME Error strings */
+#define BCMERRSTRINGTABLE { \
+ "OK", \
+ "Undefined error", \
+ "Bad Argument", \
+ "Bad Option", \
+ "Not up", \
+ "Not down", \
+ "Not AP", \
+ "Not STA", \
+ "Bad Key Index", \
+ "Radio Off", \
+ "Not band locked", \
+ "No clock", \
+ "Bad Rate valueset", \
+ "Bad Band", \
+ "Buffer too short", \
+ "Buffer too long", \
+ "Busy", \
+ "Not Associated", \
+ "Bad SSID len", \
+ "Out of Range Channel", \
+ "Bad Channel", \
+ "Bad Address", \
+ "Not Enough Resources", \
+ "Unsupported", \
+ "Bad length", \
+ "Not Ready", \
+ "Not Permitted", \
+ "No Memory", \
+ "Associated", \
+ "Not In Range", \
+ "Not Found", \
+ "WME Not Enabled", \
+ "TSPEC Not Found", \
+ "ACM Not Supported", \
+ "Not WME Association", \
+ "SDIO Bus Error", \
+ "Dongle Not Accessible", \
+ "Incorrect version" \
+}
+
+#ifndef ABS
+#define ABS(a) (((a) < 0)?-(a):(a))
+#endif /* ABS */
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b))?(a):(b))
+#endif /* MIN */
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b))?(a):(b))
+#endif /* MAX */
+
+#define CEIL(x, y) (((x) + ((y)-1)) / (y))
+#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
+#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0)
+#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0)
+#define VALID_MASK(mask) !((mask) & ((mask) + 1))
+#ifndef OFFSETOF
+#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
+#endif /* OFFSETOF */
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
+#endif
+
+/* bit map related macros */
+#ifndef setbit
+#ifndef NBBY /* the BSD family defines NBBY */
+#define NBBY 8 /* 8 bits per byte */
+#endif /* #ifndef NBBY */
+#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a, i) (((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a, i) ((((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+#endif /* setbit */
+
+#define NBITS(type) (sizeof(type) * 8)
+#define NBITVAL(nbits) (1 << (nbits))
+#define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
+#define NBITMASK(nbits) MAXBITVAL(nbits)
+#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
+
+/* basic mux operation - can be optimized on several architectures */
+#define MUX(pred, true, false) ((pred) ? (true) : (false))
+
+/* modulo inc/dec - assumes x E [0, bound - 1] */
+#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
+#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
+
+/* modulo inc/dec, bound = 2^k */
+#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
+#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
+
+/* modulo add/sub - assumes x, y E [0, bound - 1] */
+#define MODADD(x, y, bound) \
+ MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
+#define MODSUB(x, y, bound) \
+ MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
+
+/* module add/sub, bound = 2^k */
+#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
+#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
+
+/* crc defines */
+#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
+#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
+#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
+#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
+
+/* bcm_format_flags() bit description structure */
+typedef struct bcm_bit_desc {
+ uint32 bit;
+ const char* name;
+} bcm_bit_desc_t;
+
+/* tag_ID/length/value_buffer tuple */
+typedef struct bcm_tlv {
+ uint8 id;
+ uint8 len;
+ uint8 data[1];
+} bcm_tlv_t;
+
+/* Check that bcm_tlv_t fits into the given buflen */
+#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
+
+/* buffer length for ethernet address from bcm_ether_ntoa() */
+#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */
+
+/* unaligned load and store macros */
+#ifdef IL_BIGENDIAN
+static INLINE uint32
+load32_ua(uint8 *a)
+{
+ return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]);
+}
+
+static INLINE void
+store32_ua(uint8 *a, uint32 v)
+{
+ a[0] = (v >> 24) & 0xff;
+ a[1] = (v >> 16) & 0xff;
+ a[2] = (v >> 8) & 0xff;
+ a[3] = v & 0xff;
+}
+
+static INLINE uint16
+load16_ua(uint8 *a)
+{
+ return ((a[0] << 8) | a[1]);
+}
+
+static INLINE void
+store16_ua(uint8 *a, uint16 v)
+{
+ a[0] = (v >> 8) & 0xff;
+ a[1] = v & 0xff;
+}
+
+#else /* IL_BIGENDIAN */
+
+static INLINE uint32
+load32_ua(uint8 *a)
+{
+ return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
+}
+
+static INLINE void
+store32_ua(uint8 *a, uint32 v)
+{
+ a[3] = (v >> 24) & 0xff;
+ a[2] = (v >> 16) & 0xff;
+ a[1] = (v >> 8) & 0xff;
+ a[0] = v & 0xff;
+}
+
+static INLINE uint16
+load16_ua(uint8 *a)
+{
+ return ((a[1] << 8) | a[0]);
+}
+
+static INLINE void
+store16_ua(uint8 *a, uint16 v)
+{
+ a[1] = (v >> 8) & 0xff;
+ a[0] = v & 0xff;
+}
+
+#endif /* IL_BIGENDIAN */
+
+/* externs */
+/* crc */
+extern uint8 BCMROMFN(hndcrc8)(uint8 *p, uint nbytes, uint8 crc);
+extern uint16 BCMROMFN(hndcrc16)(uint8 *p, uint nbytes, uint16 crc);
+extern uint32 BCMROMFN(hndcrc32)(uint8 *p, uint nbytes, uint32 crc);
+/* format/print */
+#ifdef BCMDBG
+extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len);
+extern int bcm_format_hex(char *str, const void *bytes, int len);
+extern void deadbeef(void *p, uint len);
+extern void prhex(const char *msg, uchar *buf, uint len);
+#endif /* BCMDBG */
+extern char *bcm_brev_str(uint16 brev, char *buf);
+extern void printfbig(char *buf);
+
+/* IE parsing */
+extern bcm_tlv_t *BCMROMFN(bcm_next_tlv)(bcm_tlv_t *elt, int *buflen);
+extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key);
+extern bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs)(void *buf, int buflen, uint key);
+
+/* bcmerror */
+extern const char *bcmerrorstr(int bcmerror);
+
+/* multi-bool data type: set of bools, mbool is true if any is set */
+typedef uint32 mbool;
+#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */
+#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */
+#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* TRUE if one bool is set */
+#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
+
+/* power conversion */
+extern uint16 BCMROMFN(bcm_qdbm_to_mw)(uint8 qdbm);
+extern uint8 BCMROMFN(bcm_mw_to_qdbm)(uint16 mw);
+
+/* generic datastruct to help dump routines */
+struct fielddesc {
+ const char *nameandfmt;
+ uint32 offset;
+ uint32 len;
+};
+
+extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
+extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
+
+typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset);
+extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str,
+ char *buf, uint32 bufsize);
+
+extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
+extern uint BCMROMFN(bcm_bitcount)(uint8 *bitmap, uint bytelength);
+
+#ifdef BCMDBG_PKT /* pkt logging for debugging */
+#define PKTLIST_SIZE 1000
+typedef struct {
+ void *list[PKTLIST_SIZE]; /* List of pointers to packets */
+ uint count; /* Total count of the packets */
+} pktlist_info_t;
+
+extern void pktlist_add(pktlist_info_t *pktlist, void *p);
+extern void pktlist_remove(pktlist_info_t *pktlist, void *p);
+extern char* pktlist_dump(pktlist_info_t *pktlist, char *buf);
+#endif /* BCMDBG_PKT */
+
+#endif /* _bcmutils_h_ */
diff --git a/package/broadcom-wl/src/driver/hnddma.c b/package/broadcom-wl/src/driver/hnddma.c
index 1b79dff4c2..c6f6a13ed7 100644
--- a/package/broadcom-wl/src/driver/hnddma.c
+++ b/package/broadcom-wl/src/driver/hnddma.c
@@ -2,7 +2,7 @@
* Generic Broadcom Home Networking Division (HND) DMA module.
* This supports the following chips: BCM42xx, 44xx, 47xx .
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -10,7 +10,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: hnddma.c,v 1.11 2006/04/08 07:12:42 honor Exp $
+ * $Id$
*/
#include <typedefs.h>
@@ -19,7 +19,7 @@
#include "linux_osl.h"
#include <bcmendian.h>
#include <sbconfig.h>
-#include <bcmutils.h>
+#include "bcmutils.h"
#include <bcmdevs.h>
#include <sbutils.h>
@@ -27,71 +27,77 @@
#include "hnddma.h"
/* debug/trace */
+#ifdef BCMDBG
+#define DMA_ERROR(args) if (!(*di->msg_level & 1)); else printf args
+#define DMA_TRACE(args) if (!(*di->msg_level & 2)); else printf args
+#else
#define DMA_ERROR(args)
#define DMA_TRACE(args)
+#endif
/* default dma message level (if input msg_level pointer is null in dma_attach()) */
-static uint dma_msg_level =
- 0;
+static uint dma_msg_level = 0;
-#define MAXNAMEL 8 /* 8 char names */
+#define MAXNAMEL 8 /* 8 char names */
#define DI_INFO(dmah) (dma_info_t *)dmah
+typedef struct osl_dmainfo osldma_t;
/* dma engine software state */
-typedef struct dma_info {
- struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t,
- * which could be const
- */
- uint *msg_level; /* message level pointer */
- char name[MAXNAMEL]; /* callers name for diag msgs */
-
- void *osh; /* os handle */
- sb_t *sbh; /* sb handle */
-
- bool dma64; /* dma64 enabled */
- bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
-
- dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */
- dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */
- dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */
- dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */
-
- uint32 dma64align; /* either 8k or 4k depends on number of dd */
- dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */
- dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */
- uint ntxd; /* # tx descriptors tunable */
- uint txin; /* index of next descriptor to reclaim */
- uint txout; /* index of next descriptor to post */
- void **txp; /* pointer to parallel array of pointers to packets */
- osldma_t *tx_dmah; /* DMA TX descriptor ring handle */
- osldma_t **txp_dmah; /* DMA TX packet data handle */
- ulong txdpa; /* physical address of descriptor ring */
- uint txdalign; /* #bytes added to alloc'd mem to align txd */
- uint txdalloc; /* #bytes allocated for the ring */
-
- dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */
- dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */
- uint nrxd; /* # rx descriptors tunable */
- uint rxin; /* index of next descriptor to reclaim */
- uint rxout; /* index of next descriptor to post */
- void **rxp; /* pointer to parallel array of pointers to packets */
- osldma_t *rx_dmah; /* DMA RX descriptor ring handle */
- osldma_t **rxp_dmah; /* DMA RX packet data handle */
- ulong rxdpa; /* physical address of descriptor ring */
- uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
- uint rxdalloc; /* #bytes allocated for the ring */
-
- /* tunables */
- uint rxbufsize; /* rx buffer size in bytes,
- not including the extra headroom
- */
- uint nrxpost; /* # rx buffers to keep posted */
- uint rxoffset; /* rxcontrol offset */
- uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
- uint ddoffsethigh; /* high 32 bits */
- uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
- uint dataoffsethigh; /* high 32 bits */
+typedef struct dma_info
+{
+ struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t,
+ * which could be const
+ */
+ uint *msg_level; /* message level pointer */
+ char name[MAXNAMEL]; /* callers name for diag msgs */
+
+ void *osh; /* os handle */
+ sb_t *sbh; /* sb handle */
+
+ bool dma64; /* dma64 enabled */
+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
+
+ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */
+ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */
+ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */
+ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */
+
+ uint32 dma64align; /* either 8k or 4k depends on number of dd */
+ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */
+ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */
+ uint ntxd; /* # tx descriptors tunable */
+ uint txin; /* index of next descriptor to reclaim */
+ uint txout; /* index of next descriptor to post */
+ void **txp; /* pointer to parallel array of pointers to packets */
+ osldma_t *tx_dmah; /* DMA TX descriptor ring handle */
+ osldma_t **txp_dmah; /* DMA TX packet data handle */
+ ulong txdpa; /* physical address of descriptor ring */
+ uint txdalign; /* #bytes added to alloc'd mem to align txd */
+ uint txdalloc; /* #bytes allocated for the ring */
+
+ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */
+ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */
+ uint nrxd; /* # rx descriptors tunable */
+ uint rxin; /* index of next descriptor to reclaim */
+ uint rxout; /* index of next descriptor to post */
+ void **rxp; /* pointer to parallel array of pointers to packets */
+ osldma_t *rx_dmah; /* DMA RX descriptor ring handle */
+ osldma_t **rxp_dmah; /* DMA RX packet data handle */
+ ulong rxdpa; /* physical address of descriptor ring */
+ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
+ uint rxdalloc; /* #bytes allocated for the ring */
+
+ /* tunables */
+ uint rxbufsize; /* rx buffer size in bytes,
+ not including the extra headroom
+ */
+ uint nrxpost; /* # rx buffers to keep posted */
+ uint rxoffset; /* rxcontrol offset */
+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
+ uint ddoffsethigh; /* high 32 bits */
+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
+ uint dataoffsethigh; /* high 32 bits */
} dma_info_t;
#ifdef BCMDMA64
@@ -117,1053 +123,1394 @@ typedef struct dma_info {
#define I2B(index, type) ((index) * sizeof(type))
#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
-#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */
+#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */
/* common prototypes */
-static bool _dma_isaddrext(dma_info_t *di);
-static bool _dma_alloc(dma_info_t *di, uint direction);
-static void _dma_detach(dma_info_t *di);
-static void _dma_ddtable_init(dma_info_t *di, uint direction, ulong pa);
-static void _dma_rxinit(dma_info_t *di);
-static void *_dma_rx(dma_info_t *di);
-static void _dma_rxfill(dma_info_t *di);
-static void _dma_rxreclaim(dma_info_t *di);
-static void _dma_rxenable(dma_info_t *di);
-static void * _dma_getnextrxp(dma_info_t *di, bool forceall);
-
-static void _dma_txblock(dma_info_t *di);
-static void _dma_txunblock(dma_info_t *di);
-static uint _dma_txactive(dma_info_t *di);
-
-static void* _dma_peeknexttxp(dma_info_t *di);
-static uintptr _dma_getvar(dma_info_t *di, const char *name);
-static void _dma_counterreset(dma_info_t *di);
-static void _dma_fifoloopbackenable(dma_info_t *di);
+static bool _dma_isaddrext (dma_info_t * di);
+static bool _dma_alloc (dma_info_t * di, uint direction);
+static void _dma_detach (dma_info_t * di);
+static void _dma_ddtable_init (dma_info_t * di, uint direction, ulong pa);
+static void _dma_rxinit (dma_info_t * di);
+static void *_dma_rx (dma_info_t * di);
+static void _dma_rxfill (dma_info_t * di);
+static void _dma_rxreclaim (dma_info_t * di);
+static void _dma_rxenable (dma_info_t * di);
+static void *_dma_getnextrxp (dma_info_t * di, bool forceall);
+
+static void _dma_txblock (dma_info_t * di);
+static void _dma_txunblock (dma_info_t * di);
+static uint _dma_txactive (dma_info_t * di);
+
+static void *_dma_peeknexttxp (dma_info_t * di);
+static uintptr _dma_getvar (dma_info_t * di, const char *name);
+static void _dma_counterreset (dma_info_t * di);
+static void _dma_fifoloopbackenable (dma_info_t * di);
/* ** 32 bit DMA prototypes */
-static bool dma32_alloc(dma_info_t *di, uint direction);
-static bool dma32_txreset(dma_info_t *di);
-static bool dma32_rxreset(dma_info_t *di);
-static bool dma32_txsuspendedidle(dma_info_t *di);
-static int dma32_txfast(dma_info_t *di, void *p0, bool commit);
-static void *dma32_getnexttxp(dma_info_t *di, bool forceall);
-static void *dma32_getnextrxp(dma_info_t *di, bool forceall);
-static void dma32_txrotate(dma_info_t *di);
-static bool dma32_rxidle(dma_info_t *di);
-static void dma32_txinit(dma_info_t *di);
-static bool dma32_txenabled(dma_info_t *di);
-static void dma32_txsuspend(dma_info_t *di);
-static void dma32_txresume(dma_info_t *di);
-static bool dma32_txsuspended(dma_info_t *di);
-static void dma32_txreclaim(dma_info_t *di, bool forceall);
-static bool dma32_txstopped(dma_info_t *di);
-static bool dma32_rxstopped(dma_info_t *di);
-static bool dma32_rxenabled(dma_info_t *di);
-static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs);
+static bool dma32_alloc (dma_info_t * di, uint direction);
+static bool dma32_txreset (dma_info_t * di);
+static bool dma32_rxreset (dma_info_t * di);
+static bool dma32_txsuspendedidle (dma_info_t * di);
+static int dma32_txfast (dma_info_t * di, void *p0, bool commit);
+static void *dma32_getnexttxp (dma_info_t * di, bool forceall);
+static void *dma32_getnextrxp (dma_info_t * di, bool forceall);
+static void dma32_txrotate (dma_info_t * di);
+static bool dma32_rxidle (dma_info_t * di);
+static void dma32_txinit (dma_info_t * di);
+static bool dma32_txenabled (dma_info_t * di);
+static void dma32_txsuspend (dma_info_t * di);
+static void dma32_txresume (dma_info_t * di);
+static bool dma32_txsuspended (dma_info_t * di);
+static void dma32_txreclaim (dma_info_t * di, bool forceall);
+static bool dma32_txstopped (dma_info_t * di);
+static bool dma32_rxstopped (dma_info_t * di);
+static bool dma32_rxenabled (dma_info_t * di);
+static bool _dma32_addrext (osl_t * osh, dma32regs_t * dma32regs);
/* ** 64 bit DMA prototypes and stubs */
#ifdef BCMDMA64
-static bool dma64_alloc(dma_info_t *di, uint direction);
-static bool dma64_txreset(dma_info_t *di);
-static bool dma64_rxreset(dma_info_t *di);
-static bool dma64_txsuspendedidle(dma_info_t *di);
-static int dma64_txfast(dma_info_t *di, void *p0, bool commit);
-static void *dma64_getnexttxp(dma_info_t *di, bool forceall);
-static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
-static void dma64_txrotate(dma_info_t *di);
-
-static bool dma64_rxidle(dma_info_t *di);
-static void dma64_txinit(dma_info_t *di);
-static bool dma64_txenabled(dma_info_t *di);
-static void dma64_txsuspend(dma_info_t *di);
-static void dma64_txresume(dma_info_t *di);
-static bool dma64_txsuspended(dma_info_t *di);
-static void dma64_txreclaim(dma_info_t *di, bool forceall);
-static bool dma64_txstopped(dma_info_t *di);
-static bool dma64_rxstopped(dma_info_t *di);
-static bool dma64_rxenabled(dma_info_t *di);
-static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs);
+static bool dma64_alloc (dma_info_t * di, uint direction);
+static bool dma64_txreset (dma_info_t * di);
+static bool dma64_rxreset (dma_info_t * di);
+static bool dma64_txsuspendedidle (dma_info_t * di);
+static int dma64_txfast (dma_info_t * di, void *p0, bool commit);
+static void *dma64_getnexttxp (dma_info_t * di, bool forceall);
+static void *dma64_getnextrxp (dma_info_t * di, bool forceall);
+static void dma64_txrotate (dma_info_t * di);
+
+static bool dma64_rxidle (dma_info_t * di);
+static void dma64_txinit (dma_info_t * di);
+static bool dma64_txenabled (dma_info_t * di);
+static void dma64_txsuspend (dma_info_t * di);
+static void dma64_txresume (dma_info_t * di);
+static bool dma64_txsuspended (dma_info_t * di);
+static void dma64_txreclaim (dma_info_t * di, bool forceall);
+static bool dma64_txstopped (dma_info_t * di);
+static bool dma64_rxstopped (dma_info_t * di);
+static bool dma64_rxenabled (dma_info_t * di);
+static bool _dma64_addrext (osl_t * osh, dma64regs_t * dma64regs);
#else
-static bool dma64_alloc(dma_info_t *di, uint direction) { return FALSE; }
-static bool dma64_txreset(dma_info_t *di) { return FALSE; }
-static bool dma64_rxreset(dma_info_t *di) { return FALSE; }
-static bool dma64_txsuspendedidle(dma_info_t *di) { return FALSE;}
-static int dma64_txfast(dma_info_t *di, void *p0, bool commit) { return 0; }
-static void *dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; }
-static void *dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; }
-static void dma64_txrotate(dma_info_t *di) { return; }
-
-static bool dma64_rxidle(dma_info_t *di) { return FALSE; }
-static void dma64_txinit(dma_info_t *di) { return; }
-static bool dma64_txenabled(dma_info_t *di) { return FALSE; }
-static void dma64_txsuspend(dma_info_t *di) { return; }
-static void dma64_txresume(dma_info_t *di) { return; }
-static bool dma64_txsuspended(dma_info_t *di) {return FALSE; }
-static void dma64_txreclaim(dma_info_t *di, bool forceall) { return; }
-static bool dma64_txstopped(dma_info_t *di) { return FALSE; }
-static bool dma64_rxstopped(dma_info_t *di) { return FALSE; }
-static bool dma64_rxenabled(dma_info_t *di) { return FALSE; }
-static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs) { return FALSE; }
-
-#endif /* BCMDMA64 */
+static bool
+dma64_alloc (dma_info_t * di, uint direction)
+{
+ return FALSE;
+}
+static bool
+dma64_txreset (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+dma64_rxreset (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+dma64_txsuspendedidle (dma_info_t * di)
+{
+ return FALSE;
+}
+static int
+dma64_txfast (dma_info_t * di, void *p0, bool commit)
+{
+ return 0;
+}
+static void *
+dma64_getnexttxp (dma_info_t * di, bool forceall)
+{
+ return NULL;
+}
+static void *
+dma64_getnextrxp (dma_info_t * di, bool forceall)
+{
+ return NULL;
+}
+static void
+dma64_txrotate (dma_info_t * di)
+{
+ return;
+}
+static bool
+dma64_rxidle (dma_info_t * di)
+{
+ return FALSE;
+}
+static void
+dma64_txinit (dma_info_t * di)
+{
+ return;
+}
+static bool
+dma64_txenabled (dma_info_t * di)
+{
+ return FALSE;
+}
+static void
+dma64_txsuspend (dma_info_t * di)
+{
+ return;
+}
+static void
+dma64_txresume (dma_info_t * di)
+{
+ return;
+}
+static bool
+dma64_txsuspended (dma_info_t * di)
+{
+ return FALSE;
+}
+static void
+dma64_txreclaim (dma_info_t * di, bool forceall)
+{
+ return;
+}
+static bool
+dma64_txstopped (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+dma64_rxstopped (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+dma64_rxenabled (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+_dma64_addrext (osl_t * osh, dma64regs_t * dma64regs)
+{
+ return FALSE;
+}
+
+#endif /* BCMDMA64 */
+
+#ifdef BCMDBG
+static void dma32_dumpring (dma_info_t * di, struct bcmstrbuf *b,
+ dma32dd_t * ring, uint start, uint end,
+ uint max_num);
+static void dma32_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring);
+static void dma32_dumptx (dma_info_t * di, struct bcmstrbuf *b,
+ bool dumpring);
+static void dma32_dumprx (dma_info_t * di, struct bcmstrbuf *b,
+ bool dumpring);
+
+static void dma64_dumpring (dma_info_t * di, struct bcmstrbuf *b,
+ dma64dd_t * ring, uint start, uint end,
+ uint max_num);
+static void dma64_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring);
+static void dma64_dumptx (dma_info_t * di, struct bcmstrbuf *b,
+ bool dumpring);
+static void dma64_dumprx (dma_info_t * di, struct bcmstrbuf *b,
+ bool dumpring);
+#endif
static di_fcn_t dma64proc = {
- (di_detach_t)_dma_detach,
- (di_txinit_t)dma64_txinit,
- (di_txreset_t)dma64_txreset,
- (di_txenabled_t)dma64_txenabled,
- (di_txsuspend_t)dma64_txsuspend,
- (di_txresume_t)dma64_txresume,
- (di_txsuspended_t)dma64_txsuspended,
- (di_txsuspendedidle_t)dma64_txsuspendedidle,
- (di_txfast_t)dma64_txfast,
- (di_txstopped_t)dma64_txstopped,
- (di_txreclaim_t)dma64_txreclaim,
- (di_getnexttxp_t)dma64_getnexttxp,
- (di_peeknexttxp_t)_dma_peeknexttxp,
- (di_txblock_t)_dma_txblock,
- (di_txunblock_t)_dma_txunblock,
- (di_txactive_t)_dma_txactive,
- (di_txrotate_t)dma64_txrotate,
-
- (di_rxinit_t)_dma_rxinit,
- (di_rxreset_t)dma64_rxreset,
- (di_rxidle_t)dma64_rxidle,
- (di_rxstopped_t)dma64_rxstopped,
- (di_rxenable_t)_dma_rxenable,
- (di_rxenabled_t)dma64_rxenabled,
- (di_rx_t)_dma_rx,
- (di_rxfill_t)_dma_rxfill,
- (di_rxreclaim_t)_dma_rxreclaim,
- (di_getnextrxp_t)_dma_getnextrxp,
-
- (di_fifoloopbackenable_t)_dma_fifoloopbackenable,
- (di_getvar_t)_dma_getvar,
- (di_counterreset_t)_dma_counterreset,
-
- NULL,
- NULL,
- NULL,
- 34
+ (di_detach_t) _dma_detach,
+ (di_txinit_t) dma64_txinit,
+ (di_txreset_t) dma64_txreset,
+ (di_txenabled_t) dma64_txenabled,
+ (di_txsuspend_t) dma64_txsuspend,
+ (di_txresume_t) dma64_txresume,
+ (di_txsuspended_t) dma64_txsuspended,
+ (di_txsuspendedidle_t) dma64_txsuspendedidle,
+ (di_txfast_t) dma64_txfast,
+ (di_txstopped_t) dma64_txstopped,
+ (di_txreclaim_t) dma64_txreclaim,
+ (di_getnexttxp_t) dma64_getnexttxp,
+ (di_peeknexttxp_t) _dma_peeknexttxp,
+ (di_txblock_t) _dma_txblock,
+ (di_txunblock_t) _dma_txunblock,
+ (di_txactive_t) _dma_txactive,
+ (di_txrotate_t) dma64_txrotate,
+
+ (di_rxinit_t) _dma_rxinit,
+ (di_rxreset_t) dma64_rxreset,
+ (di_rxidle_t) dma64_rxidle,
+ (di_rxstopped_t) dma64_rxstopped,
+ (di_rxenable_t) _dma_rxenable,
+ (di_rxenabled_t) dma64_rxenabled,
+ (di_rx_t) _dma_rx,
+ (di_rxfill_t) _dma_rxfill,
+ (di_rxreclaim_t) _dma_rxreclaim,
+ (di_getnextrxp_t) _dma_getnextrxp,
+
+ (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+ (di_getvar_t) _dma_getvar,
+ (di_counterreset_t) _dma_counterreset,
+
+#ifdef BCMDBG
+ (di_dump_t) dma64_dump,
+ (di_dumptx_t) dma64_dumptx,
+ (di_dumprx_t) dma64_dumprx,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+ 34
};
static di_fcn_t dma32proc = {
- (di_detach_t)_dma_detach,
- (di_txinit_t)dma32_txinit,
- (di_txreset_t)dma32_txreset,
- (di_txenabled_t)dma32_txenabled,
- (di_txsuspend_t)dma32_txsuspend,
- (di_txresume_t)dma32_txresume,
- (di_txsuspended_t)dma32_txsuspended,
- (di_txsuspendedidle_t)dma32_txsuspendedidle,
- (di_txfast_t)dma32_txfast,
- (di_txstopped_t)dma32_txstopped,
- (di_txreclaim_t)dma32_txreclaim,
- (di_getnexttxp_t)dma32_getnexttxp,
- (di_peeknexttxp_t)_dma_peeknexttxp,
- (di_txblock_t)_dma_txblock,
- (di_txunblock_t)_dma_txunblock,
- (di_txactive_t)_dma_txactive,
- (di_txrotate_t)dma32_txrotate,
-
- (di_rxinit_t)_dma_rxinit,
- (di_rxreset_t)dma32_rxreset,
- (di_rxidle_t)dma32_rxidle,
- (di_rxstopped_t)dma32_rxstopped,
- (di_rxenable_t)_dma_rxenable,
- (di_rxenabled_t)dma32_rxenabled,
- (di_rx_t)_dma_rx,
- (di_rxfill_t)_dma_rxfill,
- (di_rxreclaim_t)_dma_rxreclaim,
- (di_getnextrxp_t)_dma_getnextrxp,
-
- (di_fifoloopbackenable_t)_dma_fifoloopbackenable,
- (di_getvar_t)_dma_getvar,
- (di_counterreset_t)_dma_counterreset,
-
- NULL,
- NULL,
- NULL,
- 34
+ (di_detach_t) _dma_detach,
+ (di_txinit_t) dma32_txinit,
+ (di_txreset_t) dma32_txreset,
+ (di_txenabled_t) dma32_txenabled,
+ (di_txsuspend_t) dma32_txsuspend,
+ (di_txresume_t) dma32_txresume,
+ (di_txsuspended_t) dma32_txsuspended,
+ (di_txsuspendedidle_t) dma32_txsuspendedidle,
+ (di_txfast_t) dma32_txfast,
+ (di_txstopped_t) dma32_txstopped,
+ (di_txreclaim_t) dma32_txreclaim,
+ (di_getnexttxp_t) dma32_getnexttxp,
+ (di_peeknexttxp_t) _dma_peeknexttxp,
+ (di_txblock_t) _dma_txblock,
+ (di_txunblock_t) _dma_txunblock,
+ (di_txactive_t) _dma_txactive,
+ (di_txrotate_t) dma32_txrotate,
+
+ (di_rxinit_t) _dma_rxinit,
+ (di_rxreset_t) dma32_rxreset,
+ (di_rxidle_t) dma32_rxidle,
+ (di_rxstopped_t) dma32_rxstopped,
+ (di_rxenable_t) _dma_rxenable,
+ (di_rxenabled_t) dma32_rxenabled,
+ (di_rx_t) _dma_rx,
+ (di_rxfill_t) _dma_rxfill,
+ (di_rxreclaim_t) _dma_rxreclaim,
+ (di_getnextrxp_t) _dma_getnextrxp,
+
+ (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+ (di_getvar_t) _dma_getvar,
+ (di_counterreset_t) _dma_counterreset,
+
+#ifdef BCMDBG
+ (di_dump_t) dma32_dump,
+ (di_dumptx_t) dma32_dumptx,
+ (di_dumprx_t) dma32_dumprx,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+ 34
};
hnddma_t *
-dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx,
- uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level)
+dma_attach (osl_t * osh, char *name, sb_t * sbh, void *dmaregstx,
+ void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize,
+ uint nrxpost, uint rxoffset, uint * msg_level)
{
- dma_info_t *di;
- uint size;
+ dma_info_t *di;
+ uint size;
+
+ /* allocate private info structure */
+ if ((di = MALLOC (osh, sizeof (dma_info_t))) == NULL)
+ {
+#ifdef BCMDBG
+ printf ("dma_attach: out of memory, malloced %d bytes\n",
+ MALLOCED (osh));
+#endif
+ return (NULL);
+ }
+ bzero ((char *) di, sizeof (dma_info_t));
- /* allocate private info structure */
- if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) {
- return (NULL);
- }
- bzero((char *)di, sizeof(dma_info_t));
+ di->msg_level = msg_level ? msg_level : &dma_msg_level;
- di->msg_level = msg_level ? msg_level : &dma_msg_level;
+ /* old chips w/o sb is no longer supported */
+ ASSERT (sbh != NULL);
- /* old chips w/o sb is no longer supported */
- ASSERT(sbh != NULL);
-
- di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64);
+ di->dma64 = ((sb_coreflagshi (sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64);
#ifndef BCMDMA64
- if (di->dma64) {
- DMA_ERROR(("dma_attach: driver doesn't have the capability to support "
- "64 bits DMA\n"));
- goto fail;
- }
+ if (di->dma64)
+ {
+ DMA_ERROR (("dma_attach: driver doesn't have the capability to support "
+ "64 bits DMA\n"));
+ goto fail;
+ }
#endif
- /* check arguments */
- ASSERT(ISPOWEROF2(ntxd));
- ASSERT(ISPOWEROF2(nrxd));
- if (nrxd == 0)
- ASSERT(dmaregsrx == NULL);
- if (ntxd == 0)
- ASSERT(dmaregstx == NULL);
-
-
- /* init dma reg pointer */
- if (di->dma64) {
- ASSERT(ntxd <= D64MAXDD);
- ASSERT(nrxd <= D64MAXDD);
- di->d64txregs = (dma64regs_t *)dmaregstx;
- di->d64rxregs = (dma64regs_t *)dmaregsrx;
-
- di->dma64align = D64RINGALIGN;
- if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
- /* for smaller dd table, HW relax the alignment requirement */
- di->dma64align = D64RINGALIGN / 2;
- }
- } else {
- ASSERT(ntxd <= D32MAXDD);
- ASSERT(nrxd <= D32MAXDD);
- di->d32txregs = (dma32regs_t *)dmaregstx;
- di->d32rxregs = (dma32regs_t *)dmaregsrx;
+ /* check arguments */
+ ASSERT (ISPOWEROF2 (ntxd));
+ ASSERT (ISPOWEROF2 (nrxd));
+ if (nrxd == 0)
+ ASSERT (dmaregsrx == NULL);
+ if (ntxd == 0)
+ ASSERT (dmaregstx == NULL);
+
+
+ /* init dma reg pointer */
+ if (di->dma64)
+ {
+ ASSERT (ntxd <= D64MAXDD);
+ ASSERT (nrxd <= D64MAXDD);
+ di->d64txregs = (dma64regs_t *) dmaregstx;
+ di->d64rxregs = (dma64regs_t *) dmaregsrx;
+
+ di->dma64align = D64RINGALIGN;
+ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2))
+ {
+ /* for smaller dd table, HW relax the alignment requirement */
+ di->dma64align = D64RINGALIGN / 2;
}
-
- DMA_TRACE(("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d "
- "rxoffset %d dmaregstx %p dmaregsrx %p\n",
- name, (di->dma64 ? "DMA64" : "DMA32"), osh, ntxd, nrxd, rxbufsize,
- nrxpost, rxoffset, dmaregstx, dmaregsrx));
-
- /* make a private copy of our callers name */
- strncpy(di->name, name, MAXNAMEL);
- di->name[MAXNAMEL-1] = '\0';
-
- di->osh = osh;
- di->sbh = sbh;
-
- /* save tunables */
- di->ntxd = ntxd;
- di->nrxd = nrxd;
-
- /* the actual dma size doesn't include the extra headroom */
- if (rxbufsize > BCMEXTRAHDROOM)
- di->rxbufsize = rxbufsize - BCMEXTRAHDROOM;
- else
- di->rxbufsize = rxbufsize;
-
- di->nrxpost = nrxpost;
- di->rxoffset = rxoffset;
-
- /*
- * figure out the DMA physical address offset for dd and data
- * for old chips w/o sb, use zero
- * for new chips w sb,
- * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
- * Other bus: use zero
- * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
- */
- di->ddoffsetlow = 0;
- di->dataoffsetlow = 0;
- /* for pci bus, add offset */
- if (sbh->bustype == PCI_BUS) {
- if ((sbh->buscoretype == SB_PCIE) && di->dma64) {
- /* pcie with DMA64 */
- di->ddoffsetlow = 0;
- di->ddoffsethigh = SB_PCIE_DMA_H32;
- } else {
- /* pci(DMA32/DMA64) or pcie with DMA32 */
- di->ddoffsetlow = SB_PCI_DMA;
- di->ddoffsethigh = 0;
- }
- di->dataoffsetlow = di->ddoffsetlow;
- di->dataoffsethigh = di->ddoffsethigh;
+ }
+ else
+ {
+ ASSERT (ntxd <= D32MAXDD);
+ ASSERT (nrxd <= D32MAXDD);
+ di->d32txregs = (dma32regs_t *) dmaregstx;
+ di->d32rxregs = (dma32regs_t *) dmaregsrx;
+ }
+
+ DMA_TRACE (("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d " "rxoffset %d dmaregstx %p dmaregsrx %p\n", name, (di->dma64 ? "DMA64" : "DMA32"), osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, dmaregstx, dmaregsrx));
+
+ /* make a private copy of our callers name */
+ strncpy (di->name, name, MAXNAMEL);
+ di->name[MAXNAMEL - 1] = '\0';
+
+ di->osh = osh;
+ di->sbh = sbh;
+
+ /* save tunables */
+ di->ntxd = ntxd;
+ di->nrxd = nrxd;
+
+ /* the actual dma size doesn't include the extra headroom */
+ if (rxbufsize > BCMEXTRAHDROOM)
+ di->rxbufsize = rxbufsize - BCMEXTRAHDROOM;
+ else
+ di->rxbufsize = rxbufsize;
+
+ di->nrxpost = nrxpost;
+ di->rxoffset = rxoffset;
+
+ /*
+ * figure out the DMA physical address offset for dd and data
+ * for old chips w/o sb, use zero
+ * for new chips w sb,
+ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
+ * Other bus: use zero
+ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
+ */
+ di->ddoffsetlow = 0;
+ di->dataoffsetlow = 0;
+ /* for pci bus, add offset */
+ if (sbh->bustype == PCI_BUS)
+ {
+ if ((sbh->buscoretype == SB_PCIE) && di->dma64)
+ {
+ /* pcie with DMA64 */
+ di->ddoffsetlow = 0;
+ di->ddoffsethigh = SB_PCIE_DMA_H32;
}
+ else
+ {
+ /* pci(DMA32/DMA64) or pcie with DMA32 */
+ di->ddoffsetlow = SB_PCI_DMA;
+ di->ddoffsethigh = 0;
+ }
+ di->dataoffsetlow = di->ddoffsetlow;
+ di->dataoffsethigh = di->ddoffsethigh;
+ }
#if defined(__mips__) && defined(IL_BIGENDIAN)
- di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED;
+ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED;
#endif
- di->addrext = _dma_isaddrext(di);
-
- /* allocate tx packet pointer vector */
- if (ntxd) {
- size = ntxd * sizeof(void *);
- if ((di->txp = MALLOC(osh, size)) == NULL) {
- DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n",
- di->name, MALLOCED(osh)));
- goto fail;
- }
- bzero((char *)di->txp, size);
+ di->addrext = _dma_isaddrext (di);
+
+ /* allocate tx packet pointer vector */
+ if (ntxd)
+ {
+ size = ntxd * sizeof (void *);
+ if ((di->txp = MALLOC (osh, size)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: out of tx memory, malloced %d bytes\n",
+ di->name, MALLOCED (osh)));
+ goto fail;
}
-
- /* allocate rx packet pointer vector */
- if (nrxd) {
- size = nrxd * sizeof(void *);
- if ((di->rxp = MALLOC(osh, size)) == NULL) {
- DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n",
- di->name, MALLOCED(osh)));
- goto fail;
- }
- bzero((char *)di->rxp, size);
+ bzero ((char *) di->txp, size);
+ }
+
+ /* allocate rx packet pointer vector */
+ if (nrxd)
+ {
+ size = nrxd * sizeof (void *);
+ if ((di->rxp = MALLOC (osh, size)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: out of rx memory, malloced %d bytes\n",
+ di->name, MALLOCED (osh)));
+ goto fail;
}
-
- /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
- if (ntxd) {
- if (!_dma_alloc(di, DMA_TX))
- goto fail;
- }
-
- /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
- if (nrxd) {
- if (!_dma_alloc(di, DMA_RX))
- goto fail;
- }
-
- if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) {
- DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n",
- di->name, di->txdpa));
- goto fail;
- }
- if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) {
- DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n",
- di->name, di->rxdpa));
- goto fail;
- }
-
- DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh "
- "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow,
- di->dataoffsethigh, di->addrext));
-
- /* allocate tx packet pointer vector and DMA mapping vectors */
- if (ntxd) {
-
- size = ntxd * sizeof(osldma_t **);
- if ((di->txp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL)
- goto fail;
- bzero((char*)di->txp_dmah, size);
- }else
- di->txp_dmah = NULL;
-
- /* allocate rx packet pointer vector and DMA mapping vectors */
- if (nrxd) {
-
- size = nrxd * sizeof(osldma_t **);
- if ((di->rxp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL)
- goto fail;
- bzero((char*)di->rxp_dmah, size);
-
- } else
- di->rxp_dmah = NULL;
-
- /* initialize opsvec of function pointers */
- di->hnddma.di_fn = DMA64_ENAB(di) ? dma64proc : dma32proc;
-
- return ((hnddma_t *)di);
+ bzero ((char *) di->rxp, size);
+ }
+
+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
+ if (ntxd)
+ {
+ if (!_dma_alloc (di, DMA_TX))
+ goto fail;
+ }
+
+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
+ if (nrxd)
+ {
+ if (!_dma_alloc (di, DMA_RX))
+ goto fail;
+ }
+
+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ)
+ && !di->addrext)
+ {
+ DMA_ERROR (("%s: dma_attach: txdpa 0x%lx: addrext not supported\n",
+ di->name, di->txdpa));
+ goto fail;
+ }
+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ)
+ && !di->addrext)
+ {
+ DMA_ERROR (("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n",
+ di->name, di->rxdpa));
+ goto fail;
+ }
+
+ DMA_TRACE (("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
+
+ /* allocate tx packet pointer vector and DMA mapping vectors */
+ if (ntxd)
+ {
+
+ size = ntxd * sizeof (osldma_t **);
+ if ((di->txp_dmah = (osldma_t **) MALLOC (osh, size)) == NULL)
+ goto fail;
+ bzero ((char *) di->txp_dmah, size);
+ }
+ else
+ di->txp_dmah = NULL;
+
+ /* allocate rx packet pointer vector and DMA mapping vectors */
+ if (nrxd)
+ {
+
+ size = nrxd * sizeof (osldma_t **);
+ if ((di->rxp_dmah = (osldma_t **) MALLOC (osh, size)) == NULL)
+ goto fail;
+ bzero ((char *) di->rxp_dmah, size);
+
+ }
+ else
+ di->rxp_dmah = NULL;
+
+ /* initialize opsvec of function pointers */
+ di->hnddma.di_fn = DMA64_ENAB (di) ? dma64proc : dma32proc;
+
+ return ((hnddma_t *) di);
fail:
- _dma_detach(di);
- return (NULL);
+ _dma_detach (di);
+ return (NULL);
}
/* init the tx or rx descriptor */
static INLINE void
-dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *flags,
- uint32 bufcount)
-{
- /* dma32 uses 32 bits control to fit both flags and bufcounter */
- *flags = *flags | (bufcount & CTRL_BC_MASK);
-
- if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
- W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow));
- W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags));
- } else {
- /* address extension */
- uint32 ae;
- ASSERT(di->addrext);
- ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
- pa &= ~PCI32ADDR_HIGH;
-
- *flags |= (ae << CTRL_AE_SHIFT);
- W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow));
- W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags));
- }
+dma32_dd_upd (dma_info_t * di, dma32dd_t * ddring, ulong pa, uint outidx,
+ uint32 * flags, uint32 bufcount)
+{
+ /* dma32 uses 32 bits control to fit both flags and bufcounter */
+ *flags = *flags | (bufcount & CTRL_BC_MASK);
+
+ if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH))
+ {
+ W_SM (&ddring[outidx].addr, BUS_SWAP32 (pa + di->dataoffsetlow));
+ W_SM (&ddring[outidx].ctrl, BUS_SWAP32 (*flags));
+ }
+ else
+ {
+ /* address extension */
+ uint32 ae;
+ ASSERT (di->addrext);
+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ pa &= ~PCI32ADDR_HIGH;
+
+ *flags |= (ae << CTRL_AE_SHIFT);
+ W_SM (&ddring[outidx].addr, BUS_SWAP32 (pa + di->dataoffsetlow));
+ W_SM (&ddring[outidx].ctrl, BUS_SWAP32 (*flags));
+ }
}
static INLINE void
-dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags,
- uint32 bufcount)
-{
- uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
-
- /* PCI bus with big(>1G) physical address, use address extension */
- if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
- W_SM(&ddring[outidx].addrlow, BUS_SWAP32(pa + di->dataoffsetlow));
- W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(0 + di->dataoffsethigh));
- W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
- W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
- } else {
- /* address extension */
- uint32 ae;
- ASSERT(di->addrext);
-
- ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
- pa &= ~PCI32ADDR_HIGH;
-
- ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
- W_SM(&ddring[outidx].addrlow, BUS_SWAP32(pa + di->dataoffsetlow));
- W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(0 + di->dataoffsethigh));
- W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
- W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
- }
+dma64_dd_upd (dma_info_t * di, dma64dd_t * ddring, ulong pa, uint outidx,
+ uint32 * flags, uint32 bufcount)
+{
+ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
+
+ /* PCI bus with big(>1G) physical address, use address extension */
+ if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH))
+ {
+ W_SM (&ddring[outidx].addrlow, BUS_SWAP32 (pa + di->dataoffsetlow));
+ W_SM (&ddring[outidx].addrhigh, BUS_SWAP32 (0 + di->dataoffsethigh));
+ W_SM (&ddring[outidx].ctrl1, BUS_SWAP32 (*flags));
+ W_SM (&ddring[outidx].ctrl2, BUS_SWAP32 (ctrl2));
+ }
+ else
+ {
+ /* address extension */
+ uint32 ae;
+ ASSERT (di->addrext);
+
+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ pa &= ~PCI32ADDR_HIGH;
+
+ ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
+ W_SM (&ddring[outidx].addrlow, BUS_SWAP32 (pa + di->dataoffsetlow));
+ W_SM (&ddring[outidx].addrhigh, BUS_SWAP32 (0 + di->dataoffsethigh));
+ W_SM (&ddring[outidx].ctrl1, BUS_SWAP32 (*flags));
+ W_SM (&ddring[outidx].ctrl2, BUS_SWAP32 (ctrl2));
+ }
}
static bool
-_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs)
+_dma32_addrext (osl_t * osh, dma32regs_t * dma32regs)
{
- uint32 w;
+ uint32 w;
- OR_REG(osh, &dma32regs->control, XC_AE);
- w = R_REG(osh, &dma32regs->control);
- AND_REG(osh, &dma32regs->control, ~XC_AE);
- return ((w & XC_AE) == XC_AE);
+ OR_REG (osh, &dma32regs->control, XC_AE);
+ w = R_REG (osh, &dma32regs->control);
+ AND_REG (osh, &dma32regs->control, ~XC_AE);
+ return ((w & XC_AE) == XC_AE);
}
static bool
-_dma_alloc(dma_info_t *di, uint direction)
+_dma_alloc (dma_info_t * di, uint direction)
{
- if (DMA64_ENAB(di)) {
- return dma64_alloc(di, direction);
- } else {
- return dma32_alloc(di, direction);
- }
+ if (DMA64_ENAB (di))
+ {
+ return dma64_alloc (di, direction);
+ }
+ else
+ {
+ return dma32_alloc (di, direction);
+ }
}
/* !! may be called with core in reset */
static void
-_dma_detach(dma_info_t *di)
-{
- if (di == NULL)
- return;
-
- DMA_TRACE(("%s: dma_detach\n", di->name));
-
- /* shouldn't be here if descriptors are unreclaimed */
- ASSERT(di->txin == di->txout);
- ASSERT(di->rxin == di->rxout);
-
- /* free dma descriptor rings */
- if (DMA64_ENAB(di)) {
- if (di->txd64)
- DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->txd64 - di->txdalign),
- di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah);
- if (di->rxd64)
- DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->rxd64 - di->rxdalign),
- di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah);
- } else {
- if (di->txd32)
- DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->txd32 - di->txdalign),
- di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah);
- if (di->rxd32)
- DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->rxd32 - di->rxdalign),
- di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah);
- }
-
- /* free packet pointer vectors */
- if (di->txp)
- MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *)));
- if (di->rxp)
- MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *)));
-
- /* free tx packet DMA handles */
- if (di->txp_dmah)
- MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(osldma_t **));
-
- /* free rx packet DMA handles */
- if (di->rxp_dmah)
- MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(osldma_t **));
-
- /* free our private info structure */
- MFREE(di->osh, (void *)di, sizeof(dma_info_t));
+_dma_detach (dma_info_t * di)
+{
+ if (di == NULL)
+ return;
+
+ DMA_TRACE (("%s: dma_detach\n", di->name));
+
+ /* shouldn't be here if descriptors are unreclaimed */
+ ASSERT (di->txin == di->txout);
+ ASSERT (di->rxin == di->rxout);
+
+ /* free dma descriptor rings */
+ if (DMA64_ENAB (di))
+ {
+ if (di->txd64)
+ DMA_FREE_CONSISTENT (di->osh,
+ ((int8 *) (uintptr) di->txd64 - di->txdalign),
+ di->txdalloc, (di->txdpa - di->txdalign),
+ &di->tx_dmah);
+ if (di->rxd64)
+ DMA_FREE_CONSISTENT (di->osh,
+ ((int8 *) (uintptr) di->rxd64 - di->rxdalign),
+ di->rxdalloc, (di->rxdpa - di->rxdalign),
+ &di->rx_dmah);
+ }
+ else
+ {
+ if (di->txd32)
+ DMA_FREE_CONSISTENT (di->osh,
+ ((int8 *) (uintptr) di->txd32 - di->txdalign),
+ di->txdalloc, (di->txdpa - di->txdalign),
+ &di->tx_dmah);
+ if (di->rxd32)
+ DMA_FREE_CONSISTENT (di->osh,
+ ((int8 *) (uintptr) di->rxd32 - di->rxdalign),
+ di->rxdalloc, (di->rxdpa - di->rxdalign),
+ &di->rx_dmah);
+ }
+
+ /* free packet pointer vectors */
+ if (di->txp)
+ MFREE (di->osh, (void *) di->txp, (di->ntxd * sizeof (void *)));
+ if (di->rxp)
+ MFREE (di->osh, (void *) di->rxp, (di->nrxd * sizeof (void *)));
+
+ /* free tx packet DMA handles */
+ if (di->txp_dmah)
+ MFREE (di->osh, (void *) di->txp_dmah, di->ntxd * sizeof (osldma_t **));
+
+ /* free rx packet DMA handles */
+ if (di->rxp_dmah)
+ MFREE (di->osh, (void *) di->rxp_dmah, di->nrxd * sizeof (osldma_t **));
+
+ /* free our private info structure */
+ MFREE (di->osh, (void *) di, sizeof (dma_info_t));
}
/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */
static bool
-_dma_isaddrext(dma_info_t *di)
-{
- if (DMA64_ENAB(di)) {
- /* DMA64 supports full 32 bits or 64 bits. AE is always valid */
-
- /* not all tx or rx channel are available */
- if (di->d64txregs != NULL) {
- if (!_dma64_addrext(di->osh, di->d64txregs)) {
- DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n",
- di->name));
- ASSERT(0);
- }
- return TRUE;
- } else if (di->d64rxregs != NULL) {
- if (!_dma64_addrext(di->osh, di->d64rxregs)) {
- DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n",
- di->name));
- ASSERT(0);
- }
- return TRUE;
- }
- return FALSE;
- } else if (di->d32txregs)
- return (_dma32_addrext(di->osh, di->d32txregs));
- else if (di->d32rxregs)
- return (_dma32_addrext(di->osh, di->d32rxregs));
- return FALSE;
+_dma_isaddrext (dma_info_t * di)
+{
+ if (DMA64_ENAB (di))
+ {
+ /* DMA64 supports full 32 bits or 64 bits. AE is always valid */
+
+ /* not all tx or rx channel are available */
+ if (di->d64txregs != NULL)
+ {
+ if (!_dma64_addrext (di->osh, di->d64txregs))
+ {
+ DMA_ERROR (("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", di->name));
+ ASSERT (0);
+ }
+ return TRUE;
+ }
+ else if (di->d64rxregs != NULL)
+ {
+ if (!_dma64_addrext (di->osh, di->d64rxregs))
+ {
+ DMA_ERROR (("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", di->name));
+ ASSERT (0);
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+ else if (di->d32txregs)
+ return (_dma32_addrext (di->osh, di->d32txregs));
+ else if (di->d32rxregs)
+ return (_dma32_addrext (di->osh, di->d32rxregs));
+ return FALSE;
}
/* initialize descriptor table base address */
static void
-_dma_ddtable_init(dma_info_t *di, uint direction, ulong pa)
-{
- if (DMA64_ENAB(di)) {
-
- if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
- if (direction == DMA_TX) {
- W_REG(di->osh, &di->d64txregs->addrlow, (pa + di->ddoffsetlow));
- W_REG(di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh);
- } else {
- W_REG(di->osh, &di->d64rxregs->addrlow, (pa + di->ddoffsetlow));
- W_REG(di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh);
- }
- } else {
- /* DMA64 32bits address extension */
- uint32 ae;
- ASSERT(di->addrext);
-
- /* shift the high bit(s) from pa to ae */
- ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
- pa &= ~PCI32ADDR_HIGH;
-
- if (direction == DMA_TX) {
- W_REG(di->osh, &di->d64txregs->addrlow, (pa + di->ddoffsetlow));
- W_REG(di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh);
- SET_REG(di->osh, &di->d64txregs->control, D64_XC_AE,
- (ae << D64_XC_AE_SHIFT));
- } else {
- W_REG(di->osh, &di->d64rxregs->addrlow, (pa + di->ddoffsetlow));
- W_REG(di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh);
- SET_REG(di->osh, &di->d64rxregs->control, D64_RC_AE,
- (ae << D64_RC_AE_SHIFT));
- }
- }
-
- } else {
- if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
- if (direction == DMA_TX)
- W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow));
- else
- W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow));
- } else {
- /* dma32 address extension */
- uint32 ae;
- ASSERT(di->addrext);
-
- /* shift the high bit(s) from pa to ae */
- ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
- pa &= ~PCI32ADDR_HIGH;
-
- if (direction == DMA_TX) {
- W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow));
- SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <<XC_AE_SHIFT);
- } else {
- W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow));
- SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <<RC_AE_SHIFT);
- }
- }
+_dma_ddtable_init (dma_info_t * di, uint direction, ulong pa)
+{
+ if (DMA64_ENAB (di))
+ {
+
+ if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH))
+ {
+ if (direction == DMA_TX)
+ {
+ W_REG (di->osh, &di->d64txregs->addrlow,
+ (pa + di->ddoffsetlow));
+ W_REG (di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh);
+ }
+ else
+ {
+ W_REG (di->osh, &di->d64rxregs->addrlow,
+ (pa + di->ddoffsetlow));
+ W_REG (di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh);
+ }
+ }
+ else
+ {
+ /* DMA64 32bits address extension */
+ uint32 ae;
+ ASSERT (di->addrext);
+
+ /* shift the high bit(s) from pa to ae */
+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ pa &= ~PCI32ADDR_HIGH;
+
+ if (direction == DMA_TX)
+ {
+ W_REG (di->osh, &di->d64txregs->addrlow,
+ (pa + di->ddoffsetlow));
+ W_REG (di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh);
+ SET_REG (di->osh, &di->d64txregs->control, D64_XC_AE,
+ (ae << D64_XC_AE_SHIFT));
+ }
+ else
+ {
+ W_REG (di->osh, &di->d64rxregs->addrlow,
+ (pa + di->ddoffsetlow));
+ W_REG (di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh);
+ SET_REG (di->osh, &di->d64rxregs->control, D64_RC_AE,
+ (ae << D64_RC_AE_SHIFT));
+ }
+ }
+
+ }
+ else
+ {
+ if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH))
+ {
+ if (direction == DMA_TX)
+ W_REG (di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow));
+ else
+ W_REG (di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow));
}
+ else
+ {
+ /* dma32 address extension */
+ uint32 ae;
+ ASSERT (di->addrext);
+
+ /* shift the high bit(s) from pa to ae */
+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ pa &= ~PCI32ADDR_HIGH;
+
+ if (direction == DMA_TX)
+ {
+ W_REG (di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow));
+ SET_REG (di->osh, &di->d32txregs->control, XC_AE,
+ ae << XC_AE_SHIFT);
+ }
+ else
+ {
+ W_REG (di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow));
+ SET_REG (di->osh, &di->d32rxregs->control, RC_AE,
+ ae << RC_AE_SHIFT);
+ }
+ }
+ }
}
static void
-_dma_fifoloopbackenable(dma_info_t *di)
+_dma_fifoloopbackenable (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
- if (DMA64_ENAB(di))
- OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE);
- else
- OR_REG(di->osh, &di->d32txregs->control, XC_LE);
+ DMA_TRACE (("%s: dma_fifoloopbackenable\n", di->name));
+ if (DMA64_ENAB (di))
+ OR_REG (di->osh, &di->d64txregs->control, D64_XC_LE);
+ else
+ OR_REG (di->osh, &di->d32txregs->control, XC_LE);
}
static void
-_dma_rxinit(dma_info_t *di)
+_dma_rxinit (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_rxinit\n", di->name));
+ DMA_TRACE (("%s: dma_rxinit\n", di->name));
- if (di->nrxd == 0)
- return;
+ if (di->nrxd == 0)
+ return;
- di->rxin = di->rxout = 0;
+ di->rxin = di->rxout = 0;
- /* clear rx descriptor ring */
- if (DMA64_ENAB(di)) {
- BZERO_SM((void *)(uintptr)di->rxd64, (di->nrxd * sizeof(dma64dd_t)));
- _dma_rxenable(di);
- _dma_ddtable_init(di, DMA_RX, di->rxdpa);
- } else {
- BZERO_SM((void *)(uintptr)di->rxd32, (di->nrxd * sizeof(dma32dd_t)));
- _dma_rxenable(di);
- _dma_ddtable_init(di, DMA_RX, di->rxdpa);
- }
+ /* clear rx descriptor ring */
+ if (DMA64_ENAB (di))
+ BZERO_SM ((void *) (uintptr) di->rxd64, (di->nrxd * sizeof (dma64dd_t)));
+ else
+ BZERO_SM ((void *) (uintptr) di->rxd32, (di->nrxd * sizeof (dma32dd_t)));
+
+ _dma_rxenable (di);
+ _dma_ddtable_init (di, DMA_RX, di->rxdpa);
}
static void
-_dma_rxenable(dma_info_t *di)
+_dma_rxenable (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_rxenable\n", di->name));
-
- if (DMA64_ENAB(di))
- W_REG(di->osh, &di->d64rxregs->control,
- ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE));
- else
- W_REG(di->osh, &di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
+ DMA_TRACE (("%s: dma_rxenable\n", di->name));
+
+ if (DMA64_ENAB (di))
+ W_REG (di->osh, &di->d64rxregs->control,
+ ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE));
+ else
+ W_REG (di->osh, &di->d32rxregs->control,
+ ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
}
/* !! rx entry routine, returns a pointer to the next frame received,
* or NULL if there are no more
*/
static void *
-_dma_rx(dma_info_t *di)
-{
- void *p;
- uint len;
- int skiplen = 0;
-
- while ((p = _dma_getnextrxp(di, FALSE))) {
- /* skip giant packets which span multiple rx descriptors */
- if (skiplen > 0) {
- skiplen -= di->rxbufsize;
- if (skiplen < 0)
- skiplen = 0;
- PKTFREE(di->osh, p, FALSE);
- continue;
- }
-
- len = ltoh16(*(uint16*)(PKTDATA(di->osh, p)));
- DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
-
- /* bad frame length check */
- if (len > (di->rxbufsize - di->rxoffset)) {
- DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len));
- if (len > 0)
- skiplen = len - (di->rxbufsize - di->rxoffset);
- PKTFREE(di->osh, p, FALSE);
- di->hnddma.rxgiants++;
- continue;
- }
-
- /* set actual length */
- PKTSETLEN(di->osh, p, (di->rxoffset + len));
-
- break;
+_dma_rx (dma_info_t * di)
+{
+ void *p;
+ uint len;
+ int skiplen = 0;
+
+ while ((p = _dma_getnextrxp (di, FALSE)))
+ {
+ /* skip giant packets which span multiple rx descriptors */
+ if (skiplen > 0)
+ {
+ skiplen -= di->rxbufsize;
+ if (skiplen < 0)
+ skiplen = 0;
+ PKTFREE (di->osh, p, FALSE);
+ continue;
+ }
+
+ len = ltoh16 (*(uint16 *) (PKTDATA (di->osh, p)));
+ DMA_TRACE (("%s: dma_rx len %d\n", di->name, len));
+
+ /* bad frame length check */
+ if (len > (di->rxbufsize - di->rxoffset))
+ {
+ DMA_ERROR (("%s: dma_rx: bad frame length (%d)\n", di->name, len));
+ if (len > 0)
+ skiplen = len - (di->rxbufsize - di->rxoffset);
+ PKTFREE (di->osh, p, FALSE);
+ di->hnddma.rxgiants++;
+ continue;
}
- return (p);
+ /* set actual length */
+ PKTSETLEN (di->osh, p, (di->rxoffset + len));
+
+ break;
+ }
+
+ return (p);
}
/* post receive buffers */
static void
-_dma_rxfill(dma_info_t *di)
-{
- void *p;
- uint rxin, rxout;
- uint32 flags = 0;
- uint n;
- uint i;
- uint32 pa;
- uint extra_offset = 0;
-
- /*
- * Determine how many receive buffers we're lacking
- * from the full complement, allocate, initialize,
- * and post them, then update the chip rx lastdscr.
- */
-
- rxin = di->rxin;
- rxout = di->rxout;
-
- n = di->nrxpost - NRXDACTIVE(rxin, rxout);
-
- DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
-
- if (di->rxbufsize > BCMEXTRAHDROOM)
- extra_offset = BCMEXTRAHDROOM;
-
- for (i = 0; i < n; i++) {
- /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
- size to be allocated
- */
- if ((p = PKTGET(di->osh, di->rxbufsize + extra_offset,
- FALSE)) == NULL) {
- DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
- di->hnddma.rxnobuf++;
- break;
- }
- /* reserve an extra headroom, if applicable */
- if (extra_offset)
- PKTPULL(di->osh, p, extra_offset);
-
- /* Do a cached write instead of uncached write since DMA_MAP
- * will flush the cache.
- */
- *(uint32*)(PKTDATA(di->osh, p)) = 0;
-
- pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p),
- di->rxbufsize, DMA_RX, p);
-
- ASSERT(ISALIGNED(pa, 4));
-
- /* save the free packet pointer */
- ASSERT(di->rxp[rxout] == NULL);
- di->rxp[rxout] = p;
-
- /* reset flags for each descriptor */
- flags = 0;
- if (DMA64_ENAB(di)) {
- if (rxout == (di->nrxd - 1))
- flags = D64_CTRL1_EOT;
-
- dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, di->rxbufsize);
- } else {
- if (rxout == (di->nrxd - 1))
- flags = CTRL_EOT;
-
- dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize);
- }
- rxout = NEXTRXD(rxout);
+_dma_rxfill (dma_info_t * di)
+{
+ void *p;
+ uint rxin, rxout;
+ uint32 flags = 0;
+ uint n;
+ uint i;
+ uint32 pa;
+ uint extra_offset = 0;
+
+ /*
+ * Determine how many receive buffers we're lacking
+ * from the full complement, allocate, initialize,
+ * and post them, then update the chip rx lastdscr.
+ */
+
+ rxin = di->rxin;
+ rxout = di->rxout;
+
+ n = di->nrxpost - NRXDACTIVE (rxin, rxout);
+
+ DMA_TRACE (("%s: dma_rxfill: post %d\n", di->name, n));
+
+ if (di->rxbufsize > BCMEXTRAHDROOM)
+ extra_offset = BCMEXTRAHDROOM;
+
+ for (i = 0; i < n; i++)
+ {
+ /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
+ size to be allocated
+ */
+ if ((p = PKTGET (di->osh, di->rxbufsize + extra_offset, FALSE)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_rxfill: out of rxbufs\n", di->name));
+ di->hnddma.rxnobuf++;
+ break;
}
+ /* reserve an extra headroom, if applicable */
+ if (extra_offset)
+ PKTPULL (di->osh, p, extra_offset);
- di->rxout = rxout;
+ /* Do a cached write instead of uncached write since DMA_MAP
+ * will flush the cache.
+ */
+ *(uint32 *) (PKTDATA (di->osh, p)) = 0;
- /* update the chip lastdscr pointer */
- if (DMA64_ENAB(di)) {
- W_REG(di->osh, &di->d64rxregs->ptr, I2B(rxout, dma64dd_t));
- } else {
- W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t));
- }
-}
+ pa = (uint32) DMA_MAP (di->osh, PKTDATA (di->osh, p),
+ di->rxbufsize, DMA_RX, p, &di->rxp_dmah[rxout]);
-/* like getnexttxp but no reclaim */
-static void *
-_dma_peeknexttxp(dma_info_t *di)
-{
- uint end, i;
+ ASSERT (ISALIGNED (pa, 4));
+
+ /* save the free packet pointer */
+ ASSERT (di->rxp[rxout] == NULL);
+ di->rxp[rxout] = p;
- if (di->ntxd == 0)
- return (NULL);
+ /* reset flags for each descriptor */
+ flags = 0;
+ if (DMA64_ENAB (di))
+ {
+ if (rxout == (di->nrxd - 1))
+ flags = D64_CTRL1_EOT;
- if (DMA64_ENAB(di)) {
- end = B2I(R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
- } else {
- end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
+ dma64_dd_upd (di, di->rxd64, pa, rxout, &flags, di->rxbufsize);
}
+ else
+ {
+ if (rxout == (di->nrxd - 1))
+ flags = CTRL_EOT;
- for (i = di->txin; i != end; i = NEXTTXD(i))
- if (di->txp[i])
- return (di->txp[i]);
+ dma32_dd_upd (di, di->rxd32, pa, rxout, &flags, di->rxbufsize);
+ }
+ rxout = NEXTRXD (rxout);
+ }
+
+ di->rxout = rxout;
+
+ /* update the chip lastdscr pointer */
+ if (DMA64_ENAB (di))
+ {
+ W_REG (di->osh, &di->d64rxregs->ptr, I2B (rxout, dma64dd_t));
+ }
+ else
+ {
+ W_REG (di->osh, &di->d32rxregs->ptr, I2B (rxout, dma32dd_t));
+ }
+}
- return (NULL);
+/* like getnexttxp but no reclaim */
+static void *
+_dma_peeknexttxp (dma_info_t * di)
+{
+ uint end, i;
+
+ if (di->ntxd == 0)
+ return (NULL);
+
+ if (DMA64_ENAB (di))
+ {
+ end =
+ B2I (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK,
+ dma64dd_t);
+ }
+ else
+ {
+ end =
+ B2I (R_REG (di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
+ }
+
+ for (i = di->txin; i != end; i = NEXTTXD (i))
+ if (di->txp[i])
+ return (di->txp[i]);
+
+ return (NULL);
}
static void
-_dma_rxreclaim(dma_info_t *di)
+_dma_rxreclaim (dma_info_t * di)
{
- void *p;
+ void *p;
- /* "unused local" warning suppression for OSLs that
- * define PKTFREE() without using the di->osh arg
- */
- di = di;
+ /* "unused local" warning suppression for OSLs that
+ * define PKTFREE() without using the di->osh arg
+ */
+ di = di;
- DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
+ DMA_TRACE (("%s: dma_rxreclaim\n", di->name));
- while ((p = _dma_getnextrxp(di, TRUE)))
- PKTFREE(di->osh, p, FALSE);
+ while ((p = _dma_getnextrxp (di, TRUE)))
+ PKTFREE (di->osh, p, FALSE);
}
static void *
-_dma_getnextrxp(dma_info_t *di, bool forceall)
+_dma_getnextrxp (dma_info_t * di, bool forceall)
{
- if (di->nrxd == 0)
- return (NULL);
-
- if (DMA64_ENAB(di)) {
- return dma64_getnextrxp(di, forceall);
- } else {
- return dma32_getnextrxp(di, forceall);
- }
+ if (di->nrxd == 0)
+ return (NULL);
+
+ if (DMA64_ENAB (di))
+ {
+ return dma64_getnextrxp (di, forceall);
+ }
+ else
+ {
+ return dma32_getnextrxp (di, forceall);
+ }
}
static void
-_dma_txblock(dma_info_t *di)
+_dma_txblock (dma_info_t * di)
{
- di->hnddma.txavail = 0;
+ di->hnddma.txavail = 0;
}
static void
-_dma_txunblock(dma_info_t *di)
+_dma_txunblock (dma_info_t * di)
{
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
}
static uint
-_dma_txactive(dma_info_t *di)
+_dma_txactive (dma_info_t * di)
{
- return (NTXDACTIVE(di->txin, di->txout));
+ return (NTXDACTIVE (di->txin, di->txout));
}
static void
-_dma_counterreset(dma_info_t *di)
+_dma_counterreset (dma_info_t * di)
{
- /* reset all software counter */
- di->hnddma.rxgiants = 0;
- di->hnddma.rxnobuf = 0;
- di->hnddma.txnobuf = 0;
+ /* reset all software counter */
+ di->hnddma.rxgiants = 0;
+ di->hnddma.rxnobuf = 0;
+ di->hnddma.txnobuf = 0;
}
/* get the address of the var in order to change later */
static uintptr
-_dma_getvar(dma_info_t *di, const char *name)
+_dma_getvar (dma_info_t * di, const char *name)
{
- if (!strcmp(name, "&txavail"))
- return ((uintptr) &(di->hnddma.txavail));
- else {
- ASSERT(0);
- }
- return (0);
+ if (!strcmp (name, "&txavail"))
+ return ((uintptr) & (di->hnddma.txavail));
+ else
+ {
+ ASSERT (0);
+ }
+ return (0);
}
void
-dma_txpioloopback(osl_t *osh, dma32regs_t *regs)
+dma_txpioloopback (osl_t * osh, dma32regs_t * regs)
{
- OR_REG(osh, &regs->control, XC_LE);
+ OR_REG (osh, &regs->control, XC_LE);
}
+#ifdef BCMDBG
+static void
+dma32_dumpring (dma_info_t * di, struct bcmstrbuf *b, dma32dd_t * ring,
+ uint start, uint end, uint max_num)
+{
+ uint i;
+
+ for (i = start; i != end; i = XXD ((i + 1), max_num))
+ {
+ /* in the format of high->low 8 bytes */
+ bcm_bprintf (b, "ring index %d: 0x%x %x\n", i, ring[i].addr,
+ ring[i].ctrl);
+ }
+}
+
+static void
+dma32_dumptx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ if (di->ntxd == 0)
+ return;
+
+ bcm_bprintf (b, "DMA32: txd32 %p txdpa 0x%lx txp %p txin %d txout %d "
+ "txavail %d\n", di->txd32, di->txdpa, di->txp, di->txin,
+ di->txout, di->hnddma.txavail);
+
+ bcm_bprintf (b, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n",
+ R_REG (di->osh, &di->d32txregs->control),
+ R_REG (di->osh, &di->d32txregs->addr),
+ R_REG (di->osh, &di->d32txregs->ptr),
+ R_REG (di->osh, &di->d32txregs->status));
+
+ if (dumpring && di->txd32)
+ dma32_dumpring (di, b, di->txd32, di->txin, di->txout, di->ntxd);
+}
+
+static void
+dma32_dumprx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ if (di->nrxd == 0)
+ return;
+
+ bcm_bprintf (b, "DMA32: rxd32 %p rxdpa 0x%lx rxp %p rxin %d rxout %d\n",
+ di->rxd32, di->rxdpa, di->rxp, di->rxin, di->rxout);
+
+ bcm_bprintf (b, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n",
+ R_REG (di->osh, &di->d32rxregs->control),
+ R_REG (di->osh, &di->d32rxregs->addr),
+ R_REG (di->osh, &di->d32rxregs->ptr),
+ R_REG (di->osh, &di->d32rxregs->status));
+ if (di->rxd32 && dumpring)
+ dma32_dumpring (di, b, di->rxd32, di->rxin, di->rxout, di->nrxd);
+}
+
+static void
+dma32_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ dma32_dumptx (di, b, dumpring);
+ dma32_dumprx (di, b, dumpring);
+}
+
+static void
+dma64_dumpring (dma_info_t * di, struct bcmstrbuf *b, dma64dd_t * ring,
+ uint start, uint end, uint max_num)
+{
+ uint i;
+
+ for (i = start; i != end; i = XXD ((i + 1), max_num))
+ {
+ /* in the format of high->low 16 bytes */
+ bcm_bprintf (b, "ring index %d: 0x%x %x %x %x\n",
+ i, ring[i].addrhigh, ring[i].addrlow, ring[i].ctrl2,
+ ring[i].ctrl1);
+ }
+}
+
+static void
+dma64_dumptx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ if (di->ntxd == 0)
+ return;
+
+ bcm_bprintf (b, "DMA64: txd64 %p txdpa 0x%lx txp %p txin %d txout %d "
+ "txavail %d\n", di->txd64, di->txdpa, di->txp, di->txin,
+ di->txout, di->hnddma.txavail);
+
+ bcm_bprintf (b, "xmtcontrol 0x%x xmtaddrlow 0x%x xmtaddrhigh 0x%x "
+ "xmtptr 0x%x xmtstatus0 0x%x xmtstatus1 0x%x\n",
+ R_REG (di->osh, &di->d64txregs->control),
+ R_REG (di->osh, &di->d64txregs->addrlow),
+ R_REG (di->osh, &di->d64txregs->addrhigh),
+ R_REG (di->osh, &di->d64txregs->ptr),
+ R_REG (di->osh, &di->d64txregs->status0),
+ R_REG (di->osh, &di->d64txregs->status1));
+
+ if (dumpring && di->txd64)
+ {
+ dma64_dumpring (di, b, di->txd64, di->txin, di->txout, di->ntxd);
+ }
+}
+
+static void
+dma64_dumprx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ if (di->nrxd == 0)
+ return;
+
+ bcm_bprintf (b, "DMA64: rxd64 %p rxdpa 0x%lx rxp %p rxin %d rxout %d\n",
+ di->rxd64, di->rxdpa, di->rxp, di->rxin, di->rxout);
+
+ bcm_bprintf (b, "rcvcontrol 0x%x rcvaddrlow 0x%x rcvaddrhigh 0x%x rcvptr "
+ "0x%x rcvstatus0 0x%x rcvstatus1 0x%x\n",
+ R_REG (di->osh, &di->d64rxregs->control),
+ R_REG (di->osh, &di->d64rxregs->addrlow),
+ R_REG (di->osh, &di->d64rxregs->addrhigh),
+ R_REG (di->osh, &di->d64rxregs->ptr),
+ R_REG (di->osh, &di->d64rxregs->status0),
+ R_REG (di->osh, &di->d64rxregs->status1));
+ if (di->rxd64 && dumpring)
+ {
+ dma64_dumpring (di, b, di->rxd64, di->rxin, di->rxout, di->nrxd);
+ }
+}
+
+static void
+dma64_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ dma64_dumptx (di, b, dumpring);
+ dma64_dumprx (di, b, dumpring);
+}
+
+#endif /* BCMDBG */
/* 32 bits DMA functions */
static void
-dma32_txinit(dma_info_t *di)
+dma32_txinit (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txinit\n", di->name));
+ DMA_TRACE (("%s: dma_txinit\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- di->txin = di->txout = 0;
- di->hnddma.txavail = di->ntxd - 1;
+ di->txin = di->txout = 0;
+ di->hnddma.txavail = di->ntxd - 1;
- /* clear tx descriptor ring */
- BZERO_SM((void *)(uintptr)di->txd32, (di->ntxd * sizeof(dma32dd_t)));
- W_REG(di->osh, &di->d32txregs->control, XC_XE);
- _dma_ddtable_init(di, DMA_TX, di->txdpa);
+ /* clear tx descriptor ring */
+ BZERO_SM ((void *) (uintptr) di->txd32, (di->ntxd * sizeof (dma32dd_t)));
+ W_REG (di->osh, &di->d32txregs->control, XC_XE);
+ _dma_ddtable_init (di, DMA_TX, di->txdpa);
}
static bool
-dma32_txenabled(dma_info_t *di)
+dma32_txenabled (dma_info_t * di)
{
- uint32 xc;
+ uint32 xc;
- /* If the chip is dead, it is not enabled :-) */
- xc = R_REG(di->osh, &di->d32txregs->control);
- return ((xc != 0xffffffff) && (xc & XC_XE));
+ /* If the chip is dead, it is not enabled :-) */
+ xc = R_REG (di->osh, &di->d32txregs->control);
+ return ((xc != 0xffffffff) && (xc & XC_XE));
}
static void
-dma32_txsuspend(dma_info_t *di)
+dma32_txsuspend (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+ DMA_TRACE (("%s: dma_txsuspend\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- OR_REG(di->osh, &di->d32txregs->control, XC_SE);
+ OR_REG (di->osh, &di->d32txregs->control, XC_SE);
}
static void
-dma32_txresume(dma_info_t *di)
+dma32_txresume (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txresume\n", di->name));
+ DMA_TRACE (("%s: dma_txresume\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- AND_REG(di->osh, &di->d32txregs->control, ~XC_SE);
+ AND_REG (di->osh, &di->d32txregs->control, ~XC_SE);
}
static bool
-dma32_txsuspended(dma_info_t *di)
+dma32_txsuspended (dma_info_t * di)
{
- return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE);
+ return (di->ntxd == 0)
+ || ((R_REG (di->osh, &di->d32txregs->control) & XC_SE) == XC_SE);
}
static void
-dma32_txreclaim(dma_info_t *di, bool forceall)
+dma32_txreclaim (dma_info_t * di, bool forceall)
{
- void *p;
+ void *p;
- DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
+ DMA_TRACE (("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
- while ((p = dma32_getnexttxp(di, forceall)))
- PKTFREE(di->osh, p, TRUE);
+ while ((p = dma32_getnexttxp (di, forceall)))
+ PKTFREE (di->osh, p, TRUE);
}
static bool
-dma32_txstopped(dma_info_t *di)
+dma32_txstopped (dma_info_t * di)
{
- return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED);
+ return ((R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK) ==
+ XS_XS_STOPPED);
}
static bool
-dma32_rxstopped(dma_info_t *di)
+dma32_rxstopped (dma_info_t * di)
{
- return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED);
+ return ((R_REG (di->osh, &di->d32rxregs->status) & RS_RS_MASK) ==
+ RS_RS_STOPPED);
}
static bool
-dma32_alloc(dma_info_t *di, uint direction)
-{
- uint size;
- uint ddlen;
- void *va;
-
- ddlen = sizeof(dma32dd_t);
-
- size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
-
- if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN))
- size += D32RINGALIGN;
-
-
- if (direction == DMA_TX) {
- if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) {
- DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
- di->name));
- return FALSE;
- }
-
- di->txd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN);
- di->txdalign = (uint)((int8*)(uintptr)di->txd32 - (int8*)va);
- di->txdpa += di->txdalign;
- di->txdalloc = size;
- ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN));
- } else {
- if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) {
- DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
- di->name));
- return FALSE;
- }
- di->rxd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN);
- di->rxdalign = (uint)((int8*)(uintptr)di->rxd32 - (int8*)va);
- di->rxdpa += di->rxdalign;
- di->rxdalloc = size;
- ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN));
+dma32_alloc (dma_info_t * di, uint direction)
+{
+ uint size;
+ uint ddlen;
+ void *va;
+
+ ddlen = sizeof (dma32dd_t);
+
+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+
+ if (!ISALIGNED (DMA_CONSISTENT_ALIGN, D32RINGALIGN))
+ size += D32RINGALIGN;
+
+
+ if (direction == DMA_TX)
+ {
+ if ((va =
+ DMA_ALLOC_CONSISTENT (di->osh, size, &di->txdpa,
+ &di->tx_dmah)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
+ di->name));
+ return FALSE;
}
- return TRUE;
+ di->txd32 = (dma32dd_t *) ROUNDUP ((uintptr) va, D32RINGALIGN);
+ di->txdalign = (uint) ((int8 *) (uintptr) di->txd32 - (int8 *) va);
+ di->txdpa += di->txdalign;
+ di->txdalloc = size;
+ ASSERT (ISALIGNED ((uintptr) di->txd32, D32RINGALIGN));
+ }
+ else
+ {
+ if ((va =
+ DMA_ALLOC_CONSISTENT (di->osh, size, &di->rxdpa,
+ &di->rx_dmah)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
+ di->name));
+ return FALSE;
+ }
+ di->rxd32 = (dma32dd_t *) ROUNDUP ((uintptr) va, D32RINGALIGN);
+ di->rxdalign = (uint) ((int8 *) (uintptr) di->rxd32 - (int8 *) va);
+ di->rxdpa += di->rxdalign;
+ di->rxdalloc = size;
+ ASSERT (ISALIGNED ((uintptr) di->rxd32, D32RINGALIGN));
+ }
+
+ return TRUE;
}
static bool
-dma32_txreset(dma_info_t *di)
+dma32_txreset (dma_info_t * di)
{
- uint32 status;
+ uint32 status;
- if (di->ntxd == 0)
- return TRUE;
+ if (di->ntxd == 0)
+ return TRUE;
- /* suspend tx DMA first */
- W_REG(di->osh, &di->d32txregs->control, XC_SE);
- SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK))
- != XS_XS_DISABLED) &&
- (status != XS_XS_IDLE) &&
- (status != XS_XS_STOPPED),
- (10000));
+ /* suspend tx DMA first */
+ W_REG (di->osh, &di->d32txregs->control, XC_SE);
+ SPINWAIT (((status = (R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK))
+ != XS_XS_DISABLED) &&
+ (status != XS_XS_IDLE) && (status != XS_XS_STOPPED), (10000));
- W_REG(di->osh, &di->d32txregs->control, 0);
- SPINWAIT(((status = (R_REG(di->osh,
- &di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED),
- 10000);
+ W_REG (di->osh, &di->d32txregs->control, 0);
+ SPINWAIT (((status = (R_REG (di->osh,
+ &di->d32txregs->status) & XS_XS_MASK)) !=
+ XS_XS_DISABLED), 10000);
- /* wait for the last transaction to complete */
- OSL_DELAY(300);
+ /* wait for the last transaction to complete */
+ OSL_DELAY (300);
- return (status == XS_XS_DISABLED);
+ return (status == XS_XS_DISABLED);
}
static bool
-dma32_rxidle(dma_info_t *di)
+dma32_rxidle (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_rxidle\n", di->name));
+ DMA_TRACE (("%s: dma_rxidle\n", di->name));
- if (di->nrxd == 0)
- return TRUE;
+ if (di->nrxd == 0)
+ return TRUE;
- return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) ==
- R_REG(di->osh, &di->d32rxregs->ptr));
+ return ((R_REG (di->osh, &di->d32rxregs->status) & RS_CD_MASK) ==
+ R_REG (di->osh, &di->d32rxregs->ptr));
}
static bool
-dma32_rxreset(dma_info_t *di)
+dma32_rxreset (dma_info_t * di)
{
- uint32 status;
+ uint32 status;
- if (di->nrxd == 0)
- return TRUE;
+ if (di->nrxd == 0)
+ return TRUE;
- W_REG(di->osh, &di->d32rxregs->control, 0);
- SPINWAIT(((status = (R_REG(di->osh,
- &di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED),
- 10000);
+ W_REG (di->osh, &di->d32rxregs->control, 0);
+ SPINWAIT (((status = (R_REG (di->osh,
+ &di->d32rxregs->status) & RS_RS_MASK)) !=
+ RS_RS_DISABLED), 10000);
- return (status == RS_RS_DISABLED);
+ return (status == RS_RS_DISABLED);
}
static bool
-dma32_rxenabled(dma_info_t *di)
+dma32_rxenabled (dma_info_t * di)
{
- uint32 rc;
+ uint32 rc;
- rc = R_REG(di->osh, &di->d32rxregs->control);
- return ((rc != 0xffffffff) && (rc & RC_RE));
+ rc = R_REG (di->osh, &di->d32rxregs->control);
+ return ((rc != 0xffffffff) && (rc & RC_RE));
}
static bool
-dma32_txsuspendedidle(dma_info_t *di)
+dma32_txsuspendedidle (dma_info_t * di)
{
- if (di->ntxd == 0)
- return TRUE;
+ if (di->ntxd == 0)
+ return TRUE;
- if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE))
- return 0;
+ if (!(R_REG (di->osh, &di->d32txregs->control) & XC_SE))
+ return 0;
- if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
- return 0;
+ if ((R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
+ return 0;
- OSL_DELAY(2);
- return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE);
+ OSL_DELAY (2);
+ return ((R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK) ==
+ XS_XS_IDLE);
}
/* !! tx entry routine
@@ -1171,77 +1518,81 @@ dma32_txsuspendedidle(dma_info_t *di)
* dma buffers can cross 4 Kbyte page boundaries.
*/
static int
-dma32_txfast(dma_info_t *di, void *p0, bool commit)
-{
- void *p, *next;
- uchar *data;
- uint len;
- uint txout;
- uint32 flags = 0;
- uint32 pa;
-
- DMA_TRACE(("%s: dma_txfast\n", di->name));
-
- txout = di->txout;
-
- /*
- * Walk the chain of packet buffers
- * allocating and initializing transmit descriptor entries.
- */
- for (p = p0; p; p = next) {
- data = PKTDATA(di->osh, p);
- len = PKTLEN(di->osh, p);
- next = PKTNEXT(di->osh, p);
-
- /* return nonzero if out of tx descriptors */
- if (NEXTTXD(txout) == di->txin)
- goto outoftxd;
-
- if (len == 0)
- continue;
-
- /* get physical address of buffer start */
- pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p);
-
- flags = 0;
- if (p == p0)
- flags |= CTRL_SOF;
- if (next == NULL)
- flags |= (CTRL_IOC | CTRL_EOF);
- if (txout == (di->ntxd - 1))
- flags |= CTRL_EOT;
-
- dma32_dd_upd(di, di->txd32, pa, txout, &flags, len);
- ASSERT(di->txp[txout] == NULL);
-
- txout = NEXTTXD(txout);
- }
+dma32_txfast (dma_info_t * di, void *p0, bool commit)
+{
+ void *p, *next;
+ uchar *data;
+ uint len;
+ uint txout;
+ uint32 flags = 0;
+ uint32 pa;
+
+ DMA_TRACE (("%s: dma_txfast\n", di->name));
+
+ txout = di->txout;
+
+ /*
+ * Walk the chain of packet buffers
+ * allocating and initializing transmit descriptor entries.
+ */
+ for (p = p0; p; p = next)
+ {
+ data = PKTDATA (di->osh, p);
+ len = PKTLEN (di->osh, p);
+ next = PKTNEXT (di->osh, p);
+
+ /* return nonzero if out of tx descriptors */
+ if (NEXTTXD (txout) == di->txin)
+ goto outoftxd;
+
+ if (len == 0)
+ continue;
+
+ /* get physical address of buffer start */
+ pa =
+ (uint32) DMA_MAP (di->osh, data, len, DMA_TX, p,
+ &di->txp_dmah[txout]);
+
+ flags = 0;
+ if (p == p0)
+ flags |= CTRL_SOF;
+ if (next == NULL)
+ flags |= (CTRL_IOC | CTRL_EOF);
+ if (txout == (di->ntxd - 1))
+ flags |= CTRL_EOT;
- /* if last txd eof not set, fix it */
- if (!(flags & CTRL_EOF))
- W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF));
+ dma32_dd_upd (di, di->txd32, pa, txout, &flags, len);
+ ASSERT (di->txp[txout] == NULL);
- /* save the packet */
- di->txp[PREVTXD(txout)] = p0;
+ txout = NEXTTXD (txout);
+ }
- /* bump the tx descriptor index */
- di->txout = txout;
+ /* if last txd eof not set, fix it */
+ if (!(flags & CTRL_EOF))
+ W_SM (&di->txd32[PREVTXD (txout)].ctrl,
+ BUS_SWAP32 (flags | CTRL_IOC | CTRL_EOF));
- /* kick the chip */
- if (commit)
- W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t));
+ /* save the packet */
+ di->txp[PREVTXD (txout)] = p0;
- /* tx flow control */
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ /* bump the tx descriptor index */
+ di->txout = txout;
- return (0);
+ /* kick the chip */
+ if (commit)
+ W_REG (di->osh, &di->d32txregs->ptr, I2B (txout, dma32dd_t));
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
+
+ return (0);
outoftxd:
- DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
- PKTFREE(di->osh, p0, TRUE);
- di->hnddma.txavail = 0;
- di->hnddma.txnobuf++;
- return (-1);
+ DMA_ERROR (("%s: dma_txfast: out of txds\n", di->name));
+ PKTFREE (di->osh, p0, TRUE);
+ di->hnddma.txavail = 0;
+ di->hnddma.txnobuf++;
+ return (-1);
}
/*
@@ -1251,431 +1602,456 @@ outoftxd:
* regardless of the value of the hardware "curr" pointer.
*/
static void *
-dma32_getnexttxp(dma_info_t *di, bool forceall)
+dma32_getnexttxp (dma_info_t * di, bool forceall)
{
- uint start, end, i;
- void *txp;
+ uint start, end, i;
+ void *txp;
- DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
+ DMA_TRACE (("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
- if (di->ntxd == 0)
- return (NULL);
+ if (di->ntxd == 0)
+ return (NULL);
- txp = NULL;
+ txp = NULL;
- start = di->txin;
- if (forceall)
- end = di->txout;
- else
- end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
+ start = di->txin;
+ if (forceall)
+ end = di->txout;
+ else
+ end =
+ B2I (R_REG (di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
- if ((start == 0) && (end > di->txout))
- goto bogus;
+ if ((start == 0) && (end > di->txout))
+ goto bogus;
- for (i = start; i != end && !txp; i = NEXTTXD(i)) {
- DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow),
- (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK),
- DMA_TX, di->txp[i]);
+ for (i = start; i != end && !txp; i = NEXTTXD (i))
+ {
+ DMA_UNMAP (di->osh,
+ (BUS_SWAP32 (R_SM (&di->txd32[i].addr)) - di->dataoffsetlow),
+ (BUS_SWAP32 (R_SM (&di->txd32[i].ctrl)) & CTRL_BC_MASK),
+ DMA_TX, di->txp[i], &di->txp_dmah[i]);
- W_SM(&di->txd32[i].addr, 0xdeadbeef);
- txp = di->txp[i];
- di->txp[i] = NULL;
- }
+ W_SM (&di->txd32[i].addr, 0xdeadbeef);
+ txp = di->txp[i];
+ di->txp[i] = NULL;
+ }
- di->txin = i;
+ di->txin = i;
- /* tx flow control */
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
- return (txp);
+ return (txp);
bogus:
/*
DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
start, end, di->txout, forceall));
*/
- return (NULL);
+ return (NULL);
}
static void *
-dma32_getnextrxp(dma_info_t *di, bool forceall)
+dma32_getnextrxp (dma_info_t * di, bool forceall)
{
- uint i;
- void *rxp;
+ uint i;
+ void *rxp;
- /* if forcing, dma engine must be disabled */
- ASSERT(!forceall || !dma32_rxenabled(di));
+ /* if forcing, dma engine must be disabled */
+ ASSERT (!forceall || !dma32_rxenabled (di));
- i = di->rxin;
+ i = di->rxin;
- /* return if no packets posted */
- if (i == di->rxout)
- return (NULL);
+ /* return if no packets posted */
+ if (i == di->rxout)
+ return (NULL);
- /* ignore curr if forceall */
- if (!forceall && (i == B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t)))
- return (NULL);
+ /* ignore curr if forceall */
+ if (!forceall
+ && (i ==
+ B2I (R_REG (di->osh, &di->d32rxregs->status) & RS_CD_MASK,
+ dma32dd_t)))
+ return (NULL);
- /* get the packet pointer that corresponds to the rx descriptor */
- rxp = di->rxp[i];
- ASSERT(rxp);
- di->rxp[i] = NULL;
+ /* get the packet pointer that corresponds to the rx descriptor */
+ rxp = di->rxp[i];
+ ASSERT (rxp);
+ di->rxp[i] = NULL;
- /* clear this packet from the descriptor ring */
- DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow),
- di->rxbufsize, DMA_RX, rxp);
+ /* clear this packet from the descriptor ring */
+ DMA_UNMAP (di->osh,
+ (BUS_SWAP32 (R_SM (&di->rxd32[i].addr)) - di->dataoffsetlow),
+ di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]);
- W_SM(&di->rxd32[i].addr, 0xdeadbeef);
+ W_SM (&di->rxd32[i].addr, 0xdeadbeef);
- di->rxin = NEXTRXD(i);
+ di->rxin = NEXTRXD (i);
- return (rxp);
+ return (rxp);
}
/*
* Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
*/
static void
-dma32_txrotate(dma_info_t *di)
+dma32_txrotate (dma_info_t * di)
{
- uint ad;
- uint nactive;
- uint rot;
- uint old, new;
- uint32 w;
- uint first, last;
-
- ASSERT(dma32_txsuspendedidle(di));
-
- nactive = _dma_txactive(di);
- ad = B2I(((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t);
- rot = TXD(ad - di->txin);
-
- ASSERT(rot < di->ntxd);
-
- /* full-ring case is a lot harder - don't worry about this */
- if (rot >= (di->ntxd - nactive)) {
- DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
- return;
- }
-
- first = di->txin;
- last = PREVTXD(di->txout);
-
- /* move entries starting at last and moving backwards to first */
- for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
- new = TXD(old + rot);
-
- /*
- * Move the tx dma descriptor.
- * EOT is set only in the last entry in the ring.
- */
- w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT;
- if (new == (di->ntxd - 1))
- w |= CTRL_EOT;
- W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w));
- W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr));
-
- /* zap the old tx dma descriptor address field */
- W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef));
-
- /* move the corresponding txp[] entry */
- ASSERT(di->txp[new] == NULL);
- di->txp[new] = di->txp[old];
- di->txp[old] = NULL;
- }
-
- /* update txin and txout */
- di->txin = ad;
- di->txout = TXD(di->txout + rot);
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-
- /* kick the chip */
- W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t));
+ uint ad;
+ uint nactive;
+ uint rot;
+ uint old, new;
+ uint32 w;
+ uint first, last;
+
+ ASSERT (dma32_txsuspendedidle (di));
+
+ nactive = _dma_txactive (di);
+ ad =
+ B2I (((R_REG (di->osh, &di->d32txregs->status) & XS_AD_MASK) >>
+ XS_AD_SHIFT), dma32dd_t);
+ rot = TXD (ad - di->txin);
+
+ ASSERT (rot < di->ntxd);
+
+ /* full-ring case is a lot harder - don't worry about this */
+ if (rot >= (di->ntxd - nactive))
+ {
+ DMA_ERROR (("%s: dma_txrotate: ring full - punt\n", di->name));
+ return;
+ }
+
+ first = di->txin;
+ last = PREVTXD (di->txout);
+
+ /* move entries starting at last and moving backwards to first */
+ for (old = last; old != PREVTXD (first); old = PREVTXD (old))
+ {
+ new = TXD (old + rot);
+
+ /*
+ * Move the tx dma descriptor.
+ * EOT is set only in the last entry in the ring.
+ */
+ w = BUS_SWAP32 (R_SM (&di->txd32[old].ctrl)) & ~CTRL_EOT;
+ if (new == (di->ntxd - 1))
+ w |= CTRL_EOT;
+ W_SM (&di->txd32[new].ctrl, BUS_SWAP32 (w));
+ W_SM (&di->txd32[new].addr, R_SM (&di->txd32[old].addr));
+
+ /* zap the old tx dma descriptor address field */
+ W_SM (&di->txd32[old].addr, BUS_SWAP32 (0xdeadbeef));
+
+ /* move the corresponding txp[] entry */
+ ASSERT (di->txp[new] == NULL);
+ di->txp[new] = di->txp[old];
+ di->txp[old] = NULL;
+ }
+
+ /* update txin and txout */
+ di->txin = ad;
+ di->txout = TXD (di->txout + rot);
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
+
+ /* kick the chip */
+ W_REG (di->osh, &di->d32txregs->ptr, I2B (di->txout, dma32dd_t));
}
/* 64 bits DMA functions */
#ifdef BCMDMA64
static void
-dma64_txinit(dma_info_t *di)
+dma64_txinit (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txinit\n", di->name));
+ DMA_TRACE (("%s: dma_txinit\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- di->txin = di->txout = 0;
- di->hnddma.txavail = di->ntxd - 1;
+ di->txin = di->txout = 0;
+ di->hnddma.txavail = di->ntxd - 1;
- /* clear tx descriptor ring */
- BZERO_SM((void *)(uintptr)di->txd64, (di->ntxd * sizeof(dma64dd_t)));
- W_REG(di->osh, &di->d64txregs->control, D64_XC_XE);
- _dma_ddtable_init(di, DMA_TX, di->txdpa);
+ /* clear tx descriptor ring */
+ BZERO_SM ((void *) (uintptr) di->txd64, (di->ntxd * sizeof (dma64dd_t)));
+ W_REG (di->osh, &di->d64txregs->control, D64_XC_XE);
+ _dma_ddtable_init (di, DMA_TX, di->txdpa);
}
static bool
-dma64_txenabled(dma_info_t *di)
+dma64_txenabled (dma_info_t * di)
{
- uint32 xc;
+ uint32 xc;
- /* If the chip is dead, it is not enabled :-) */
- xc = R_REG(di->osh, &di->d64txregs->control);
- return ((xc != 0xffffffff) && (xc & D64_XC_XE));
+ /* If the chip is dead, it is not enabled :-) */
+ xc = R_REG (di->osh, &di->d64txregs->control);
+ return ((xc != 0xffffffff) && (xc & D64_XC_XE));
}
static void
-dma64_txsuspend(dma_info_t *di)
+dma64_txsuspend (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+ DMA_TRACE (("%s: dma_txsuspend\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE);
+ OR_REG (di->osh, &di->d64txregs->control, D64_XC_SE);
}
static void
-dma64_txresume(dma_info_t *di)
+dma64_txresume (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txresume\n", di->name));
+ DMA_TRACE (("%s: dma_txresume\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_SE);
+ AND_REG (di->osh, &di->d64txregs->control, ~D64_XC_SE);
}
static bool
-dma64_txsuspended(dma_info_t *di)
+dma64_txsuspended (dma_info_t * di)
{
- return (di->ntxd == 0) || ((R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE)
- == D64_XC_SE);
+ return (di->ntxd == 0)
+ || ((R_REG (di->osh, &di->d64txregs->control) & D64_XC_SE) == D64_XC_SE);
}
static void
-dma64_txreclaim(dma_info_t *di, bool forceall)
+dma64_txreclaim (dma_info_t * di, bool forceall)
{
- void *p;
+ void *p;
- DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
+ DMA_TRACE (("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
- while ((p = dma64_getnexttxp(di, forceall)))
- PKTFREE(di->osh, p, TRUE);
+ while ((p = dma64_getnexttxp (di, forceall)))
+ PKTFREE (di->osh, p, TRUE);
}
static bool
-dma64_txstopped(dma_info_t *di)
+dma64_txstopped (dma_info_t * di)
{
- return ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED);
+ return ((R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+ D64_XS0_XS_STOPPED);
}
static bool
-dma64_rxstopped(dma_info_t *di)
+dma64_rxstopped (dma_info_t * di)
{
- return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED);
+ return ((R_REG (di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
+ D64_RS0_RS_STOPPED);
}
static bool
-dma64_alloc(dma_info_t *di, uint direction)
-{
- uint size;
- uint ddlen;
- uint32 alignbytes;
- void *va;
-
- ddlen = sizeof(dma64dd_t);
-
- size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
-
- alignbytes = di->dma64align;
-
- if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes))
- size += alignbytes;
-
- if (direction == DMA_TX) {
- if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) {
- DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
- di->name));
- return FALSE;
- }
-
- di->txd64 = (dma64dd_t *) ROUNDUP((uintptr)va, alignbytes);
- di->txdalign = (uint)((int8*)(uintptr)di->txd64 - (int8*)va);
- di->txdpa += di->txdalign;
- di->txdalloc = size;
- ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes));
- } else {
- if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) {
- DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
- di->name));
- return FALSE;
- }
- di->rxd64 = (dma64dd_t *) ROUNDUP((uintptr)va, alignbytes);
- di->rxdalign = (uint)((int8*)(uintptr)di->rxd64 - (int8*)va);
- di->rxdpa += di->rxdalign;
- di->rxdalloc = size;
- ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes));
+dma64_alloc (dma_info_t * di, uint direction)
+{
+ uint size;
+ uint ddlen;
+ uint32 alignbytes;
+ void *va;
+
+ ddlen = sizeof (dma64dd_t);
+
+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+
+ alignbytes = di->dma64align;
+
+ if (!ISALIGNED (DMA_CONSISTENT_ALIGN, alignbytes))
+ size += alignbytes;
+
+ if (direction == DMA_TX)
+ {
+ if ((va =
+ DMA_ALLOC_CONSISTENT (di->osh, size, &di->txdpa,
+ &di->tx_dmah)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
+ di->name));
+ return FALSE;
}
- return TRUE;
+ di->txd64 = (dma64dd_t *) ROUNDUP ((uintptr) va, alignbytes);
+ di->txdalign = (uint) ((int8 *) (uintptr) di->txd64 - (int8 *) va);
+ di->txdpa += di->txdalign;
+ di->txdalloc = size;
+ ASSERT (ISALIGNED ((uintptr) di->txd64, alignbytes));
+ }
+ else
+ {
+ if ((va =
+ DMA_ALLOC_CONSISTENT (di->osh, size, &di->rxdpa,
+ &di->rx_dmah)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
+ di->name));
+ return FALSE;
+ }
+ di->rxd64 = (dma64dd_t *) ROUNDUP ((uintptr) va, alignbytes);
+ di->rxdalign = (uint) ((int8 *) (uintptr) di->rxd64 - (int8 *) va);
+ di->rxdpa += di->rxdalign;
+ di->rxdalloc = size;
+ ASSERT (ISALIGNED ((uintptr) di->rxd64, alignbytes));
+ }
+
+ return TRUE;
}
static bool
-dma64_txreset(dma_info_t *di)
+dma64_txreset (dma_info_t * di)
{
- uint32 status;
+ uint32 status;
- if (di->ntxd == 0)
- return TRUE;
+ if (di->ntxd == 0)
+ return TRUE;
- /* suspend tx DMA first */
- W_REG(di->osh, &di->d64txregs->control, D64_XC_SE);
- SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) !=
- D64_XS0_XS_DISABLED) &&
- (status != D64_XS0_XS_IDLE) &&
- (status != D64_XS0_XS_STOPPED),
- 10000);
+ /* suspend tx DMA first */
+ W_REG (di->osh, &di->d64txregs->control, D64_XC_SE);
+ SPINWAIT (((status =
+ (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) !=
+ D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
+ && (status != D64_XS0_XS_STOPPED), 10000);
- W_REG(di->osh, &di->d64txregs->control, 0);
- SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) !=
- D64_XS0_XS_DISABLED),
- 10000);
+ W_REG (di->osh, &di->d64txregs->control, 0);
+ SPINWAIT (((status =
+ (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) !=
+ D64_XS0_XS_DISABLED), 10000);
- /* wait for the last transaction to complete */
- OSL_DELAY(300);
+ /* wait for the last transaction to complete */
+ OSL_DELAY (300);
- return (status == D64_XS0_XS_DISABLED);
+ return (status == D64_XS0_XS_DISABLED);
}
static bool
-dma64_rxidle(dma_info_t *di)
+dma64_rxidle (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_rxidle\n", di->name));
+ DMA_TRACE (("%s: dma_rxidle\n", di->name));
- if (di->nrxd == 0)
- return TRUE;
+ if (di->nrxd == 0)
+ return TRUE;
- return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
- R_REG(di->osh, &di->d64rxregs->ptr));
+ return ((R_REG (di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
+ R_REG (di->osh, &di->d64rxregs->ptr));
}
static bool
-dma64_rxreset(dma_info_t *di)
+dma64_rxreset (dma_info_t * di)
{
- uint32 status;
+ uint32 status;
- if (di->nrxd == 0)
- return TRUE;
+ if (di->nrxd == 0)
+ return TRUE;
- W_REG(di->osh, &di->d64rxregs->control, 0);
- SPINWAIT(((status = (R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK)) !=
- D64_RS0_RS_DISABLED),
- 10000);
+ W_REG (di->osh, &di->d64rxregs->control, 0);
+ SPINWAIT (((status =
+ (R_REG (di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK)) !=
+ D64_RS0_RS_DISABLED), 10000);
- return (status == D64_RS0_RS_DISABLED);
+ return (status == D64_RS0_RS_DISABLED);
}
static bool
-dma64_rxenabled(dma_info_t *di)
+dma64_rxenabled (dma_info_t * di)
{
- uint32 rc;
+ uint32 rc;
- rc = R_REG(di->osh, &di->d64rxregs->control);
- return ((rc != 0xffffffff) && (rc & D64_RC_RE));
+ rc = R_REG (di->osh, &di->d64rxregs->control);
+ return ((rc != 0xffffffff) && (rc & D64_RC_RE));
}
static bool
-dma64_txsuspendedidle(dma_info_t *di)
+dma64_txsuspendedidle (dma_info_t * di)
{
- if (di->ntxd == 0)
- return TRUE;
+ if (di->ntxd == 0)
+ return TRUE;
- if (!(R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE))
- return 0;
+ if (!(R_REG (di->osh, &di->d64txregs->control) & D64_XC_SE))
+ return 0;
- if ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE)
- return 1;
+ if ((R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+ D64_XS0_XS_IDLE)
+ return 1;
- return 0;
+ return 0;
}
/* !! tx entry routine */
static int
-dma64_txfast(dma_info_t *di, void *p0, bool commit)
-{
- void *p, *next;
- uchar *data;
- uint len;
- uint txout;
- uint32 flags = 0;
- uint32 pa;
-
- DMA_TRACE(("%s: dma_txfast\n", di->name));
-
- txout = di->txout;
-
- /*
- * Walk the chain of packet buffers
- * allocating and initializing transmit descriptor entries.
- */
- for (p = p0; p; p = next) {
- data = PKTDATA(di->osh, p);
- len = PKTLEN(di->osh, p);
- next = PKTNEXT(di->osh, p);
-
- /* return nonzero if out of tx descriptors */
- if (NEXTTXD(txout) == di->txin)
- goto outoftxd;
-
- if (len == 0)
- continue;
-
- /* get physical address of buffer start */
- pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p);
-
- flags = 0;
- if (p == p0)
- flags |= D64_CTRL1_SOF;
- if (next == NULL)
- flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
- if (txout == (di->ntxd - 1))
- flags |= D64_CTRL1_EOT;
-
- dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
- ASSERT(di->txp[txout] == NULL);
-
- txout = NEXTTXD(txout);
- }
+dma64_txfast (dma_info_t * di, void *p0, bool commit)
+{
+ void *p, *next;
+ uchar *data;
+ uint len;
+ uint txout;
+ uint32 flags = 0;
+ uint32 pa;
- /* if last txd eof not set, fix it */
- if (!(flags & D64_CTRL1_EOF))
- W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
- BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
+ DMA_TRACE (("%s: dma_txfast\n", di->name));
- /* save the packet */
- di->txp[PREVTXD(txout)] = p0;
+ txout = di->txout;
- /* bump the tx descriptor index */
- di->txout = txout;
+ /*
+ * Walk the chain of packet buffers
+ * allocating and initializing transmit descriptor entries.
+ */
+ for (p = p0; p; p = next)
+ {
+ data = PKTDATA (di->osh, p);
+ len = PKTLEN (di->osh, p);
+ next = PKTNEXT (di->osh, p);
- /* kick the chip */
- if (commit)
- W_REG(di->osh, &di->d64txregs->ptr, I2B(txout, dma64dd_t));
+ /* return nonzero if out of tx descriptors */
+ if (NEXTTXD (txout) == di->txin)
+ goto outoftxd;
- /* tx flow control */
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ if (len == 0)
+ continue;
- return (0);
+ /* get physical address of buffer start */
+ pa =
+ (uint32) DMA_MAP (di->osh, data, len, DMA_TX, p,
+ &di->txp_dmah[txout]);
+
+ flags = 0;
+ if (p == p0)
+ flags |= D64_CTRL1_SOF;
+ if (next == NULL)
+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
+ if (txout == (di->ntxd - 1))
+ flags |= D64_CTRL1_EOT;
+
+ dma64_dd_upd (di, di->txd64, pa, txout, &flags, len);
+ ASSERT (di->txp[txout] == NULL);
+
+ txout = NEXTTXD (txout);
+ }
+
+ /* if last txd eof not set, fix it */
+ if (!(flags & D64_CTRL1_EOF))
+ W_SM (&di->txd64[PREVTXD (txout)].ctrl1,
+ BUS_SWAP32 (flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
+
+ /* save the packet */
+ di->txp[PREVTXD (txout)] = p0;
+
+ /* bump the tx descriptor index */
+ di->txout = txout;
+
+ /* kick the chip */
+ if (commit)
+ W_REG (di->osh, &di->d64txregs->ptr, I2B (txout, dma64dd_t));
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
+
+ return (0);
outoftxd:
- DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
- PKTFREE(di->osh, p0, TRUE);
- di->hnddma.txavail = 0;
- di->hnddma.txnobuf++;
- return (-1);
+ DMA_ERROR (("%s: dma_txfast: out of txds\n", di->name));
+ PKTFREE (di->osh, p0, TRUE);
+ di->hnddma.txavail = 0;
+ di->hnddma.txnobuf++;
+ return (-1);
}
/*
@@ -1685,209 +2061,221 @@ outoftxd:
* regardless of the value of the hardware "curr" pointer.
*/
static void *
-dma64_getnexttxp(dma_info_t *di, bool forceall)
+dma64_getnexttxp (dma_info_t * di, bool forceall)
{
- uint start, end, i;
- void *txp;
+ uint start, end, i;
+ void *txp;
- DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
+ DMA_TRACE (("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
- if (di->ntxd == 0)
- return (NULL);
+ if (di->ntxd == 0)
+ return (NULL);
- txp = NULL;
+ txp = NULL;
- start = di->txin;
- if (forceall)
- end = di->txout;
- else
- end = B2I(R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
+ start = di->txin;
+ if (forceall)
+ end = di->txout;
+ else
+ end =
+ B2I (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK,
+ dma64dd_t);
- if ((start == 0) && (end > di->txout))
- goto bogus;
+ if ((start == 0) && (end > di->txout))
+ goto bogus;
- for (i = start; i != end && !txp; i = NEXTTXD(i)) {
- DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow),
- (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK),
- DMA_TX, di->txp[i]);
+ for (i = start; i != end && !txp; i = NEXTTXD (i))
+ {
+ DMA_UNMAP (di->osh,
+ (BUS_SWAP32 (R_SM (&di->txd64[i].addrlow)) -
+ di->dataoffsetlow),
+ (BUS_SWAP32 (R_SM (&di->txd64[i].ctrl2)) &
+ D64_CTRL2_BC_MASK), DMA_TX, di->txp[i], &di->txp_dmah[i]);
- W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
- W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
+ W_SM (&di->txd64[i].addrlow, 0xdeadbeef);
+ W_SM (&di->txd64[i].addrhigh, 0xdeadbeef);
- txp = di->txp[i];
- di->txp[i] = NULL;
- }
+ txp = di->txp[i];
+ di->txp[i] = NULL;
+ }
- di->txin = i;
+ di->txin = i;
- /* tx flow control */
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
- return (txp);
+ return (txp);
bogus:
/*
DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
start, end, di->txout, forceall));
*/
- return (NULL);
+ return (NULL);
}
static void *
-dma64_getnextrxp(dma_info_t *di, bool forceall)
+dma64_getnextrxp (dma_info_t * di, bool forceall)
{
- uint i;
- void *rxp;
+ uint i;
+ void *rxp;
- /* if forcing, dma engine must be disabled */
- ASSERT(!forceall || !dma64_rxenabled(di));
+ /* if forcing, dma engine must be disabled */
+ ASSERT (!forceall || !dma64_rxenabled (di));
- i = di->rxin;
+ i = di->rxin;
- /* return if no packets posted */
- if (i == di->rxout)
- return (NULL);
+ /* return if no packets posted */
+ if (i == di->rxout)
+ return (NULL);
- /* ignore curr if forceall */
- if (!forceall &&
- (i == B2I(R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t)))
- return (NULL);
+ /* ignore curr if forceall */
+ if (!forceall &&
+ (i ==
+ B2I (R_REG (di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK,
+ dma64dd_t)))
+ return (NULL);
- /* get the packet pointer that corresponds to the rx descriptor */
- rxp = di->rxp[i];
- ASSERT(rxp);
- di->rxp[i] = NULL;
+ /* get the packet pointer that corresponds to the rx descriptor */
+ rxp = di->rxp[i];
+ ASSERT (rxp);
+ di->rxp[i] = NULL;
- /* clear this packet from the descriptor ring */
- DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow),
- di->rxbufsize, DMA_RX, rxp);
+ /* clear this packet from the descriptor ring */
+ DMA_UNMAP (di->osh,
+ (BUS_SWAP32 (R_SM (&di->rxd64[i].addrlow)) - di->dataoffsetlow),
+ di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]);
- W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
- W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
+ W_SM (&di->rxd64[i].addrlow, 0xdeadbeef);
+ W_SM (&di->rxd64[i].addrhigh, 0xdeadbeef);
- di->rxin = NEXTRXD(i);
+ di->rxin = NEXTRXD (i);
- return (rxp);
+ return (rxp);
}
static bool
-_dma64_addrext(osl_t *osh, dma64regs_t *dma64regs)
+_dma64_addrext (osl_t * osh, dma64regs_t * dma64regs)
{
- uint32 w;
- OR_REG(osh, &dma64regs->control, D64_XC_AE);
- w = R_REG(osh, &dma64regs->control);
- AND_REG(osh, &dma64regs->control, ~D64_XC_AE);
- return ((w & D64_XC_AE) == D64_XC_AE);
+ uint32 w;
+ OR_REG (osh, &dma64regs->control, D64_XC_AE);
+ w = R_REG (osh, &dma64regs->control);
+ AND_REG (osh, &dma64regs->control, ~D64_XC_AE);
+ return ((w & D64_XC_AE) == D64_XC_AE);
}
/*
* Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
*/
static void
-dma64_txrotate(dma_info_t *di)
+dma64_txrotate (dma_info_t * di)
{
- uint ad;
- uint nactive;
- uint rot;
- uint old, new;
- uint32 w;
- uint first, last;
-
- ASSERT(dma64_txsuspendedidle(di));
-
- nactive = _dma_txactive(di);
- ad = B2I((R_REG(di->osh, &di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t);
- rot = TXD(ad - di->txin);
-
- ASSERT(rot < di->ntxd);
-
- /* full-ring case is a lot harder - don't worry about this */
- if (rot >= (di->ntxd - nactive)) {
- DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
- return;
- }
-
- first = di->txin;
- last = PREVTXD(di->txout);
-
- /* move entries starting at last and moving backwards to first */
- for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
- new = TXD(old + rot);
-
- /*
- * Move the tx dma descriptor.
- * EOT is set only in the last entry in the ring.
- */
- w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
- if (new == (di->ntxd - 1))
- w |= D64_CTRL1_EOT;
- W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
-
- w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
- W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
-
- W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
- W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
-
- /* zap the old tx dma descriptor address field */
- W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
- W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
-
- /* move the corresponding txp[] entry */
- ASSERT(di->txp[new] == NULL);
- di->txp[new] = di->txp[old];
- di->txp[old] = NULL;
- }
-
- /* update txin and txout */
- di->txin = ad;
- di->txout = TXD(di->txout + rot);
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-
- /* kick the chip */
- W_REG(di->osh, &di->d64txregs->ptr, I2B(di->txout, dma64dd_t));
+ uint ad;
+ uint nactive;
+ uint rot;
+ uint old, new;
+ uint32 w;
+ uint first, last;
+
+ ASSERT (dma64_txsuspendedidle (di));
+
+ nactive = _dma_txactive (di);
+ ad =
+ B2I ((R_REG (di->osh, &di->d64txregs->status1) & D64_XS1_AD_MASK),
+ dma64dd_t);
+ rot = TXD (ad - di->txin);
+
+ ASSERT (rot < di->ntxd);
+
+ /* full-ring case is a lot harder - don't worry about this */
+ if (rot >= (di->ntxd - nactive))
+ {
+ DMA_ERROR (("%s: dma_txrotate: ring full - punt\n", di->name));
+ return;
+ }
+
+ first = di->txin;
+ last = PREVTXD (di->txout);
+
+ /* move entries starting at last and moving backwards to first */
+ for (old = last; old != PREVTXD (first); old = PREVTXD (old))
+ {
+ new = TXD (old + rot);
+
+ /*
+ * Move the tx dma descriptor.
+ * EOT is set only in the last entry in the ring.
+ */
+ w = BUS_SWAP32 (R_SM (&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
+ if (new == (di->ntxd - 1))
+ w |= D64_CTRL1_EOT;
+ W_SM (&di->txd64[new].ctrl1, BUS_SWAP32 (w));
+
+ w = BUS_SWAP32 (R_SM (&di->txd64[old].ctrl2));
+ W_SM (&di->txd64[new].ctrl2, BUS_SWAP32 (w));
+
+ W_SM (&di->txd64[new].addrlow, R_SM (&di->txd64[old].addrlow));
+ W_SM (&di->txd64[new].addrhigh, R_SM (&di->txd64[old].addrhigh));
+
+ /* zap the old tx dma descriptor address field */
+ W_SM (&di->txd64[old].addrlow, BUS_SWAP32 (0xdeadbeef));
+ W_SM (&di->txd64[old].addrhigh, BUS_SWAP32 (0xdeadbeef));
+
+ /* move the corresponding txp[] entry */
+ ASSERT (di->txp[new] == NULL);
+ di->txp[new] = di->txp[old];
+ di->txp[old] = NULL;
+ }
+
+ /* update txin and txout */
+ di->txin = ad;
+ di->txout = TXD (di->txout + rot);
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
+
+ /* kick the chip */
+ W_REG (di->osh, &di->d64txregs->ptr, I2B (di->txout, dma64dd_t));
}
-#endif /* BCMDMA64 */
+#endif /* BCMDMA64 */
uint
-dma_addrwidth(sb_t *sbh, void *dmaregs)
-{
- dma32regs_t *dma32regs;
- osl_t *osh;
-
- osh = sb_osh(sbh);
-
- if (DMA64_CAP) {
- /* DMA engine is 64-bit capable */
- if (((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64)) {
- /* backplane are 64 bits capable */
-#if 0
- if (sb_backplane64(sbh))
- /* If bus is System Backplane or PCIE then we can access 64-bits */
- if ((BUSTYPE(sbh->bustype) == SB_BUS) ||
- ((BUSTYPE(sbh->bustype) == PCI_BUS) &&
- sbh->buscoretype == SB_PCIE))
- return (DMADDRWIDTH_64);
-#endif
-
- /* DMA64 is always 32 bits capable, AE is always TRUE */
+dma_addrwidth (sb_t * sbh, void *dmaregs)
+{
+ dma32regs_t *dma32regs;
+ osl_t *osh;
+
+ osh = sb_osh (sbh);
+
+ if (DMA64_CAP)
+ {
+ /* DMA engine is 64-bit capable */
+ if (((sb_coreflagshi (sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64))
+ {
+ /* backplane are 64 bits capable */
+ if (sb_backplane64 (sbh))
+ /* If bus is System Backplane or PCIE then we can access 64-bits */
+ if ((BUSTYPE (sbh->bustype) == SB_BUS) ||
+ ((BUSTYPE (sbh->bustype) == PCI_BUS) &&
+ sbh->buscoretype == SB_PCIE))
+ return (DMADDRWIDTH_64);
+
+ /* DMA64 is always 32 bits capable, AE is always TRUE */
#ifdef BCMDMA64
- ASSERT(_dma64_addrext(osh, (dma64regs_t *)dmaregs));
+ ASSERT (_dma64_addrext (osh, (dma64regs_t *) dmaregs));
#endif
- return (DMADDRWIDTH_32);
- }
+ return (DMADDRWIDTH_32);
}
+ }
- /* Start checking for 32-bit / 30-bit addressing */
- dma32regs = (dma32regs_t *)dmaregs;
+ /* Start checking for 32-bit / 30-bit addressing */
+ dma32regs = (dma32regs_t *) dmaregs;
- /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */
- if ((BUSTYPE(sbh->bustype) == SB_BUS) ||
- ((BUSTYPE(sbh->bustype) == PCI_BUS) && sbh->buscoretype == SB_PCIE) ||
- (_dma32_addrext(osh, dma32regs)))
- return (DMADDRWIDTH_32);
+ /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */
+ if ((BUSTYPE (sbh->bustype) == SB_BUS) ||
+ ((BUSTYPE (sbh->bustype) == PCI_BUS) && sbh->buscoretype == SB_PCIE) ||
+ (_dma32_addrext (osh, dma32regs)))
+ return (DMADDRWIDTH_32);
- /* Fallthru */
- return (DMADDRWIDTH_30);
+ /* Fallthru */
+ return (DMADDRWIDTH_30);
}
diff --git a/package/broadcom-wl/src/driver/hnddma.h b/package/broadcom-wl/src/driver/hnddma.h
index de74c067b2..8d1b5acb6b 100644
--- a/package/broadcom-wl/src/driver/hnddma.h
+++ b/package/broadcom-wl/src/driver/hnddma.h
@@ -2,14 +2,14 @@
* Generic Broadcom Home Networking Division (HND) DMA engine SW interface
* This supports the following chips: BCM42xx, 44xx, 47xx .
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: hnddma.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $
+ * $Id$
*/
#ifndef _hnddma_h_
@@ -39,7 +39,7 @@ typedef void* (*di_rx_t)(hnddma_t *dmah);
typedef void (*di_rxfill_t)(hnddma_t *dmah);
typedef void (*di_txreclaim_t)(hnddma_t *dmah, bool forceall);
typedef void (*di_rxreclaim_t)(hnddma_t *dmah);
-typedef uintptr (*di_getvar_t)(hnddma_t *dmah, char *name);
+typedef uintptr (*di_getvar_t)(hnddma_t *dmah, const char *name);
typedef void* (*di_getnexttxp_t)(hnddma_t *dmah, bool forceall);
typedef void* (*di_getnextrxp_t)(hnddma_t *dmah, bool forceall);
typedef void* (*di_peeknexttxp_t)(hnddma_t *dmah);
@@ -141,8 +141,12 @@ extern hnddma_t * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx,
#define dma_txactive(di) ((di)->di_fn.txactive(di))
#define dma_txrotate(di) ((di)->di_fn.txrotate(di))
#define dma_counterreset(di) ((di)->di_fn.counterreset(di))
+#ifdef BCMDBG
+#define dma_dump(di, buf, dumpring) ((di)->di_fn.dump(di, buf, dumpring))
+#define dma_dumptx(di, buf, dumpring) ((di)->di_fn.dumptx(di, buf, dumpring))
+#define dma_dumprx(di, buf, dumpring) ((di)->di_fn.dumprx(di, buf, dumpring))
+#endif
-#define DMA_DUMP_SIZE 2048
/* return addresswidth allowed
* This needs to be done after SB attach but before dma attach.
* SB attach provides ability to probe backplane and dma core capabilities
diff --git a/package/broadcom-wl/src/driver/linux_osl.c b/package/broadcom-wl/src/driver/linux_osl.c
index 24fd77daea..cc55eb68e9 100644
--- a/package/broadcom-wl/src/driver/linux_osl.c
+++ b/package/broadcom-wl/src/driver/linux_osl.c
@@ -1,7 +1,7 @@
/*
* Linux OS Independent Layer
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,266 +9,882 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: linux_osl.c,v 1.1.1.14 2006/04/08 06:13:39 honor Exp $
+ * $Id$
*/
#define LINUX_OSL
#include <typedefs.h>
#include <bcmendian.h>
-#include <linux/module.h>
#include <linuxver.h>
#include <bcmdefs.h>
#include <osl.h>
#include "linux_osl.h"
-#include <bcmutils.h>
+#include "bcmutils.h"
#include <linux/delay.h>
#ifdef mips
#include <asm/paccess.h>
#endif /* mips */
#include <pcicfg.h>
-#define PCI_CFG_RETRY 10
+#define PCI_CFG_RETRY 10
#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */
-#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */
-
-typedef struct bcm_mem_link {
- struct bcm_mem_link *prev;
- struct bcm_mem_link *next;
- uint size;
- int line;
- char file[BCM_MEM_FILENAME_LEN];
+#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */
+
+typedef struct bcm_mem_link
+{
+ struct bcm_mem_link *prev;
+ struct bcm_mem_link *next;
+ uint size;
+ int line;
+ char file[BCM_MEM_FILENAME_LEN];
} bcm_mem_link_t;
-static int16 linuxbcmerrormap[] = \
-{ 0, /* 0 */
- -EINVAL, /* BCME_ERROR */
- -EINVAL, /* BCME_BADARG */
- -EINVAL, /* BCME_BADOPTION */
- -EINVAL, /* BCME_NOTUP */
- -EINVAL, /* BCME_NOTDOWN */
- -EINVAL, /* BCME_NOTAP */
- -EINVAL, /* BCME_NOTSTA */
- -EINVAL, /* BCME_BADKEYIDX */
- -EINVAL, /* BCME_RADIOOFF */
- -EINVAL, /* BCME_NOTBANDLOCKED */
- -EINVAL, /* BCME_NOCLK */
- -EINVAL, /* BCME_BADRATESET */
- -EINVAL, /* BCME_BADBAND */
- -E2BIG, /* BCME_BUFTOOSHORT */
- -E2BIG, /* BCME_BUFTOOLONG */
- -EBUSY, /* BCME_BUSY */
- -EINVAL, /* BCME_NOTASSOCIATED */
- -EINVAL, /* BCME_BADSSIDLEN */
- -EINVAL, /* BCME_OUTOFRANGECHAN */
- -EINVAL, /* BCME_BADCHAN */
- -EFAULT, /* BCME_BADADDR */
- -ENOMEM, /* BCME_NORESOURCE */
- -EOPNOTSUPP, /* BCME_UNSUPPORTED */
- -EMSGSIZE, /* BCME_BADLENGTH */
- -EINVAL, /* BCME_NOTREADY */
- -EPERM, /* BCME_NOTPERMITTED */
- -ENOMEM, /* BCME_NOMEM */
- -EINVAL, /* BCME_ASSOCIATED */
- -ERANGE, /* BCME_RANGE */
- -EINVAL, /* BCME_NOTFOUND */
- -EINVAL, /* BCME_WME_NOT_ENABLED */
- -EINVAL, /* BCME_TSPEC_NOTFOUND */
- -EINVAL, /* BCME_ACM_NOTSUPPORTED */
- -EINVAL, /* BCME_NOT_WME_ASSOCIATION */
- -EIO, /* BCME_SDIO_ERROR */
- -ENODEV /* BCME_DONGLE_DOWN */
+#if 0
+struct osl_info
+{
+ osl_pubinfo_t pub;
+ uint magic;
+ void *pdev;
+ uint malloced;
+ uint failed;
+ uint bustype;
+ bcm_mem_link_t *dbgmem_list;
+#ifdef BCMDBG_PKT /* pkt logging for debugging */
+ pktlist_info_t pktlist;
+#endif /* BCMDBG_PKT */
+};
+#endif
+
+static int16 linuxbcmerrormap[] = { 0, /* 0 */
+ -EINVAL, /* BCME_ERROR */
+ -EINVAL, /* BCME_BADARG */
+ -EINVAL, /* BCME_BADOPTION */
+ -EINVAL, /* BCME_NOTUP */
+ -EINVAL, /* BCME_NOTDOWN */
+ -EINVAL, /* BCME_NOTAP */
+ -EINVAL, /* BCME_NOTSTA */
+ -EINVAL, /* BCME_BADKEYIDX */
+ -EINVAL, /* BCME_RADIOOFF */
+ -EINVAL, /* BCME_NOTBANDLOCKED */
+ -EINVAL, /* BCME_NOCLK */
+ -EINVAL, /* BCME_BADRATESET */
+ -EINVAL, /* BCME_BADBAND */
+ -E2BIG, /* BCME_BUFTOOSHORT */
+ -E2BIG, /* BCME_BUFTOOLONG */
+ -EBUSY, /* BCME_BUSY */
+ -EINVAL, /* BCME_NOTASSOCIATED */
+ -EINVAL, /* BCME_BADSSIDLEN */
+ -EINVAL, /* BCME_OUTOFRANGECHAN */
+ -EINVAL, /* BCME_BADCHAN */
+ -EFAULT, /* BCME_BADADDR */
+ -ENOMEM, /* BCME_NORESOURCE */
+ -EOPNOTSUPP, /* BCME_UNSUPPORTED */
+ -EMSGSIZE, /* BCME_BADLENGTH */
+ -EINVAL, /* BCME_NOTREADY */
+ -EPERM, /* BCME_NOTPERMITTED */
+ -ENOMEM, /* BCME_NOMEM */
+ -EINVAL, /* BCME_ASSOCIATED */
+ -ERANGE, /* BCME_RANGE */
+ -EINVAL, /* BCME_NOTFOUND */
+ -EINVAL, /* BCME_WME_NOT_ENABLED */
+ -EINVAL, /* BCME_TSPEC_NOTFOUND */
+ -EINVAL, /* BCME_ACM_NOTSUPPORTED */
+ -EINVAL, /* BCME_NOT_WME_ASSOCIATION */
+ -EIO, /* BCME_SDIO_ERROR */
+ -ENODEV, /* BCME_DONGLE_DOWN */
+ -EINVAL /* BCME_VERSION */
+/* When an new error code is added to bcmutils.h, add os
+ * spcecific error translation here as well
+ */
+/* check if BCME_LAST changed since the last time this function was updated */
+#if BCME_LAST != -37
+#error "You need to add a OS error translation in the linuxbcmerrormap \
+ for new error code defined in bcmuitls.h"
+#endif /* BCME_LAST != -37 */
};
/* translate bcmerrors into linux errors */
int
-osl_error(int bcmerror)
+osl_error (int bcmerror)
{
- int abs_bcmerror;
- int array_size = ARRAYSIZE(linuxbcmerrormap);
+ if (bcmerror > 0)
+ bcmerror = 0;
+ else if (bcmerror < BCME_LAST)
+ bcmerror = BCME_ERROR;
- abs_bcmerror = ABS(bcmerror);
+ /* Array bounds covered by ASSERT in osl_attach */
+ return linuxbcmerrormap[-bcmerror];
+}
- if (bcmerror > 0)
- abs_bcmerror = 0;
+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));
+
+ /* Check that error map has the right number of entries in it */
+ ASSERT (ABS (BCME_LAST) == (ARRAYSIZE (linuxbcmerrormap) - 1));
+
+ osh->magic = OS_HANDLE_MAGIC;
+ osh->malloced = 0;
+ osh->failed = 0;
+ osh->dbgmem_list = NULL;
+ osh->pdev = pdev;
+ osh->pub.pkttag = pkttag;
+ osh->bustype = bustype;
+
+ switch (bustype)
+ {
+ case PCI_BUS:
+ case SB_BUS:
+ case PCMCIA_BUS:
+ osh->pub.mmbus = TRUE;
+ break;
+ case JTAG_BUS:
+ case SDIO_BUS:
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+#ifdef BCMDBG
+ if (pkttag)
+ {
+ struct sk_buff *skb;
+ ASSERT (OSL_PKTTAG_SZ <= sizeof (skb->cb));
+ }
+#endif
+ return osh;
+}
- else if (abs_bcmerror >= array_size)
- abs_bcmerror = BCME_ERROR;
+void
+osl_detach (osl_t * osh)
+{
+ if (osh == NULL)
+ return;
- return linuxbcmerrormap[abs_bcmerror];
+ ASSERT (osh->magic == OS_HANDLE_MAGIC);
+ kfree (osh);
}
-osl_t *
-osl_attach(void *pdev, bool pkttag)
+/* Return a new packet. zero out pkttag */
+void *
+osl_pktget (osl_t * osh, uint len)
+{
+ struct sk_buff *skb;
+
+ if ((skb = dev_alloc_skb (len)))
+ {
+ skb_put (skb, len);
+ skb->priority = 0;
+
+#ifdef BCMDBG_PKT
+ pktlist_add (&(osh->pktlist), (void *) skb);
+#endif /* BCMDBG_PKT */
+
+ osh->pub.pktalloced++;
+ }
+
+ return ((void *) skb);
+}
+
+/* Free the driver packet. Free the tag if present */
+void
+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);
+
+ /* perversion: we use skb->next to chain multi-skb packets */
+ while (skb)
+ {
+ nskb = skb->next;
+ skb->next = NULL;
+
+#ifdef BCMDBG_PKT
+ pktlist_remove (&(osh->pktlist), (void *) skb);
+#endif /* BCMDBG_PKT */
+
+ if (skb->destructor)
+ {
+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists
+ */
+ dev_kfree_skb_any (skb);
+ }
+ else
+ {
+ /* can free immediately (even in_irq()) if destructor does not exist */
+ dev_kfree_skb (skb);
+ }
+
+ osh->pub.pktalloced--;
+
+ skb = nskb;
+ }
+}
+
+uint32
+osl_pci_read_config (osl_t * osh, uint offset, uint size)
{
- osl_t *osh;
+ uint val;
+ uint retry = PCI_CFG_RETRY;
- osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
- ASSERT(osh);
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
- bzero(osh, sizeof(osl_t));
+ /* only 4byte access supported */
+ ASSERT (size == 4);
- /*
- * check the cases where
- * 1.Error code Added to bcmerror table, but forgot to add it to the OS
- * dependent error code
- * 2. Error code is added to the bcmerror table, but forgot to add the
- * corresponding errorstring(dummy call to bcmerrorstr)
- */
- bcmerrorstr(0);
- ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1));
+ do
+ {
+ pci_read_config_dword (osh->pdev, offset, &val);
+ if (val != 0xffffffff)
+ break;
+ }
+ while (retry--);
- osh->magic = OS_HANDLE_MAGIC;
- osh->malloced = 0;
- osh->failed = 0;
- osh->dbgmem_list = NULL;
- osh->pdev = pdev;
- osh->pub.pkttag = pkttag;
+#ifdef BCMDBG
+ if (retry < PCI_CFG_RETRY)
+ printk ("PCI CONFIG READ access to %d required %d retries\n", offset,
+ (PCI_CFG_RETRY - retry));
+#endif /* BCMDBG */
- return osh;
+ return (val);
}
void
-osl_detach(osl_t *osh)
+osl_pci_write_config (osl_t * osh, uint offset, uint size, uint val)
{
- if (osh == NULL)
- return;
+ uint retry = PCI_CFG_RETRY;
+
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ /* only 4byte access supported */
+ 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 /* BCMDBG */
+}
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
- kfree(osh);
+/* return bus # for the pci device pointed by osh->pdev */
+uint
+osl_pci_bus (osl_t * osh)
+{
+ ASSERT (osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+ return ((struct pci_dev *) osh->pdev)->bus->number;
}
-/* Return a new packet. zero out pkttag */
-void*
-osl_pktget(osl_t *osh, uint len, bool send)
+/* return slot # for the pci device pointed by osh->pdev */
+uint
+osl_pci_slot (osl_t * osh)
{
- struct sk_buff *skb;
+ ASSERT (osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
- if ((skb = dev_alloc_skb(len))) {
- skb_put(skb, len);
- skb->priority = 0;
+ return PCI_SLOT (((struct pci_dev *) osh->pdev)->devfn);
+}
-#ifdef BCMDBG_PKT
- pktlist_add(&(osh->pktlist), (void *) skb);
-#endif /* BCMDBG_PKT */
+static void
+osl_pcmcia_attr (osl_t * osh, uint offset, char *buf, int size, bool write)
+{
+}
- osh->pub.pktalloced++;
- }
+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
+
+void *
+osl_debug_malloc (osl_t * osh, uint size, int line, char *file)
+{
+ bcm_mem_link_t *p;
+ char *basename;
+
+ ASSERT (size);
- return ((void*) skb);
+ if ((p =
+ (bcm_mem_link_t *) osl_malloc (osh,
+ sizeof (bcm_mem_link_t) + size)) ==
+ NULL)
+ return (NULL);
+
+ p->size = size;
+ p->line = line;
+
+ basename = strrchr (file, '/');
+ /* skip the '/' */
+ if (basename)
+ basename++;
+
+ if (!basename)
+ basename = file;
+
+ strncpy (p->file, basename, BCM_MEM_FILENAME_LEN);
+ p->file[BCM_MEM_FILENAME_LEN - 1] = '\0';
+
+ /* link this block */
+ p->prev = NULL;
+ p->next = osh->dbgmem_list;
+ if (p->next)
+ p->next->prev = p;
+ osh->dbgmem_list = p;
+
+ return p + 1;
}
-typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, uint16 status);
-/* Free the driver packet. Free the tag if present */
void
-osl_pktfree(osl_t *osh, void *p, bool send)
+osl_debug_mfree (osl_t * osh, void *addr, uint size, int line, char *file)
{
- struct sk_buff *skb, *nskb;
- pktfree_cb_fn_t tx_fn = osh->pub.tx_fn;
+ bcm_mem_link_t *p =
+ (bcm_mem_link_t *) ((int8 *) addr - sizeof (bcm_mem_link_t));
+
+ ASSERT ((osh && (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
+ ("osl_debug_mfree: dealloc size %d does not match alloc size %d on addr %p"
+ " at line %d file %s\n", size, p->size, addr, line, file);
+ ASSERT (p->size == size);
+ return;
+ }
+
+ /* unlink this block */
+ 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;
+
+ osl_mfree (osh, p, size + sizeof (bcm_mem_link_t));
+}
- skb = (struct sk_buff*) p;
-
- if (send && tx_fn)
- tx_fn(osh->pub.tx_ctx, p, 0);
+int
+osl_debug_memdump (osl_t * osh, struct bcmstrbuf *b)
+{
+ bcm_mem_link_t *p;
- /* perversion: we use skb->next to chain multi-skb packets */
- while (skb) {
- nskb = skb->next;
- skb->next = NULL;
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
-#ifdef BCMDBG_PKT
- pktlist_remove(&(osh->pktlist), (void *) skb);
-#endif /* BCMDBG_PKT */
+ bcm_bprintf (b, " Address\tSize\tFile:line\n");
+ for (p = osh->dbgmem_list; p; p = p->next)
+ bcm_bprintf (b, "0x%08x\t%5d\t%s:%d\n",
+ (uintptr) p + sizeof (bcm_mem_link_t), p->size, p->file,
+ p->line);
- if (skb->destructor) {
- /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists
- */
- dev_kfree_skb_any(skb);
- } else {
- /* can free immediately (even in_irq()) if destructor does not exist */
- dev_kfree_skb(skb);
- }
+ return 0;
+}
- osh->pub.pktalloced--;
+#endif /* BCMDBG_MEM */
- skb = nskb;
- }
+void *
+osl_malloc (osl_t * osh, uint size)
+{
+ void *addr;
+
+ /* only ASSERT if osh is defined */
+ if (osh)
+ ASSERT (osh->magic == OS_HANDLE_MAGIC);
+
+ if ((addr = kmalloc (size, GFP_ATOMIC)) == NULL)
+ {
+ if (osh)
+ osh->failed++;
+ return (NULL);
+ }
+ if (osh)
+ osh->malloced += size;
+
+ return (addr);
}
-void*
-osl_malloc(osl_t *osh, uint size)
+void
+osl_mfree (osl_t * osh, void *addr, uint size)
{
- void *addr;
+ if (osh)
+ {
+ ASSERT (osh->magic == OS_HANDLE_MAGIC);
+ osh->malloced -= size;
+ }
+ kfree (addr);
+}
- /* only ASSERT if osh is defined */
- if (osh)
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
+uint
+osl_malloced (osl_t * osh)
+{
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ return (osh->malloced);
+}
- if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) {
- if (osh)
- osh->failed++;
- return (NULL);
- }
- if (osh)
- osh->malloced += size;
+uint
+osl_malloc_failed (osl_t * osh)
+{
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ return (osh->failed);
+}
+
+void *
+osl_dma_alloc_consistent (osl_t * osh, uint size, ulong * pap)
+{
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
- return (addr);
+ return (pci_alloc_consistent (osh->pdev, size, (dma_addr_t *) pap));
}
void
-osl_mfree(osl_t *osh, void *addr, uint size)
+osl_dma_free_consistent (osl_t * osh, void *va, uint size, ulong pa)
{
- if (osh) {
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
- osh->malloced -= size;
- }
- kfree(addr);
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ pci_free_consistent (osh->pdev, size, va, (dma_addr_t) pa);
}
uint
-osl_malloced(osl_t *osh)
+osl_dma_map (osl_t * osh, void *va, uint size, int direction)
{
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- return (osh->malloced);
+ int dir;
+
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
+ return (pci_map_single (osh->pdev, va, size, dir));
}
-uint osl_malloc_failed(osl_t *osh)
+void
+osl_dma_unmap (osl_t * osh, uint pa, uint size, int direction)
{
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- return (osh->failed);
+ int dir;
+
+ ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
+ pci_unmap_single (osh->pdev, (uint32) pa, size, dir);
}
-#undef osl_delay
+#if defined(BINOSL) || defined(BCMDBG_ASSERT)
void
-osl_delay(uint usec)
+osl_assert (char *exp, char *file, int line)
{
- OSL_DELAY(usec);
+ char tempbuf[255];
+
+ sprintf (tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
+ file, line);
+ panic (tempbuf);
+}
+#endif /* BCMDBG_ASSERT || BINOSL */
+
+void
+osl_delay (uint usec)
+{
+ uint d;
+
+ while (usec > 0)
+ {
+ d = MIN (usec, 1000);
+ udelay (d);
+ usec -= d;
+ }
}
/* Clone a packet.
* The pkttag contents are NOT cloned.
*/
void *
-osl_pktdup(osl_t *osh, void *skb)
+osl_pktdup (osl_t * osh, void *skb)
+{
+ void *p;
+
+ if ((p = skb_clone ((struct sk_buff *) skb, GFP_ATOMIC)) == NULL)
+ return NULL;
+
+ /* skb_clone copies skb->cb.. we don't want that */
+ if (osh->pub.pkttag)
+ bzero ((void *) ((struct sk_buff *) p)->cb, OSL_PKTTAG_SZ);
+
+ /* Increment the packet counter */
+ osh->pub.pktalloced++;
+#ifdef BCMDBG_PKT
+ pktlist_add (&(osh->pktlist), (void *) p);
+#endif /* BCMDBG_PKT */
+ return (p);
+}
+
+uint
+osl_pktalloced (osl_t * osh)
+{
+ return (osh->pub.pktalloced);
+}
+
+#ifdef BCMDBG_PKT
+char *
+osl_pktlist_dump (osl_t * osh, char *buf)
+{
+ pktlist_dump (&(osh->pktlist), buf);
+ return buf;
+}
+
+void
+osl_pktlist_add (osl_t * osh, void *p)
+{
+ pktlist_add (&(osh->pktlist), p);
+}
+
+void
+osl_pktlist_remove (osl_t * osh, void *p)
+{
+ pktlist_remove (&(osh->pktlist), p);
+}
+#endif /* BCMDBG_PKT */
+
+/*
+ * BINOSL selects the slightly slower function-call-based binary compatible osl.
+ */
+#ifdef BINOSL
+
+int
+osl_printf (const char *format, ...)
+{
+ va_list args;
+ char buf[1024];
+ int len;
+
+ /* sprintf into a local buffer because there *is* no "vprintk()".. */
+ va_start (args, format);
+ len = vsnprintf (buf, 1024, format, args);
+ va_end (args);
+
+ if (len > sizeof (buf))
+ {
+ printk ("osl_printf: buffer overrun\n");
+ return (0);
+ }
+
+ return (printk (buf));
+}
+
+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_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));
+}
+
+void
+bcopy (const void *src, void *dst, int len)
+{
+ memcpy (dst, src, len);
+}
+
+int
+bcmp (const void *b1, const void *b2, int len)
+{
+ return (memcmp (b1, b2, len));
+}
+
+void
+bzero (void *b, int len)
+{
+ memset (b, '\0', len);
+}
+
+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)
+{
+#ifdef mips
+ return ((void *) KSEG1ADDR (va));
+#else
+ return ((void *) va);
+#endif /* mips */
+}
+
+uint
+osl_getcycles (void)
{
- void * p;
+ uint cycles;
+
+#if defined(mips)
+ cycles = read_c0_count () * 2;
+#elif defined(__i386__)
+ rdtscl (cycles);
+#else
+ cycles = 0;
+#endif /* defined(mips) */
+ return cycles;
+}
- if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL)
- return NULL;
+void *
+osl_reg_map (uint32 pa, uint size)
+{
+ return (ioremap_nocache ((unsigned long) pa, (unsigned long) size));
+}
- /* skb_clone copies skb->cb.. we don't want that */
- if (osh->pub.pkttag)
- bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ);
+void
+osl_reg_unmap (void *va)
+{
+ iounmap (va);
+}
- /* Increment the packet counter */
- osh->pub.pktalloced++;
- return (p);
+int
+osl_busprobe (uint32 * val, uint32 addr)
+{
+#ifdef mips
+ return get_dbe (*val, (uint32 *) addr);
+#else
+ *val = readl ((uint32 *) (uintptr) addr);
+ return 0;
+#endif /* mips */
+}
+
+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_pktalloced(osl_t *osh)
+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 (osh->pub.pktalloced);
+ 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;
+}
+
+/* Convert a driver packet to native(OS) packet
+ * In the process, packettag is zeroed out before sending up
+ * IP code depends on skb->cb to be setup correctly with various options
+ * In our case, that means it should be 0
+ */
+struct sk_buff *
+osl_pkt_tonative (osl_t * osh, void *pkt)
+{
+ struct sk_buff *nskb;
+
+ if (osh->pub.pkttag)
+ bzero ((void *) ((struct sk_buff *) pkt)->cb, OSL_PKTTAG_SZ);
+
+ /* Decrement the packet counter */
+ for (nskb = (struct sk_buff *) pkt; nskb; nskb = nskb->next)
+ {
+#ifdef BCMDBG_PKT
+ pktlist_remove (&(osh->pktlist), (void *) nskb);
+#endif /* BCMDBG_PKT */
+ osh->pub.pktalloced--;
+ }
+
+ return (struct sk_buff *) pkt;
+}
+
+/* Convert a native(OS) packet to driver packet.
+ * In the process, native packet is destroyed, there is no copying
+ * Also, a packettag is zeroed out
+ */
+void *
+osl_pkt_frmnative (osl_t * osh, struct sk_buff *skb)
+{
+ struct sk_buff *nskb;
+
+ if (osh->pub.pkttag)
+ bzero ((void *) skb->cb, OSL_PKTTAG_SZ);
+
+ /* Increment the packet counter */
+ for (nskb = skb; nskb; nskb = nskb->next)
+ {
+#ifdef BCMDBG_PKT
+ pktlist_add (&(osh->pktlist), (void *) nskb);
+#endif /* BCMDBG_PKT */
+ osh->pub.pktalloced++;
+ }
+
+ return (void *) skb;
}
+#endif /* BINOSL */
diff --git a/package/broadcom-wl/src/driver/linux_osl.h b/package/broadcom-wl/src/driver/linux_osl.h
index d9c5533b85..f65c85966b 100644
--- a/package/broadcom-wl/src/driver/linux_osl.h
+++ b/package/broadcom-wl/src/driver/linux_osl.h
@@ -1,7 +1,7 @@
/*
* Linux OS Independent Layer
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: linux_osl.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $
+ * $Id$
*/
#ifndef _linux_osl_h_
@@ -19,17 +19,25 @@
#include <linuxver.h>
#include <osl.h>
-#define OSL_PKTTAG_SZ 32 /* Size of PktTag */
+#define OSL_PKTTAG_SZ 32 /* Size of PktTag */
-/* osl handle type forward declaration */
-typedef struct osl_dmainfo osldma_t;
+/* microsecond delay */
+extern void osl_delay(uint usec);
/* OSL initialization */
-extern osl_t *osl_attach(void *pdev, bool pkttag);
+extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
extern void osl_detach(osl_t *osh);
+#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \
+ do { \
+ ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \
+ ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \
+ } while (0)
+
/* host/bus architecture-specific byte swap */
#define BUS_SWAP32(v) (v)
+
+
#define MALLOC_FAILED(osh) osl_malloc_failed((osh))
extern void *osl_malloc(osl_t *osh, uint size);
@@ -37,61 +45,110 @@ extern void osl_mfree(osl_t *osh, void *addr, uint size);
extern uint osl_malloced(osl_t *osh);
extern uint osl_malloc_failed(osl_t *osh);
-/* API for DMA addressing capability */
-#define DMA_MAP(osh, va, size, direction, p) \
- osl_dma_map((osh), (va), (size), (direction))
-#define DMA_UNMAP(osh, pa, size, direction, p) \
- osl_dma_unmap((osh), (pa), (size), (direction))
-static inline uint
-osl_dma_map(void *osh, void *va, uint size, int direction)
-{
- int dir;
- struct pci_dev *dev;
-
- dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev);
- dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
- return (pci_map_single(dev, va, size, dir));
-}
-
-static inline void
-osl_dma_unmap(void *osh, uint pa, uint size, int direction)
-{
- int dir;
- struct pci_dev *dev;
-
- dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev);
- dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
- pci_unmap_single(dev, (uint32)pa, size, dir);
-}
-
-#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
+/* allocate/free shared (dma-able) consistent memory */
#define DMA_CONSISTENT_ALIGN PAGE_SIZE
#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah) \
osl_dma_alloc_consistent((osh), (size), (pap))
#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
-static inline void*
-osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap)
-{
- return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap));
-}
+extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap);
+extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
-static inline void
-osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
-{
- pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
-}
+/* map/unmap direction */
+#define DMA_TX 1 /* TX direction for DMA */
+#define DMA_RX 2 /* RX direction for DMA */
+
+/* map/unmap shared (dma-able) memory */
+#define DMA_MAP(osh, va, size, direction, p, dmah) \
+ osl_dma_map((osh), (va), (size), (direction))
+#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \
+ osl_dma_unmap((osh), (pa), (size), (direction))
+extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction);
+extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction);
+/* API for DMA addressing capability */
+#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
/* register access macros */
#if defined(BCMJTAG)
#include <bcmjtag.h>
-#define R_REG(osh, r) bcmjtag_read(NULL, (uint32)(r), sizeof(*(r)))
-#define W_REG(osh, r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof(*(r)))
-#endif /* defined(BCMSDIO) */
+#define OSL_WRITE_REG(osh, r, v) (bcmjtag_write(NULL, (uintptr)(r), (v), sizeof(*(r))))
+#define OSL_READ_REG(osh, r) (bcmjtag_read(NULL, (uintptr)(r), sizeof(*(r))))
+#endif
+
+#if defined(BCMJTAG)
+#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \
+ mmap_op else bus_op
+#define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \
+ mmap_op : bus_op
+#else
+#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op
+#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
+#endif
+
+/*
+ * BINOSL selects the slightly slower function-call-based binary compatible osl.
+ * Macros expand to calls to functions defined in linux_osl.c .
+ */
+#ifndef BINOSL
+
+/* string library, kernel mode */
+#ifndef printf
+#define printf(fmt, args...) printk(fmt, ## args)
+#endif /* printf */
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+/* register access macros */
+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
+
+/* bcopy, bcmp, and bzero */
+#define bcopy(src, dst, len) memcpy((dst), (src), (len))
+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
+#define bzero(b, len) memset((b), '\0', (len))
+
+/* uncached virtual address */
+#ifdef mips
+#define OSL_UNCACHED(va) KSEG1ADDR((va))
+#include <asm/addrspace.h>
+#else
+#define OSL_UNCACHED(va) (va)
+#endif /* mips */
+
+/* get processor cycle count */
+#if defined(mips)
+#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2)
+#elif defined(__i386__)
+#define OSL_GETCYCLES(x) rdtscl((x))
+#else
+#define OSL_GETCYCLES(x) ((x) = 0)
+#endif /* defined(mips) */
+
+/* dereference an address that may cause a bus exception */
+#ifdef mips
+#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17))
+#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into"\
+ " a module")
+#else
+#define BUSPROBE(val, addr) get_dbe((val), (addr))
+#include <asm/paccess.h>
+#endif /* defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) */
+#else
+#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; })
+#endif /* mips */
+
+/* map/unmap physical to virtual I/O */
+#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
+#define REG_UNMAP(va) iounmap((void *)(va))
+
+/* shared (dma-able) memory access macros */
+#define R_SM(r) *(r)
+#define W_SM(r, v) (*(r) = (v))
+#define BZERO_SM(r, len) memset((r), '\0', (len))
/* packet primitives */
-#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send))
+#define PKTGET(osh, len, send) osl_pktget((osh), (len))
#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data)
#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len)
@@ -104,15 +161,25 @@ osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes))
#define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb))
-#define PKTALLOCED(osh) osl_pktalloced((osh))
+#define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced
+#ifdef BCMDBG_PKT /* pkt logging for debugging */
+#define PKTLIST_DUMP(osh, buf) osl_pktlist_dump(osh, buf)
+#else /* BCMDBG_PKT */
#define PKTLIST_DUMP(osh, buf)
+#endif /* BCMDBG_PKT */
+
+#ifdef BCMDBG_PKT /* pkt logging for debugging */
+extern void osl_pktlist_add(osl_t *osh, void *p);
+extern void osl_pktlist_remove(osl_t *osh, void *p);
+extern char *osl_pktlist_dump(osl_t *osh, char *buf);
+#endif /* BCMDBG_PKT */
/* Convert a native(OS) packet to driver packet.
* In the process, native packet is destroyed, there is no copying
* Also, a packettag is zeroed out
*/
static INLINE void *
-osl_pkt_frmnative(osl_pubinfo_t*osh, struct sk_buff *skb)
+osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb)
{
struct sk_buff *nskb;
@@ -121,13 +188,15 @@ osl_pkt_frmnative(osl_pubinfo_t*osh, struct sk_buff *skb)
/* Increment the packet counter */
for (nskb = skb; nskb; nskb = nskb->next) {
+#ifdef BCMDBG_PKT
+ osl_pktlist_add((osl_t *)osh, (void *) nskb);
+#endif /* BCMDBG_PKT */
osh->pktalloced++;
}
return (void *)skb;
}
-#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t*)osh), \
- (struct sk_buff*)(skb))
+#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb))
/* Convert a driver packet to native(OS) packet
* In the process, packettag is zeroed out before sending up
@@ -135,7 +204,7 @@ osl_pkt_frmnative(osl_pubinfo_t*osh, struct sk_buff *skb)
* In our case, that means it should be 0
*/
static INLINE struct sk_buff *
-osl_pkt_tonative(osl_pubinfo_t*osh, void *pkt)
+osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt)
{
struct sk_buff *nskb;
@@ -144,24 +213,167 @@ osl_pkt_tonative(osl_pubinfo_t*osh, void *pkt)
/* Decrement the packet counter */
for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
+#ifdef BCMDBG_PKT
+ osl_pktlist_remove((osl_t *)osh, (void *) nskb);
+#endif /* BCMDBG_PKT */
osh->pktalloced--;
}
return (struct sk_buff *)pkt;
}
-#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t*)(osh), (pkt))
+#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt))
#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev)
#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority)
#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x))
+#define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW)
+#define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \
+ ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
+/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */
#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned)
-extern void *osl_pktget(osl_t *osh, uint len, bool send);
+extern void *osl_pktget(osl_t *osh, uint len);
+extern void osl_pktfree(osl_t *osh, void *skb, bool send);
+extern void *osl_pktdup(osl_t *osh, void *skb);
+#else /* BINOSL */
+
+/* string library */
+#ifndef LINUX_OSL
+#undef printf
+#define printf(fmt, args...) osl_printf((fmt), ## args)
+#undef sprintf
+#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args)
+#undef strcmp
+#define strcmp(s1, s2) osl_strcmp((s1), (s2))
+#undef strncmp
+#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n))
+#undef strlen
+#define strlen(s) osl_strlen((s))
+#undef strcpy
+#define strcpy(d, s) osl_strcpy((d), (s))
+#undef strncpy
+#define strncpy(d, s, n) osl_strncpy((d), (s), (n))
+#endif /* LINUX_OSL */
+extern int osl_printf(const char *format, ...);
+extern int osl_sprintf(char *buf, const char *format, ...);
+extern int osl_strcmp(const char *s1, const char *s2);
+extern int osl_strncmp(const char *s1, const char *s2, uint n);
+extern int osl_strlen(const char *s);
+extern char* osl_strcpy(char *d, const char *s);
+extern char* osl_strncpy(char *d, const char *s, uint n);
+
+/* register access macros */
+#if !defined(BCMJTAG)
+#define R_REG(osh, r) (\
+ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
+ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
+ osl_readl((volatile uint32*)(r)) \
+)
+#define W_REG(osh, r, v) do { \
+ switch (sizeof(*(r))) { \
+ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
+ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \
+ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
+ } \
+} while (0)
+#endif
+
+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
+extern uint8 osl_readb(volatile uint8 *r);
+extern uint16 osl_readw(volatile uint16 *r);
+extern uint32 osl_readl(volatile uint32 *r);
+extern void osl_writeb(uint8 v, volatile uint8 *r);
+extern void osl_writew(uint16 v, volatile uint16 *r);
+extern void osl_writel(uint32 v, volatile uint32 *r);
+
+/* bcopy, bcmp, and bzero */
+extern void bcopy(const void *src, void *dst, int len);
+extern int bcmp(const void *b1, const void *b2, int len);
+extern void bzero(void *b, int len);
+
+/* uncached virtual address */
+#define OSL_UNCACHED(va) osl_uncached((va))
+extern void *osl_uncached(void *va);
+
+/* get processor cycle count */
+#define OSL_GETCYCLES(x) ((x) = osl_getcycles())
+extern uint osl_getcycles(void);
+
+/* dereference an address that may target abort */
+#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr))
+extern int osl_busprobe(uint32 *val, uint32 addr);
+
+/* map/unmap physical to virtual */
+#define REG_MAP(pa, size) osl_reg_map((pa), (size))
+#define REG_UNMAP(va) osl_reg_unmap((va))
+extern void *osl_reg_map(uint32 pa, uint size);
+extern void osl_reg_unmap(void *va);
+
+/* shared (dma-able) memory access macros */
+#define R_SM(r) *(r)
+#define W_SM(r, v) (*(r) = (v))
+#define BZERO_SM(r, len) bzero((r), (len))
+
+/* packet primitives */
+#define PKTGET(osh, len, send) osl_pktget((osh), (len))
+#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
+#define PKTDATA(osh, skb) osl_pktdata((osh), (skb))
+#define PKTLEN(osh, skb) osl_pktlen((osh), (skb))
+#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb))
+#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb))
+#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb))
+#define PKTSETNEXT(osh, skb, x) osl_pktsetnext((skb), (x))
+#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len))
+#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes))
+#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes))
+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
+#define PKTTAG(skb) osl_pkttag((skb))
+#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative((osh), (struct sk_buff*)(skb))
+#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osh), (pkt))
+#define PKTLINK(skb) osl_pktlink((skb))
+#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x))
+#define PKTPRIO(skb) osl_pktprio((skb))
+#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x))
+#define PKTSHARED(skb) osl_pktshared((skb))
+#define PKTALLOCED(osh) osl_pktalloced((osh))
+#ifdef BCMDBG_PKT
+#define PKTLIST_DUMP(osh, buf) osl_pktlist_dump(osh, buf)
+#else /* BCMDBG_PKT */
+#define PKTLIST_DUMP(osh, buf)
+#endif /* BCMDBG_PKT */
+
+extern void *osl_pktget(osl_t *osh, uint len);
extern void osl_pktfree(osl_t *osh, void *skb, bool send);
+extern uchar *osl_pktdata(osl_t *osh, void *skb);
+extern uint osl_pktlen(osl_t *osh, void *skb);
+extern uint osl_pktheadroom(osl_t *osh, void *skb);
+extern uint osl_pkttailroom(osl_t *osh, void *skb);
+extern void *osl_pktnext(osl_t *osh, void *skb);
+extern void osl_pktsetnext(void *skb, void *x);
+extern void osl_pktsetlen(osl_t *osh, void *skb, uint len);
+extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes);
+extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes);
extern void *osl_pktdup(osl_t *osh, void *skb);
+extern void *osl_pkttag(void *skb);
+extern void *osl_pktlink(void *skb);
+extern void osl_pktsetlink(void *skb, void *x);
+extern uint osl_pktprio(void *skb);
+extern void osl_pktsetprio(void *skb, uint x);
+extern void *osl_pkt_frmnative(osl_t *osh, struct sk_buff *skb);
+extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt);
+extern bool osl_pktshared(void *skb);
extern uint osl_pktalloced(osl_t *osh);
+#ifdef BCMDBG_PKT /* pkt logging for debugging */
+extern char *osl_pktlist_dump(osl_t *osh, char *buf);
+extern void osl_pktlist_add(osl_t *osh, void *p);
+extern void osl_pktlist_remove(osl_t *osh, void *p);
+#endif /* BCMDBG_PKT */
+
+#endif /* BINOSL */
+
#define OSL_ERROR(bcmerror) osl_error(bcmerror)
extern int osl_error(int bcmerror);
diff --git a/package/broadcom-wl/src/driver/patchtable.pl b/package/broadcom-wl/src/driver/patchtable.pl
deleted file mode 100644
index 6999735125..0000000000
--- a/package/broadcom-wl/src/driver/patchtable.pl
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/perl
-#
-# Copyright (C) 2006 OpenWrt.org
-# Copyright (C) 2006 Felix Fietkau
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-use strict;
-
-my $TABLE = pack("V", 0xbadc0ded);
-my $TABLE_SIZE = 512;
-my $SLT1 = "\x01\x00\x00\x00";
-my $SLT2 = "\x02\x00\x00\x00";
-my $ACKW = "\x03\x00\x00\x00";
-my $PTABLE_END = "\xff\xff\xff\xff";
-
-my $addr = "";
-my $opcode = "";
-my $function = "";
-
-sub add_entry {
- my $key = shift;
- my $value = shift;
- my $default = shift;
-
- $TABLE .= $key;
- $TABLE .= pack("V", $value);
- $TABLE .= pack("V", $default);
-}
-
-while (<>) {
- $addr = $opcode = "";
- /^\w{8}\s*<(.*)>:$/ and $function = $1;
- /^\s*(\w+):\s*(\w{8})\s*/ and do {
- $addr = $1;
- $opcode = $2;
- };
-
- ($function eq 'wlc_update_slot_timing') and do {
- # li a2,9 -- short slot time
- ($opcode eq '24060009') and add_entry($SLT1, hex($addr), hex($opcode));
- # li v0,519 -- 510 + short slot time
- ($opcode eq '24020207') and add_entry($SLT2, hex($addr), hex($opcode));
-
- # li a2,20 -- long slot time
- ($opcode eq '24060014') and add_entry($SLT1, hex($addr), hex($opcode));
- # li v0,530 -- 510 + long slot time
- ($opcode eq '24020212') and add_entry($SLT2, hex($addr), hex($opcode));
- };
- ($function eq 'wlc_d11hdrs') and do {
- # ori s6,s6,0x1 -- ack flag (new)
- ($opcode eq '36d60001') and add_entry($ACKW, hex($addr), hex($opcode));
- # ori s3,s3,0x1 -- ack flag (old)
- ($opcode eq '36730001') and add_entry($ACKW, hex($addr), hex($opcode));
- }
-}
-
-$TABLE .= $PTABLE_END;
-$TABLE .= ("\x00" x ($TABLE_SIZE - length($TABLE)));
-print $TABLE;
diff --git a/package/broadcom-wl/src/driver/pktq.h b/package/broadcom-wl/src/driver/pktq.h
deleted file mode 100644
index 7fe21815e8..0000000000
--- a/package/broadcom-wl/src/driver/pktq.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Misc useful os-independent macros and functions.
- *
- * Copyright 2006, Broadcom Corporation
- * All Rights Reserved.
- *
- * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
- * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
- * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $
- */
-
-#ifndef _pktq_h_
-#define _pktq_h_
-#include <osl.h>
-
-/* osl multi-precedence packet queue */
-
-#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
-#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
-
-struct pktq {
- struct pktq_prec {
- void *head; /* first packet to dequeue */
- void *tail; /* last packet to dequeue */
- uint16 len; /* number of queued packets */
- uint16 max; /* maximum number of queued packets */
- } q[PKTQ_MAX_PREC];
- uint16 num_prec; /* number of precedences in use */
- uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
- uint16 max; /* total max packets */
- uint16 len; /* total number of packets */
-};
-
-#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
-
-/* forward definition of ether_addr structure used by some function prototypes */
-
-struct ether_addr;
-
-/* operations on a specific precedence in packet queue */
-
-#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max))
-#define pktq_plen(pq, prec) ((pq)->q[prec].len)
-#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len)
-#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max)
-#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0)
-
-#define pktq_ppeek(pq, prec) ((pq)->q[prec].head)
-#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail)
-
-extern void *pktq_penq(struct pktq *pq, int prec, void *p);
-extern void *pktq_penq_head(struct pktq *pq, int prec, void *p);
-extern void *pktq_pdeq(struct pktq *pq, int prec);
-extern void *pktq_pdeq_tail(struct pktq *pq, int prec);
-/* Empty the queue at particular precedence level */
-extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir);
-/* Remove a specified packet from its queue */
-extern bool pktq_pdel(struct pktq *pq, void *p, int prec);
-
-/* operations on a set of precedences in packet queue */
-
-extern int pktq_mlen(struct pktq *pq, uint prec_bmp);
-extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out);
-
-/* operations on packet queue as a whole */
-
-#define pktq_len(pq) ((int)(pq)->len)
-#define pktq_max(pq) ((int)(pq)->max)
-#define pktq_avail(pq) ((int)((pq)->max - (pq)->len))
-#define pktq_full(pq) ((pq)->len >= (pq)->max)
-#define pktq_empty(pq) ((pq)->len == 0)
-
-/* operations for single precedence queues */
-#define pktenq(pq, p) pktq_penq((pq), 0, (p))
-#define pktenq_head(pq, p) pktq_penq_head((pq), 0, (p))
-#define pktdeq(pq) pktq_pdeq((pq), 0)
-#define pktdeq_tail(pq) pktq_pdeq_tail((pq), 0)
-
-extern void pktq_init(struct pktq *pq, int num_prec, int max_len);
-/* prec_out may be NULL if caller is not interested in return value */
-extern void *pktq_deq(struct pktq *pq, int *prec_out);
-extern void *pktq_deq_tail(struct pktq *pq, int *prec_out);
-extern void *pktq_peek(struct pktq *pq, int *prec_out);
-extern void *pktq_peek_tail(struct pktq *pq, int *prec_out);
-extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); /* Empty the entire queue */
-
-/* externs */
-/* packet */
-extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
-extern uint pkttotlen(osl_t *osh, void *p);
-extern void *pktlast(osl_t *osh, void *p);
-
-extern void pktsetprio(void *pkt, bool update_vtag);
-
-#endif /* _pktq_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/802.11.h b/package/broadcom-wl/src/driver/proto/802.11.h
new file mode 100644
index 0000000000..83f4612e57
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/802.11.h
@@ -0,0 +1,1387 @@
+/*
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * Fundamental types and constants relating to 802.11
+ *
+ * $Id$
+ */
+
+#ifndef _802_11_H_
+#define _802_11_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+#ifndef _NET_ETHERNET_H_
+#include <proto/ethernet.h>
+#endif
+
+#include <proto/wpa.h>
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */
+
+/* Generic 802.11 frame constants */
+#define DOT11_A3_HDR_LEN 24 /* d11 header length with A3 */
+#define DOT11_A4_HDR_LEN 30 /* d11 header length with A4 */
+#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN /* MAC header length */
+#define DOT11_FCS_LEN 4 /* d11 FCS length */
+#define DOT11_ICV_LEN 4 /* d11 ICV length */
+#define DOT11_ICV_AES_LEN 8 /* d11 ICV/AES length */
+#define DOT11_QOS_LEN 2 /* d11 QoS length */
+#define DOT11_HTC_LEN 4 /* d11 HT Control field length */
+
+#define DOT11_KEY_INDEX_SHIFT 6 /* d11 key index shift */
+#define DOT11_IV_LEN 4 /* d11 IV length */
+#define DOT11_IV_TKIP_LEN 8 /* d11 IV TKIP length */
+#define DOT11_IV_AES_OCB_LEN 4 /* d11 IV/AES/OCB length */
+#define DOT11_IV_AES_CCM_LEN 8 /* d11 IV/AES/CCM length */
+#define DOT11_IV_MAX_LEN 8 /* maximum iv len for any encryption */
+
+/* Includes MIC */
+#define DOT11_MAX_MPDU_BODY_LEN 2304 /* max MPDU body length */
+/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */
+#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \
+ DOT11_QOS_LEN + \
+ DOT11_IV_AES_CCM_LEN + \
+ DOT11_MAX_MPDU_BODY_LEN + \
+ DOT11_ICV_LEN + \
+ DOT11_FCS_LEN) /* d11 max MPDU length */
+
+#define DOT11_MAX_SSID_LEN 32 /* d11 max ssid length */
+
+/* dot11RTSThreshold */
+#define DOT11_DEFAULT_RTS_LEN 2347 /* d11 default RTS length */
+#define DOT11_MAX_RTS_LEN 2347 /* d11 max RTS length */
+
+/* dot11FragmentationThreshold */
+#define DOT11_MIN_FRAG_LEN 256 /* d11 min fragmentation length */
+#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength
+ * of the attached PHY
+ */
+#define DOT11_DEFAULT_FRAG_LEN 2346 /* d11 default fragmentation length */
+
+/* dot11BeaconPeriod */
+#define DOT11_MIN_BEACON_PERIOD 1 /* d11 min beacon period */
+#define DOT11_MAX_BEACON_PERIOD 0xFFFF /* d11 max beacon period */
+
+/* dot11DTIMPeriod */
+#define DOT11_MIN_DTIM_PERIOD 1 /* d11 min DTIM period */
+#define DOT11_MAX_DTIM_PERIOD 0xFF /* d11 max DTIM period */
+
+/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */
+#define DOT11_LLC_SNAP_HDR_LEN 8 /* d11 LLC/SNAP header length */
+#define DOT11_OUI_LEN 3 /* d11 OUI length */
+struct dot11_llc_snap_header {
+ uint8 dsap; /* always 0xAA */
+ uint8 ssap; /* always 0xAA */
+ uint8 ctl; /* always 0x03 */
+ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00
+ * Bridge-Tunnel: 0x00 0x00 0xF8
+ */
+ uint16 type; /* ethertype */
+} PACKED;
+
+/* RFC1042 header used by 802.11 per 802.1H */
+#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) /* RCF1042 header length */
+
+/* Generic 802.11 MAC header */
+/*
+ * N.B.: This struct reflects the full 4 address 802.11 MAC header.
+ * The fields are defined such that the shorter 1, 2, and 3
+ * address headers just use the first k fields.
+ */
+struct dot11_header {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr a1; /* address 1 */
+ struct ether_addr a2; /* address 2 */
+ struct ether_addr a3; /* address 3 */
+ uint16 seq; /* sequence control */
+ struct ether_addr a4; /* address 4 */
+} PACKED;
+
+/* Control frames */
+
+struct dot11_rts_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+ struct ether_addr ta; /* transmitter address */
+} PACKED;
+#define DOT11_RTS_LEN 16 /* d11 RTS frame length */
+
+struct dot11_cts_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+} PACKED;
+#define DOT11_CTS_LEN 10 /* d11 CTS frame length */
+
+struct dot11_ack_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+} PACKED;
+#define DOT11_ACK_LEN 10 /* d11 ACK frame length */
+
+struct dot11_ps_poll_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* AID */
+ struct ether_addr bssid; /* receiver address, STA in AP */
+ struct ether_addr ta; /* transmitter address */
+} PACKED;
+#define DOT11_PS_POLL_LEN 16 /* d11 PS poll frame length */
+
+struct dot11_cf_end_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+ struct ether_addr bssid; /* transmitter address, STA in AP */
+} PACKED;
+#define DOT11_CS_END_LEN 16 /* d11 CF-END frame length */
+
+/* BA/BAR Control parameters */
+#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 /* normal ack */
+#define DOT11_BA_CTL_POLICY_NOACK 0x0001 /* no ack */
+#define DOT11_BA_CTL_POLICY_MASK 0x0001 /* ack policy mask */
+
+#define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */
+#define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */
+
+#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */
+#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */
+
+#define DOT11_BA_CTL_TID_MASK 0xF000 /* tid mask */
+#define DOT11_BA_CTL_TID_SHIFT 12 /* tid shift */
+
+/* control frame header (BA/BAR) */
+struct dot11_ctl_header {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+ struct ether_addr ta; /* transmitter address */
+} PACKED;
+#define DOT11_CTL_HDR_LEN 16 /* control frame hdr len */
+
+/* BAR frame payload */
+struct dot11_bar {
+ uint16 bar_control; /* BAR Control */
+ uint16 seqnum; /* Starting Sequence control */
+} PACKED;
+#define DOT11_BAR_LEN 4 /* BAR frame payload length */
+
+#define DOT11_BA_BITMAP_LEN 128 /* bitmap length */
+#define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */
+/* BA frame payload */
+struct dot11_ba {
+ uint16 ba_control; /* BA Control */
+ uint16 seqnum; /* Starting Sequence control */
+ uint8 bitmap[DOT11_BA_BITMAP_LEN]; /* Block Ack Bitmap */
+} PACKED;
+#define DOT11_BA_LEN 4 /* BA frame payload len (wo bitmap) */
+
+/* Management frame header */
+struct dot11_management_header {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr da; /* receiver address */
+ struct ether_addr sa; /* transmitter address */
+ struct ether_addr bssid; /* BSS ID */
+ uint16 seq; /* sequence control */
+} PACKED;
+#define DOT11_MGMT_HDR_LEN 24 /* d11 management header length */
+
+/* Management frame payloads */
+
+struct dot11_bcn_prb {
+ uint32 timestamp[2];
+ uint16 beacon_interval;
+ uint16 capability;
+} PACKED;
+#define DOT11_BCN_PRB_LEN 12 /* 802.11 beacon/probe frame fixed length */
+
+struct dot11_auth {
+ uint16 alg; /* algorithm */
+ uint16 seq; /* sequence control */
+ uint16 status; /* status code */
+} PACKED;
+#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge info
+ * elt
+ */
+
+struct dot11_assoc_req {
+ uint16 capability; /* capability information */
+ uint16 listen; /* listen interval */
+} PACKED;
+#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */
+
+struct dot11_reassoc_req {
+ uint16 capability; /* capability information */
+ uint16 listen; /* listen interval */
+ struct ether_addr ap; /* Current AP address */
+} PACKED;
+#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */
+
+struct dot11_assoc_resp {
+ uint16 capability; /* capability information */
+ uint16 status; /* status code */
+ uint16 aid; /* association ID */
+} PACKED;
+
+struct dot11_action_measure {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 data[1];
+} PACKED;
+#define DOT11_ACTION_MEASURE_LEN 3 /* d11 action measurement header length */
+
+struct dot11_action_ht_ch_width {
+ uint8 category;
+ uint8 action;
+ uint8 ch_width;
+} PACKED;
+
+struct dot11_action_ht_mimops {
+ uint8 category;
+ uint8 action;
+ uint8 control;
+} PACKED;
+
+#define SM_PWRSAVE_ENABLE 1
+#define SM_PWRSAVE_MODE 2
+
+struct dot11_action_ht_info_xchg {
+ uint8 category;
+ uint8 action;
+ uint8 info;
+} PACKED;
+
+#define DOT11_HT_INFO_XCHG_INFO_REQ 0x01
+#define DOT11_HT_INFO_XCHG_40MHZ_INTOLERANT 0x02
+#define DOT11_HT_INFO_XCHG_STA_CHAN_WIDTH 0x04
+
+
+/* ************* 802.11h related definitions. ************* */
+struct dot11_power_cnst {
+ uint8 id;
+ uint8 len;
+ uint8 power;
+} PACKED;
+typedef struct dot11_power_cnst dot11_power_cnst_t;
+
+struct dot11_power_cap {
+ uint8 min;
+ uint8 max;
+} PACKED;
+typedef struct dot11_power_cap dot11_power_cap_t;
+
+struct dot11_tpc_rep {
+ uint8 id;
+ uint8 len;
+ uint8 tx_pwr;
+ uint8 margin;
+} PACKED;
+typedef struct dot11_tpc_rep dot11_tpc_rep_t;
+#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */
+
+struct dot11_supp_channels {
+ uint8 id;
+ uint8 len;
+ uint8 first_channel;
+ uint8 num_channels;
+} PACKED;
+typedef struct dot11_supp_channels dot11_supp_channels_t;
+
+/* Extension Channel Offset IE: 802.11n-D1.0 spec. added sideband
+ * offset for 40MHz operation. The possible 3 values are:
+ * 1 = above control channel
+ * 3 = below control channel
+ * 0 = no extension channel
+ */
+struct dot11_extch {
+ uint8 id; /* IE ID, 62, DOT11_MNG_EXT_CHANNEL_OFFSET */
+ uint8 len; /* IE length */
+ uint8 extch;
+} PACKED;
+typedef struct dot11_extch dot11_extch_ie_t;
+
+struct dot11_brcm_extch {
+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */
+ uint8 len; /* IE length */
+ uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */
+ uint8 type; /* type inidicates what follows */
+ uint8 extch;
+} PACKED;
+typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t;
+
+#define BRCM_EXTCH_IE_LEN 5
+#define BRCM_EXTCH_IE_TYPE 53 /* 802.11n ID not yet assigned */
+#define DOT11_EXTCH_IE_LEN 1
+#define DOT11_EXT_CH_MASK 0x03 /* extension channel mask */
+#define DOT11_EXT_CH_UPPER 0x01 /* ext. ch. on upper sb */
+#define DOT11_EXT_CH_LOWER 0x03 /* ext. ch. on lower sb */
+#define DOT11_EXT_CH_NONE 0x00 /* no extension ch. */
+
+struct dot11_action_frmhdr {
+ uint8 category;
+ uint8 action;
+ uint8 data[1];
+} PACKED;
+
+/* CSA IE data structure */
+struct dot11_channel_switch {
+ uint8 id; /* id DOT11_MNG_CHANNEL_SWITCH_ID */
+ uint8 len; /* length of IE */
+ uint8 mode; /* mode 0 or 1 */
+ uint8 channel; /* channel switch to */
+ uint8 count; /* number of beacons before switching */
+} PACKED;
+typedef struct dot11_channel_switch dot11_chan_switch_ie_t;
+
+#define DOT11_SWITCH_IE_LEN 3 /* length of IE data, not including 2 byte header */
+/* CSA mode - 802.11h-2003 $7.3.2.20 */
+#define DOT11_CSA_MODE_ADVISORY 0 /* no DOT11_CSA_MODE_NO_TX restriction imposed */
+#define DOT11_CSA_MODE_NO_TX 1 /* no transmission upon receiving CSA frame. */
+
+struct dot11_action_switch_channel {
+ uint8 category;
+ uint8 action;
+ dot11_chan_switch_ie_t chan_switch_ie; /* for switch IE */
+ dot11_brcm_extch_ie_t extch_ie; /* extension channel offset */
+} PACKED;
+
+/* 11n Extended Channel Switch IE data structure */
+struct dot11_ext_csa {
+ uint8 id; /* id DOT11_MNG_EXT_CHANNEL_SWITCH_ID */
+ uint8 len; /* length of IE */
+ uint8 mode; /* mode 0 or 1 */
+ uint8 reg; /* regulatory class */
+ uint8 channel; /* channel switch to */
+ uint8 count; /* number of beacons before switching */
+} PACKED;
+typedef struct dot11_ext_csa dot11_ext_csa_ie_t;
+#define DOT11_EXT_CSA_IE_LEN 4 /* length of extended channel switch IE body */
+
+struct dot11_action_ext_csa {
+ uint8 category;
+ uint8 action;
+ dot11_ext_csa_ie_t chan_switch_ie; /* for switch IE */
+} PACKED;
+
+/* 802.11h Measurement Request/Report IEs */
+/* Measurement Type field */
+#define DOT11_MEASURE_TYPE_BASIC 0 /* d11 measurement basic type */
+#define DOT11_MEASURE_TYPE_CCA 1 /* d11 measurement CCA type */
+#define DOT11_MEASURE_TYPE_RPI 2 /* d11 measurement PRI type */
+
+/* Measurement Request Modes */
+#define DOT11_MEASURE_MODE_ENABLE (1<<1) /* d11 measurement enable */
+#define DOT11_MEASURE_MODE_REQUEST (1<<2) /* d11 measurement request */
+#define DOT11_MEASURE_MODE_REPORT (1<<3) /* d11 measurement report */
+/* Measurement Report Modes */
+#define DOT11_MEASURE_MODE_LATE (1<<0) /* d11 measurement late */
+#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) /* d11 measurement incapable */
+#define DOT11_MEASURE_MODE_REFUSED (1<<2) /* d11 measurement refuse */
+/* Basic Measurement Map bits */
+#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) /* d11 measurement basic map BSS */
+#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) /* d11 measurement map OFDM */
+#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) /* d11 measurement map unknown */
+#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) /* d11 measurement map radar */
+#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) /* d11 measurement map unmeasuremnt */
+
+struct dot11_meas_req {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+} PACKED;
+typedef struct dot11_meas_req dot11_meas_req_t;
+#define DOT11_MNG_IE_MREQ_LEN 14 /* d11 measurement request IE length */
+/* length of Measure Request IE data not including variable len */
+#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 /* d11 measurement request IE fixed length */
+
+struct dot11_meas_rep {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ union
+ {
+ struct {
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+ uint8 map;
+ } PACKED basic;
+ uint8 data[1];
+ } PACKED rep;
+} PACKED;
+typedef struct dot11_meas_rep dot11_meas_rep_t;
+
+/* length of Measure Report IE data not including variable len */
+#define DOT11_MNG_IE_MREP_FIXED_LEN 3 /* d11 measurement response IE fixed length */
+
+struct dot11_meas_rep_basic {
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+ uint8 map;
+} PACKED;
+typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t;
+#define DOT11_MEASURE_BASIC_REP_LEN 12 /* d11 measurement basic report length */
+
+struct dot11_quiet {
+ uint8 id;
+ uint8 len;
+ uint8 count; /* TBTTs until beacon interval in quiet starts */
+ uint8 period; /* Beacon intervals between periodic quiet periods ? */
+ uint16 duration; /* Length of quiet period, in TU's */
+ uint16 offset; /* TU's offset from TBTT in Count field */
+} PACKED;
+typedef struct dot11_quiet dot11_quiet_t;
+
+struct chan_map_tuple {
+ uint8 channel;
+ uint8 map;
+} PACKED;
+typedef struct chan_map_tuple chan_map_tuple_t;
+
+struct dot11_ibss_dfs {
+ uint8 id;
+ uint8 len;
+ uint8 eaddr[ETHER_ADDR_LEN];
+ uint8 interval;
+ chan_map_tuple_t map[1];
+} PACKED;
+typedef struct dot11_ibss_dfs dot11_ibss_dfs_t;
+
+/* WME Elements */
+#define WME_OUI "\x00\x50\xf2" /* WME OUI */
+#define WME_VER 1 /* WME version */
+#define WME_TYPE 2 /* WME type */
+#define WME_SUBTYPE_IE 0 /* Information Element */
+#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */
+#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */
+
+/* WME Access Category Indices (ACIs) */
+#define AC_BE 0 /* Best Effort */
+#define AC_BK 1 /* Background */
+#define AC_VI 2 /* Video */
+#define AC_VO 3 /* Voice */
+#define AC_COUNT 4 /* number of ACs */
+
+typedef uint8 ac_bitmap_t; /* AC bitmap of (1 << AC_xx) */
+
+#define AC_BITMAP_NONE 0x0 /* No ACs */
+#define AC_BITMAP_ALL 0xf /* All ACs */
+#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0)
+
+/* WME Information Element (IE) */
+struct wme_ie {
+ uint8 oui[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ uint8 qosinfo;
+} PACKED;
+typedef struct wme_ie wme_ie_t;
+#define WME_IE_LEN 7 /* WME IE length */
+
+struct edcf_acparam {
+ uint8 ACI;
+ uint8 ECW;
+ uint16 TXOP; /* stored in network order (ls octet first) */
+} PACKED;
+typedef struct edcf_acparam edcf_acparam_t;
+
+/* WME Parameter Element (PE) */
+struct wme_param_ie {
+ uint8 oui[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ uint8 qosinfo;
+ uint8 rsvd;
+ edcf_acparam_t acparam[AC_COUNT];
+} PACKED;
+typedef struct wme_param_ie wme_param_ie_t;
+#define WME_PARAM_IE_LEN 24 /* WME Parameter IE length */
+
+/* QoS Info field for IE as sent from AP */
+#define WME_QI_AP_APSD_MASK 0x80 /* U-APSD Supported mask */
+#define WME_QI_AP_APSD_SHIFT 7 /* U-APSD Supported shift */
+#define WME_QI_AP_COUNT_MASK 0x0f /* Parameter set count mask */
+#define WME_QI_AP_COUNT_SHIFT 0 /* Parameter set count shift */
+
+/* QoS Info field for IE as sent from STA */
+#define WME_QI_STA_MAXSPLEN_MASK 0x60 /* Max Service Period Length mask */
+#define WME_QI_STA_MAXSPLEN_SHIFT 5 /* Max Service Period Length shift */
+#define WME_QI_STA_APSD_ALL_MASK 0xf /* APSD all AC bits mask */
+#define WME_QI_STA_APSD_ALL_SHIFT 0 /* APSD all AC bits shift */
+#define WME_QI_STA_APSD_BE_MASK 0x8 /* APSD AC_BE mask */
+#define WME_QI_STA_APSD_BE_SHIFT 3 /* APSD AC_BE shift */
+#define WME_QI_STA_APSD_BK_MASK 0x4 /* APSD AC_BK mask */
+#define WME_QI_STA_APSD_BK_SHIFT 2 /* APSD AC_BK shift */
+#define WME_QI_STA_APSD_VI_MASK 0x2 /* APSD AC_VI mask */
+#define WME_QI_STA_APSD_VI_SHIFT 1 /* APSD AC_VI shift */
+#define WME_QI_STA_APSD_VO_MASK 0x1 /* APSD AC_VO mask */
+#define WME_QI_STA_APSD_VO_SHIFT 0 /* APSD AC_VO shift */
+
+/* ACI */
+#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */
+#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */
+#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */
+#define EDCF_ACM_MASK 0x10 /* ACM mask */
+#define EDCF_ACI_MASK 0x60 /* ACI mask */
+#define EDCF_ACI_SHIFT 5 /* ACI shift */
+
+/* ECW */
+#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */
+#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */
+#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1)
+#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */
+#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */
+#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */
+
+/* TXOP */
+#define EDCF_TXOP_MIN 0 /* TXOP minimum value */
+#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */
+#define EDCF_TXOP2USEC(txop) ((txop) << 5)
+
+/* Default EDCF parameters that AP advertises for STA to use; WMM draft Table 12 */
+#define EDCF_AC_BE_ACI_STA 0x03 /* STA ACI value for best effort AC */
+#define EDCF_AC_BE_ECW_STA 0xA4 /* STA ECW value for best effort AC */
+#define EDCF_AC_BE_TXOP_STA 0x0000 /* STA TXOP value for best effort AC */
+#define EDCF_AC_BK_ACI_STA 0x27 /* STA ACI value for background AC */
+#define EDCF_AC_BK_ECW_STA 0xA4 /* STA ECW value for background AC */
+#define EDCF_AC_BK_TXOP_STA 0x0000 /* STA TXOP value for background AC */
+#define EDCF_AC_VI_ACI_STA 0x42 /* STA ACI value for video AC */
+#define EDCF_AC_VI_ECW_STA 0x43 /* STA ECW value for video AC */
+#define EDCF_AC_VI_TXOP_STA 0x005e /* STA TXOP value for video AC */
+#define EDCF_AC_VO_ACI_STA 0x62 /* STA ACI value for audio AC */
+#define EDCF_AC_VO_ECW_STA 0x32 /* STA ECW value for audio AC */
+#define EDCF_AC_VO_TXOP_STA 0x002f /* STA TXOP value for audio AC */
+
+/* Default EDCF parameters that AP uses; WMM draft Table 14 */
+#define EDCF_AC_BE_ACI_AP 0x03 /* AP ACI value for best effort AC */
+#define EDCF_AC_BE_ECW_AP 0x64 /* AP ECW value for best effort AC */
+#define EDCF_AC_BE_TXOP_AP 0x0000 /* AP TXOP value for best effort AC */
+#define EDCF_AC_BK_ACI_AP 0x27 /* AP ACI value for background AC */
+#define EDCF_AC_BK_ECW_AP 0xA4 /* AP ECW value for background AC */
+#define EDCF_AC_BK_TXOP_AP 0x0000 /* AP TXOP value for background AC */
+#define EDCF_AC_VI_ACI_AP 0x41 /* AP ACI value for video AC */
+#define EDCF_AC_VI_ECW_AP 0x43 /* AP ECW value for video AC */
+#define EDCF_AC_VI_TXOP_AP 0x005e /* AP TXOP value for video AC */
+#define EDCF_AC_VO_ACI_AP 0x61 /* AP ACI value for audio AC */
+#define EDCF_AC_VO_ECW_AP 0x32 /* AP ECW value for audio AC */
+#define EDCF_AC_VO_TXOP_AP 0x002f /* AP TXOP value for audio AC */
+
+struct dot11_qbss_load_ie {
+ uint8 id; /* 11, DOT11_MNG_QBSS_LOAD_ID */
+ uint8 length;
+ uint16 station_count; /* total number of STAs associated */
+ uint8 channel_utilization; /* % of time, normalized to 255, QAP sensed medium busy */
+ uint16 aac; /* available admission capacity */
+} PACKED;
+typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t;
+
+/* nom_msdu_size */
+#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */
+#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */
+
+/* surplus_bandwidth */
+/* Represented as 3 bits of integer, binary point, 13 bits fraction */
+#define INTEGER_SHIFT 13 /* integer shift */
+#define FRACTION_MASK 0x1FFF /* fraction mask */
+
+/* Management Notification Frame */
+struct dot11_management_notification {
+ uint8 category; /* DOT11_ACTION_NOTIFICATION */
+ uint8 action;
+ uint8 token;
+ uint8 status;
+ uint8 data[1]; /* Elements */
+} PACKED;
+#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */
+
+/* WME Action Codes */
+#define WME_ADDTS_REQUEST 0 /* WME ADDTS request */
+#define WME_ADDTS_RESPONSE 1 /* WME ADDTS response */
+#define WME_DELTS_REQUEST 2 /* WME DELTS request */
+
+/* WME Setup Response Status Codes */
+#define WME_ADMISSION_ACCEPTED 0 /* WME admission accepted */
+#define WME_INVALID_PARAMETERS 1 /* WME invalide parameters */
+#define WME_ADMISSION_REFUSED 3 /* WME admission refused */
+
+/* Macro to take a pointer to a beacon or probe response
+ * body and return the char* pointer to the SSID info element
+ */
+#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN)
+
+/* Authentication frame payload constants */
+#define DOT11_OPEN_SYSTEM 0 /* d11 open authentication */
+#define DOT11_SHARED_KEY 1 /* d11 shared authentication */
+#define DOT11_CHALLENGE_LEN 128 /* d11 challenge text length */
+
+/* Frame control macros */
+#define FC_PVER_MASK 0x3 /* PVER mask */
+#define FC_PVER_SHIFT 0 /* PVER shift */
+#define FC_TYPE_MASK 0xC /* type mask */
+#define FC_TYPE_SHIFT 2 /* type shift */
+#define FC_SUBTYPE_MASK 0xF0 /* subtype mask */
+#define FC_SUBTYPE_SHIFT 4 /* subtype shift */
+#define FC_TODS 0x100 /* to DS */
+#define FC_TODS_SHIFT 8 /* to DS shift */
+#define FC_FROMDS 0x200 /* from DS */
+#define FC_FROMDS_SHIFT 9 /* from DS shift */
+#define FC_MOREFRAG 0x400 /* more frag. */
+#define FC_MOREFRAG_SHIFT 10 /* more frag. shift */
+#define FC_RETRY 0x800 /* retry */
+#define FC_RETRY_SHIFT 11 /* retry shift */
+#define FC_PM 0x1000 /* PM */
+#define FC_PM_SHIFT 12 /* PM shift */
+#define FC_MOREDATA 0x2000 /* more data */
+#define FC_MOREDATA_SHIFT 13 /* more data shift */
+#define FC_WEP 0x4000 /* WEP */
+#define FC_WEP_SHIFT 14 /* WEP shift */
+#define FC_ORDER 0x8000 /* order */
+#define FC_ORDER_SHIFT 15 /* order shift */
+
+/* sequence control macros */
+#define SEQNUM_SHIFT 4 /* seq. number shift */
+#define SEQNUM_MAX 0x1000 /* max seqnum + 1 */
+#define FRAGNUM_MASK 0xF /* frag. number mask */
+
+/* Frame Control type/subtype defs */
+
+/* FC Types */
+#define FC_TYPE_MNG 0 /* management type */
+#define FC_TYPE_CTL 1 /* control type */
+#define FC_TYPE_DATA 2 /* data type */
+
+/* Management Subtypes */
+#define FC_SUBTYPE_ASSOC_REQ 0 /* assoc. request */
+#define FC_SUBTYPE_ASSOC_RESP 1 /* assoc. response */
+#define FC_SUBTYPE_REASSOC_REQ 2 /* reassoc. request */
+#define FC_SUBTYPE_REASSOC_RESP 3 /* reassoc. response */
+#define FC_SUBTYPE_PROBE_REQ 4 /* probe request */
+#define FC_SUBTYPE_PROBE_RESP 5 /* probe response */
+#define FC_SUBTYPE_BEACON 8 /* beacon */
+#define FC_SUBTYPE_ATIM 9 /* ATIM */
+#define FC_SUBTYPE_DISASSOC 10 /* disassoc. */
+#define FC_SUBTYPE_AUTH 11 /* authentication */
+#define FC_SUBTYPE_DEAUTH 12 /* de-authentication */
+#define FC_SUBTYPE_ACTION 13 /* action */
+#define FC_SUBTYPE_ACTION_NOACK 14 /* action no-ack */
+
+/* Control Subtypes */
+#define FC_SUBTYPE_CTL_WRAPPER 7 /* Control Wrapper */
+#define FC_SUBTYPE_BLOCKACK_REQ 8 /* Block Ack Req */
+#define FC_SUBTYPE_BLOCKACK 9 /* Block Ack */
+#define FC_SUBTYPE_PS_POLL 10 /* PS poll */
+#define FC_SUBTYPE_RTS 11 /* RTS */
+#define FC_SUBTYPE_CTS 12 /* CTS */
+#define FC_SUBTYPE_ACK 13 /* ACK */
+#define FC_SUBTYPE_CF_END 14 /* CF-END */
+#define FC_SUBTYPE_CF_END_ACK 15 /* CF-END ACK */
+
+/* Data Subtypes */
+#define FC_SUBTYPE_DATA 0 /* Data */
+#define FC_SUBTYPE_DATA_CF_ACK 1 /* Data + CF-ACK */
+#define FC_SUBTYPE_DATA_CF_POLL 2 /* Data + CF-Poll */
+#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 /* Data + CF-Ack + CF-Poll */
+#define FC_SUBTYPE_NULL 4 /* Null */
+#define FC_SUBTYPE_CF_ACK 5 /* CF-Ack */
+#define FC_SUBTYPE_CF_POLL 6 /* CF-Poll */
+#define FC_SUBTYPE_CF_ACK_POLL 7 /* CF-Ack + CF-Poll */
+#define FC_SUBTYPE_QOS_DATA 8 /* QoS Data */
+#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 /* QoS Data + CF-Ack */
+#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 /* QoS Data + CF-Poll */
+#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 /* QoS Data + CF-Ack + CF-Poll */
+#define FC_SUBTYPE_QOS_NULL 12 /* QoS Null */
+#define FC_SUBTYPE_QOS_CF_POLL 14 /* QoS CF-Poll */
+#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 /* QoS CF-Ack + CF-Poll */
+
+/* Data Subtype Groups */
+#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0)
+#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0)
+#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0)
+#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0)
+
+/* Type/Subtype Combos */
+#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) /* FC kind mask */
+
+#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) /* FC kind */
+
+#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) /* Subtype from FC */
+#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) /* Type from FC */
+
+#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) /* assoc. request */
+#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) /* assoc. response */
+#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) /* reassoc. request */
+#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) /* reassoc. response */
+#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) /* probe request */
+#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) /* probe response */
+#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) /* beacon */
+#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) /* disassoc */
+#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) /* authentication */
+#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) /* deauthentication */
+#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) /* action */
+#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) /* action no-ack */
+
+#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) /* Control Wrapper */
+#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) /* Block Ack Req */
+#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) /* Block Ack */
+#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) /* PS poll */
+#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) /* RTS */
+#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) /* CTS */
+#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) /* ACK */
+#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) /* CF-END */
+#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) /* CF-END ACK */
+
+#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) /* data */
+#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) /* null data */
+#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) /* data CF ACK */
+#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) /* QoS data */
+#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) /* QoS null */
+
+/* QoS Control Field */
+
+/* 802.1D Priority */
+#define QOS_PRIO_SHIFT 0 /* QoS priority shift */
+#define QOS_PRIO_MASK 0x0007 /* QoS priority mask */
+#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) /* QoS priority */
+
+/* Traffic Identifier */
+#define QOS_TID_SHIFT 0 /* QoS TID shift */
+#define QOS_TID_MASK 0x000f /* QoS TID mask */
+#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) /* QoS TID */
+
+/* End of Service Period (U-APSD) */
+#define QOS_EOSP_SHIFT 4 /* QoS End of Service Period shift */
+#define QOS_EOSP_MASK 0x0010 /* QoS End of Service Period mask */
+#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) /* Qos EOSP */
+
+/* Ack Policy */
+#define QOS_ACK_NORMAL_ACK 0 /* Normal Ack */
+#define QOS_ACK_NO_ACK 1 /* No Ack (eg mcast) */
+#define QOS_ACK_NO_EXP_ACK 2 /* No Explicit Ack */
+#define QOS_ACK_BLOCK_ACK 3 /* Block Ack */
+#define QOS_ACK_SHIFT 5 /* QoS ACK shift */
+#define QOS_ACK_MASK 0x0060 /* QoS ACK mask */
+#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) /* QoS ACK */
+
+/* A-MSDU flag */
+#define QOS_AMSDU_SHIFT 7 /* AMSDU shift */
+#define QOS_AMSDU_MASK 0x0080 /* AMSDU mask */
+
+/* Management Frames */
+
+/* Management Frame Constants */
+
+/* Fixed fields */
+#define DOT11_MNG_AUTH_ALGO_LEN 2 /* d11 management auth. algo. length */
+#define DOT11_MNG_AUTH_SEQ_LEN 2 /* d11 management auth. seq. length */
+#define DOT11_MNG_BEACON_INT_LEN 2 /* d11 management beacon interval length */
+#define DOT11_MNG_CAP_LEN 2 /* d11 management cap. length */
+#define DOT11_MNG_AP_ADDR_LEN 6 /* d11 management AP address length */
+#define DOT11_MNG_LISTEN_INT_LEN 2 /* d11 management listen interval length */
+#define DOT11_MNG_REASON_LEN 2 /* d11 management reason length */
+#define DOT11_MNG_AID_LEN 2 /* d11 management AID length */
+#define DOT11_MNG_STATUS_LEN 2 /* d11 management status length */
+#define DOT11_MNG_TIMESTAMP_LEN 8 /* d11 management timestamp length */
+
+/* DUR/ID field in assoc resp is 0xc000 | AID */
+#define DOT11_AID_MASK 0x3fff /* d11 AID mask */
+
+/* Reason Codes */
+#define DOT11_RC_RESERVED 0 /* d11 RC reserved */
+#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */
+#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */
+#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station
+ * is leaving (or has left) IBSS or ESS
+ */
+#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */
+#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle
+ * all currently associated stations
+ */
+#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from
+ * nonauthenticated station
+ */
+#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from
+ * nonassociated station
+ */
+#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is
+ * leaving (or has left) BSS
+ */
+#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is not
+ * authenticated with responding station
+ */
+#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */
+#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */
+/* 12 is unused */
+
+/* 32-39 are QSTA specific reasons added in 11e */
+#define DOT11_RC_UNSPECIFIED_QOS 32 /* unspecified QoS-related reason */
+#define DOT11_RC_INSUFFCIENT_BW 33 /* QAP lacks sufficient bandwidth */
+#define DOT11_RC_EXCESSIVE_FRAMES 34 /* excessive number of frames need ack */
+#define DOT11_RC_TX_OUTSIDE_TXOP 35 /* transmitting outside the limits of txop */
+#define DOT11_RC_LEAVING_QBSS 36 /* QSTA is leaving the QBSS (or restting) */
+#define DOT11_RC_BAD_MECHANISM 37 /* does not want to use the mechanism */
+#define DOT11_RC_SETUP_NEEDED 38 /* mechanism needs a setup */
+#define DOT11_RC_TIMEOUT 39 /* timeout */
+
+#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */
+
+/* Status Codes */
+#define DOT11_SC_SUCCESS 0 /* Successful */
+#define DOT11_SC_FAILURE 1 /* Unspecified failure */
+#define DOT11_SC_CAP_MISMATCH 10 /* Cannot support all requested
+ * capabilities in the Capability
+ * Information field
+ */
+#define DOT11_SC_REASSOC_FAIL 11 /* Reassociation denied due to inability
+ * to confirm that association exists
+ */
+#define DOT11_SC_ASSOC_FAIL 12 /* Association denied due to reason
+ * outside the scope of this standard
+ */
+#define DOT11_SC_AUTH_MISMATCH 13 /* Responding station does not support
+ * the specified authentication
+ * algorithm
+ */
+#define DOT11_SC_AUTH_SEQ 14 /* Received an Authentication frame
+ * with authentication transaction
+ * sequence number out of expected
+ * sequence
+ */
+#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of
+ * challenge failure
+ */
+#define DOT11_SC_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout
+ * waiting for next frame in sequence
+ */
+#define DOT11_SC_ASSOC_BUSY_FAIL 17 /* Association denied because AP is
+ * unable to handle additional
+ * associated stations
+ */
+#define DOT11_SC_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting
+ * station not supporting all of the
+ * data rates in the BSSBasicRateSet
+ * parameter
+ */
+#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting
+ * station not supporting the Short
+ * Preamble option
+ */
+#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting
+ * station not supporting the PBCC
+ * Modulation option
+ */
+#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting
+ * station not supporting the Channel
+ * Agility option
+ */
+#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum
+ * Management capability is required.
+ */
+#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info
+ * in the Power Cap element is
+ * unacceptable.
+ */
+#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info
+ * in the Supported Channel element is
+ * unacceptable
+ */
+#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting
+ * station not supporting the Short Slot
+ * Time option
+ */
+#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting
+ * station not supporting the ER-PBCC
+ * Modulation option
+ */
+#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting
+ * station not supporting the DSS-OFDM
+ * option
+ */
+
+#define DOT11_SC_DECLINED 37 /* request declined */
+#define DOT11_SC_INVALID_PARAMS 38 /* One or more params have invalid values */
+
+/* Info Elts, length of INFORMATION portion of Info Elts */
+#define DOT11_MNG_DS_PARAM_LEN 1 /* d11 management DS parameter length */
+#define DOT11_MNG_IBSS_PARAM_LEN 2 /* d11 management IBSS parameter length */
+
+/* TIM Info element has 3 bytes fixed info in INFORMATION field,
+ * followed by 1 to 251 bytes of Partial Virtual Bitmap
+ */
+#define DOT11_MNG_TIM_FIXED_LEN 3 /* d11 management TIM fixed length */
+#define DOT11_MNG_TIM_DTIM_COUNT 0 /* d11 management DTIM count */
+#define DOT11_MNG_TIM_DTIM_PERIOD 1 /* d11 management DTIM period */
+#define DOT11_MNG_TIM_BITMAP_CTL 2 /* d11 management TIM BITMAP control */
+#define DOT11_MNG_TIM_PVB 3 /* d11 management TIM PVB */
+
+/* TLV defines */
+#define TLV_TAG_OFF 0 /* tag offset */
+#define TLV_LEN_OFF 1 /* length offset */
+#define TLV_HDR_LEN 2 /* header length */
+#define TLV_BODY_OFF 2 /* body offset */
+
+/* Management Frame Information Element IDs */
+#define DOT11_MNG_SSID_ID 0 /* d11 management SSID id */
+#define DOT11_MNG_RATES_ID 1 /* d11 management rates id */
+#define DOT11_MNG_FH_PARMS_ID 2 /* d11 management FH parameter id */
+#define DOT11_MNG_DS_PARMS_ID 3 /* d11 management DS parameter id */
+#define DOT11_MNG_CF_PARMS_ID 4 /* d11 management CF parameter id */
+#define DOT11_MNG_TIM_ID 5 /* d11 management TIM id */
+#define DOT11_MNG_IBSS_PARMS_ID 6 /* d11 management IBSS parameter id */
+#define DOT11_MNG_COUNTRY_ID 7 /* d11 management country id */
+#define DOT11_MNG_HOPPING_PARMS_ID 8 /* d11 management hopping parameter id */
+#define DOT11_MNG_HOPPING_TABLE_ID 9 /* d11 management hopping table id */
+#define DOT11_MNG_REQUEST_ID 10 /* d11 management request id */
+#define DOT11_MNG_QBSS_LOAD_ID 11 /* d11 management QBSS Load id */
+#define DOT11_MNG_CHALLENGE_ID 16 /* d11 management chanllenge id */
+#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */
+#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */
+#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */
+#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */
+#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */
+#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement */
+#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */
+#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */
+#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */
+#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */
+#define DOT11_MNG_ERP_ID 42 /* d11 management ERP id */
+#define DOT11_MNG_TS_DELAY_ID 43 /* d11 management TS Delay id */
+#define DOT11_MNG_HT_CAP 45 /* d11 mgmt HT cap id */
+#define DOT11_MNG_NONERP_ID 47 /* d11 management NON-ERP id */
+#define DOT11_MNG_RSN_ID 48 /* d11 management RSN id */
+#define DOT11_MNG_EXT_RATES_ID 50 /* d11 management ext. rates id */
+#define DOT11_MNG_EXT_CSA_ID 60 /* d11 Extended CSA */
+#define DOT11_MNG_HT_ADD 61 /* d11 mgmt additional HT info */
+#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 /* d11 mgmt ext channel offset */
+#define DOT11_MNG_EXT_CAP 127 /* d11 mgmt ext capability */
+#define DOT11_MNG_WPA_ID 221 /* d11 management WPA id */
+#define DOT11_MNG_PROPR_ID 221 /* d11 management proprietary id */
+
+/* Rate element Basic flag and rate mask */
+#define DOT11_RATE_BASIC 0x80 /* flag for a Basic Rate */
+#define DOT11_RATE_MASK 0x7F /* mask for numeric part of rate */
+
+/* ERP info element bit values */
+#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */
+#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present
+ *in the BSS
+ */
+#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for
+ *ERP-OFDM frames
+ */
+#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed,
+ * 1 == not allowed
+ */
+/* TS Delay element offset & size */
+#define DOT11_MGN_TS_DELAY_LEN 4 /* length of TS DELAY IE */
+#define TS_DELAY_FIELD_SIZE 4 /* TS DELAY field size */
+
+/* Capability Information Field */
+#define DOT11_CAP_ESS 0x0001 /* d11 cap. ESS */
+#define DOT11_CAP_IBSS 0x0002 /* d11 cap. IBSS */
+#define DOT11_CAP_POLLABLE 0x0004 /* d11 cap. pollable */
+#define DOT11_CAP_POLL_RQ 0x0008 /* d11 cap. poll request */
+#define DOT11_CAP_PRIVACY 0x0010 /* d11 cap. privacy */
+#define DOT11_CAP_SHORT 0x0020 /* d11 cap. short */
+#define DOT11_CAP_PBCC 0x0040 /* d11 cap. PBCC */
+#define DOT11_CAP_AGILITY 0x0080 /* d11 cap. agility */
+#define DOT11_CAP_SPECTRUM 0x0100 /* d11 cap. spectrum */
+#define DOT11_CAP_SHORTSLOT 0x0400 /* d11 cap. shortslot */
+#define DOT11_CAP_CCK_OFDM 0x2000 /* d11 cap. CCK/OFDM */
+
+/* Extended Capability Information Field */
+#define DOT11_EXT_CAP_HT_IE_SUPPORT 0x01 /* support for info xchg action frame */
+
+/* Action Frame Constants */
+#define DOT11_ACTION_HDR_LEN 2 /* action frame header length */
+#define DOT11_ACTION_CAT_ERR_MASK 0x80 /* d11 action category error mask */
+#define DOT11_ACTION_CAT_MASK 0x7F /* d11 action category mask */
+#define DOT11_ACTION_CAT_SPECT_MNG 0x00 /* d11 action category spectrum management */
+#define DOT11_ACTION_CAT_BLOCKACK 0x03 /* d11 action category block ack */
+#define DOT11_ACTION_CAT_HT 0x07 /* d11 action category for HT */
+#define DOT11_ACTION_NOTIFICATION 0x11 /* 17 */
+
+#define DOT11_ACTION_ID_M_REQ 0 /* d11 action measurement request */
+#define DOT11_ACTION_ID_M_REP 1 /* d11 action measurement response */
+#define DOT11_ACTION_ID_TPC_REQ 2 /* d11 action TPC request */
+#define DOT11_ACTION_ID_TPC_REP 3 /* d11 action TPC response */
+#define DOT11_ACTION_ID_CHANNEL_SWITCH 4 /* d11 action channel switch */
+#define DOT11_ACTION_ID_EXT_CSA 5 /* d11 extened CSA for 11n */
+
+/* HT action ids */
+#define DOT11_ACTION_ID_HT_CH_WIDTH 0 /* notify channel width action id */
+#define DOT11_ACTION_ID_HT_MIMO_PS 1 /* mimo ps action id */
+#define DOT11_ACTION_ID_HT_INFO_XCHG 8 /* HT Information Exchange action id */
+
+/* Block Ack action types */
+#define DOT11_BA_ACTION_ADDBA_REQ 0 /* ADDBA Req action frame type */
+#define DOT11_BA_ACTION_ADDBA_RESP 1 /* ADDBA Resp action frame type */
+#define DOT11_BA_ACTION_DELBA 2 /* DELBA action frame type */
+
+/* ADDBA action parameters */
+#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 /* AMSDU supported under BA */
+#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 /* policy mask(ack vs delayed) */
+#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 /* policy shift */
+#define DOT11_ADDBA_PARAM_TID_MASK 0x003c /* tid mask */
+#define DOT11_ADDBA_PARAM_TID_SHIFT 2 /* tid shift */
+#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 /* buffer size mask */
+#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 /* buffer size shift */
+
+#define DOT11_ADDBA_POLICY_DELAYED 0 /* delayed BA policy */
+#define DOT11_ADDBA_POLICY_IMMEDIATE 1 /* immediate BA policy */
+
+struct dot11_addba_req {
+ uint8 category; /* category of action frame (3) */
+ uint8 action; /* action: addba req */
+ uint8 token; /* identifier */
+ uint16 addba_param_set; /* parameter set */
+ uint16 timeout; /* timeout in seconds */
+ uint16 start_seqnum; /* starting sequence number */
+}PACKED;
+typedef struct dot11_addba_req dot11_addba_req_t;
+#define DOT11_ADDBA_REQ_LEN 9 /* length of addba req frame */
+
+struct dot11_addba_resp {
+ uint8 category; /* category of action frame (3) */
+ uint8 action; /* action: addba resp */
+ uint8 token; /* identifier */
+ uint16 status; /* status of add request */
+ uint16 addba_param_set; /* negotiated parameter set */
+ uint16 timeout; /* negotiated timeout in seconds */
+}PACKED;
+typedef struct dot11_addba_resp dot11_addba_resp_t;
+#define DOT11_ADDBA_RESP_LEN 9 /* length of addba resp frame */
+
+/* DELBA action parameters */
+#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 /* initiator mask */
+#define DOT11_DELBA_PARAM_INIT_SHIFT 11 /* initiator shift */
+#define DOT11_DELBA_PARAM_TID_MASK 0xf000 /* tid mask */
+#define DOT11_DELBA_PARAM_TID_SHIFT 12 /* tid shift */
+
+struct dot11_delba {
+ uint8 category; /* category of action frame (3) */
+ uint8 action; /* action: addba req */
+ uint16 delba_param_set; /* paarmeter set */
+ uint16 reason; /* reason for dellba */
+}PACKED;
+typedef struct dot11_delba dot11_delba_t;
+#define DOT11_DELBA_LEN 6 /* length of delba frame */
+
+/* MLME Enumerations */
+#define DOT11_BSSTYPE_INFRASTRUCTURE 0 /* d11 infrastructure */
+#define DOT11_BSSTYPE_INDEPENDENT 1 /* d11 independent */
+#define DOT11_BSSTYPE_ANY 2 /* d11 any BSS type */
+#define DOT11_SCANTYPE_ACTIVE 0 /* d11 scan active */
+#define DOT11_SCANTYPE_PASSIVE 1 /* d11 scan passive */
+
+/* 802.11 BRCM "Compromise" Pre N constants */
+#define PREN_PREAMBLE 24 /* green field preamble time */
+#define PREN_MM_EXT 8 /* extra mixed mode preamble time */
+#define PREN_PREAMBLE_EXT 4 /* extra preamble (multiply by unique_streams-1) */
+
+/* 802.11 N PHY constants */
+#define NPHY_RIFS_TIME 2 /* NPHY RIFS time */
+
+/* 802.11 A PHY constants */
+#define APHY_SLOT_TIME 9 /* APHY slot time */
+#define APHY_SIFS_TIME 16 /* APHY SIFS time */
+#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) /* APHY DIFS time */
+#define APHY_PREAMBLE_TIME 16 /* APHY preamble time */
+#define APHY_SIGNAL_TIME 4 /* APHY signal time */
+#define APHY_SYMBOL_TIME 4 /* APHY symbol time */
+#define APHY_SERVICE_NBITS 16 /* APHY service nbits */
+#define APHY_TAIL_NBITS 6 /* APHY tail nbits */
+#define APHY_CWMIN 15 /* APHY cwmin */
+
+/* 802.11 B PHY constants */
+#define BPHY_SLOT_TIME 20 /* BPHY slot time */
+#define BPHY_SIFS_TIME 10 /* BPHY SIFS time */
+#define BPHY_DIFS_TIME 50 /* BPHY DIFS time */
+#define BPHY_PLCP_TIME 192 /* BPHY PLCP time */
+#define BPHY_PLCP_SHORT_TIME 96 /* BPHY PLCP short time */
+#define BPHY_CWMIN 31 /* BPHY cwmin */
+
+/* 802.11 G constants */
+#define DOT11_OFDM_SIGNAL_EXTENSION 6 /* d11 OFDM signal extension */
+
+#define PHY_CWMAX 1023 /* PHY cwmax */
+
+#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */
+
+/* dot11Counters Table - 802.11 spec., Annex D */
+typedef struct d11cnt {
+ uint32 txfrag; /* dot11TransmittedFragmentCount */
+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */
+ uint32 txfail; /* dot11FailedCount */
+ uint32 txretry; /* dot11RetryCount */
+ uint32 txretrie; /* dot11MultipleRetryCount */
+ uint32 rxdup; /* dot11FrameduplicateCount */
+ uint32 txrts; /* dot11RTSSuccessCount */
+ uint32 txnocts; /* dot11RTSFailureCount */
+ uint32 txnoack; /* dot11ACKFailureCount */
+ uint32 rxfrag; /* dot11ReceivedFragmentCount */
+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */
+ uint32 rxcrc; /* dot11FCSErrorCount */
+ uint32 txfrmsnt; /* dot11TransmittedFrameCount */
+ uint32 rxundec; /* dot11WEPUndecryptableCount */
+} d11cnt_t;
+
+/* BRCM OUI */
+#define BRCM_OUI "\x00\x10\x18" /* Broadcom OUI */
+
+/* OUI for BRCM proprietary IE */
+#define BRCM_PROP_OUI "\x00\x90\x4C" /* Broadcom proprietary OUI */
+
+/* BRCM info element */
+struct brcm_ie {
+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */
+ uint8 len; /* IE length */
+ uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */
+ uint8 ver; /* type/ver of this IE */
+ uint8 assoc; /* # of assoc STAs */
+ uint8 flags; /* misc flags */
+ uint8 flags1; /* misc flags */
+ uint16 amsdu_mtu_pref; /* preferred A-MSDU MTU */
+} PACKED;
+typedef struct brcm_ie brcm_ie_t;
+#define BRCM_IE_LEN 11 /* BRCM IE length */
+#define BRCM_IE_VER 2 /* BRCM IE version */
+#define BRCM_IE_LEGACY_AES_VER 1 /* BRCM IE legacy AES version */
+
+/* brcm_ie flags */
+#define BRF_ABCAP 0x1 /* afterburner capable */
+#define BRF_ABRQRD 0x2 /* afterburner requested */
+#define BRF_LZWDS 0x4 /* lazy wds enabled */
+#define BRF_BLOCKACK 0x8 /* BlockACK capable */
+#define BRF_ABCOUNTER_MASK 0xf0 /* afterburner wds "state" counter */
+#define BRF_ABCOUNTER_SHIFT 4 /* offset of afterburner wds "state" counter */
+
+/* brcm_ie flags1 */
+#define BRF1_AMSDU 0x1 /* A-MSDU capable */
+#define BRF1_DPT 0x2 /* DPT capable */
+
+#define AB_WDS_TIMEOUT_MAX 15 /* afterburner wds Max count indicating not
+ * locally capable
+ */
+#define AB_WDS_TIMEOUT_MIN 1 /* afterburner wds, use zero count as indicating
+ * "downrev"
+ */
+
+/* EWC definitions */
+#define MCSSET_LEN 16 /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */
+#define MAX_MCS_NUM (128) /* max mcs number = 128 */
+
+struct ewc_cap_ie {
+ uint16 cap;
+ uint8 params;
+ uint8 supp_mcs[MCSSET_LEN];
+ uint16 ext_htcap;
+ uint32 txbf_cap;
+ uint8 as_cap;
+} PACKED;
+typedef struct ewc_cap_ie ewc_cap_ie_t;
+
+/* CAP IE: EWC 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */
+/* the capability IE is primarily used to convey this nodes abilities */
+struct ewc_prop_cap_ie {
+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */
+ uint8 len; /* IE length */
+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */
+ uint8 type; /* type inidicates what follows */
+ ewc_cap_ie_t cap_ie;
+} PACKED;
+typedef struct ewc_prop_cap_ie ewc_prop_cap_ie_t;
+#define EWC_PROP_IE_OVERHEAD 4 /* overhead bytes for prop oui ie */
+#define EWC_CAP_IE_LEN 26
+#define EWC_CAP_IE_TYPE 51
+
+#define EWC_CAP_LDPC_CODING 0x0001 /* Support for rx of LDPC coded pkts */
+#define EWC_CAP_40MHZ 0x0002 /* FALSE:20Mhz, TRUE:20/40MHZ supported */
+#define EWC_CAP_MIMO_PS_MASK 0x000C /* Mimo PS mask */
+#define EWC_CAP_MIMO_PS_SHIFT 0x0002 /* Mimo PS shift */
+#define EWC_CAP_MIMO_PS_OFF 0x0003 /* Mimo PS, no restriction */
+#define EWC_CAP_MIMO_PS_RTS 0x0001 /* Mimo PS, send RTS/CTS around MIMO frames */
+#define EWC_CAP_MIMO_PS_ON 0x0000 /* Mimo PS, MIMO disallowed */
+#define EWC_CAP_GF 0x0010 /* Greenfield preamble support */
+#define EWC_CAP_SHORT_GI_20 0x0020 /* 20MHZ short guard interval support */
+#define EWC_CAP_SHORT_GI_40 0x0040 /* 40Mhz short guard interval support */
+#define EWC_CAP_TX_STBC 0x0080 /* Tx STBC support */
+#define EWC_CAP_RX_STBC_MASK 0x0300 /* Rx STBC mask */
+#define EWC_CAP_RX_STBC_SHIFT 8 /* Rx STBC shift */
+#define EWC_CAP_DELAYED_BA 0x0400 /* delayed BA support */
+#define EWC_CAP_MAX_AMSDU 0x0800 /* Max AMSDU size in bytes , 0=3839, 1=7935 */
+#define EWC_CAP_DSSS_CCK 0x1000 /* DSSS/CCK supported by the BSS */
+#define EWC_CAP_PSMP 0x2000 /* Power Save Multi Poll support */
+#define EWC_CAP_40MHZ_INTOLERANT 0x4000 /* 40MHz Intolerant */
+#define EWC_CAP_LSIG_TXOP 0x8000 /* L-SIG TXOP protection support */
+
+#define EWC_CAP_RX_STBC_NO 0x0 /* no rx STBC support */
+#define EWC_CAP_RX_STBC_ONE_STREAM 0x1 /* rx STBC support of 1 spatial stream */
+#define EWC_CAP_RX_STBC_TWO_STREAM 0x2 /* rx STBC support of 1-2 spatial streams */
+#define EWC_CAP_RX_STBC_THREE_STREAM 0x3 /* rx STBC support of 1-3 spatial streams */
+
+#define EWC_MAX_AMSDU 7935 /* max amsdu size (bytes) per the EWC spec */
+#define EWC_MIN_AMSDU 3835 /* min amsdu size (bytes) per the EWC spec */
+
+#define EWC_PARAMS_RX_FACTOR_MASK 0x03 /* ampdu rcv factor mask */
+#define EWC_PARAMS_DENSITY_MASK 0x1C /* ampdu density mask */
+#define EWC_PARAMS_DENSITY_SHIFT 2 /* ampdu density shift */
+
+/* EWC/AMPDU specific define */
+#define AMPDU_MAX_MPDU_DENSITY 7 /* max mpdu density; in 1/8 usec units */
+#define AMPDU_MAX_RX_FACTOR 3 /* max rcv ampdu len (64kb) */
+#define AMPDU_RX_FACTOR_BASE 8*1024 /* ampdu factor base for rx len */
+#define AMPDU_DELIMITER_LEN 4 /* length of ampdu delimiter */
+
+struct ewc_add_ie {
+ uint8 ctl_ch; /* control channel number */
+ uint8 byte1; /* ext ch,rec. ch. width, RIFS support */
+ uint16 opmode; /* operation mode */
+ uint16 misc_bits; /* misc bits */
+ uint8 basic_mcs[MCSSET_LEN]; /* required MCS set */
+} PACKED;
+typedef struct ewc_add_ie ewc_add_ie_t;
+
+/* ADD IE: EWC 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */
+/* the additional IE is primarily used to convey the current BSS configuration */
+struct ewc_prop_add_ie {
+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */
+ uint8 len; /* IE length */
+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */
+ uint8 type; /* indicates what follows */
+ ewc_add_ie_t add_ie;
+} PACKED;
+typedef struct ewc_prop_add_ie ewc_prop_add_ie_t;
+
+#define EWC_ADD_IE_LEN 22
+#define EWC_ADD_IE_TYPE 52
+
+/* byte1 defn's */
+#define EWC_BW_ANY 0x04 /* set, STA can use 20 or 40MHz */
+#define EWC_RIFS_PERMITTED 0x08 /* RIFS allowed */
+
+/* opmode defn's */
+#define EWC_OPMODE_MASK 0x0003 /* protection mode mask */
+#define EWC_OPMODE_SHIFT 0 /* protection mode shift */
+#define EWC_OPMODE_PURE 0x0000 /* protection mode PURE */
+#define EWC_OPMODE_OPTIONAL 0x0001 /* protection mode optional */
+#define EWC_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */
+#define EWC_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */
+#define EWC_OPMODE_NONGF 0x0004 /* protection mode non-GF */
+#define DOT11N_TXBURST 0x0008 /* Tx burst limit */
+#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */
+
+/* misc_bites defn's */
+#define EWC_BASIC_STBC_MCS 0x007f /* basic STBC MCS */
+#define EWC_DUAL_STBC_PROT 0x0080 /* Dual STBC Protection */
+#define EWC_SECOND_BCN 0x0100 /* Secondary beacon support */
+#define EWC_LSIG_TXOP 0x0200 /* L-SIG TXOP Protection full support */
+#define EWC_PCO_ACTIVE 0x0400 /* PCO active */
+#define EWC_PCO_PHASE 0x0800 /* PCO phase */
+
+/* Tx Burst Limits */
+#define DOT11N_2G_TXBURST_LIMIT 6160 /* 2G band Tx burst limit per 802.11n Draft 1.10 (usec) */
+#define DOT11N_5G_TXBURST_LIMIT 3080 /* 5G band Tx burst limit per 802.11n Draft 1.10 (usec) */
+
+/* Macros for opmode */
+#define GET_EWC_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & EWC_OPMODE_MASK) \
+ >> EWC_OPMODE_SHIFT)
+#define EWC_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & EWC_OPMODE_MASK) \
+ == EWC_OPMODE_MIXED) /* mixed mode present */
+#define EWC_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & EWC_OPMODE_MASK) \
+ == EWC_OPMODE_HT20IN40) /* 20MHz HT present */
+#define EWC_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & EWC_OPMODE_MASK) \
+ == EWC_OPMODE_OPTIONAL) /* Optional protection present */
+#define EWC_USE_PROTECTION(add_ie) (EWC_HT20_PRESENT((add_ie)) || \
+ EWC_MIXEDMODE_PRESENT((add_ie))) /* use protection */
+#define EWC_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & EWC_OPMODE_NONGF) \
+ == EWC_OPMODE_NONGF) /* non-GF present */
+#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \
+ == DOT11N_TXBURST) /* Tx Burst present */
+#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \
+ == DOT11N_OBSS_NONHT) /* OBSS Non-HT present */
+
+/* Vendor IE structure */
+struct vndr_ie {
+ uchar id;
+ uchar len;
+ uchar oui [3];
+ uchar data [1]; /* Variable size data */
+} PACKED;
+typedef struct vndr_ie vndr_ie_t;
+
+#define VNDR_IE_HDR_LEN 2 /* id + len field */
+#define VNDR_IE_MIN_LEN 3 /* size of the oui field */
+#define VNDR_IE_MAX_LEN 256 /* verdor IE max length */
+
+/* WPA definitions */
+#define WPA_VERSION 1 /* WPA version */
+#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
+
+#define WPA2_VERSION 1 /* WPA2 version */
+#define WPA2_VERSION_LEN 2 /* WAP2 version length */
+#define WPA2_OUI "\x00\x0F\xAC" /* WPA2 OUI */
+
+#define WPA_OUI_LEN 3 /* WPA OUI length */
+
+/* RSN authenticated key managment suite */
+#define RSN_AKM_NONE 0 /* None (IBSS) */
+#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
+#define RSN_AKM_PSK 2 /* Pre-shared Key */
+
+/* Key related defines */
+#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */
+#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */
+#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */
+#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */
+
+#define WEP1_KEY_SIZE 5 /* max size of any WEP key */
+#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */
+#define WEP128_KEY_SIZE 13 /* max size of any WEP key */
+#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */
+#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */
+#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */
+#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */
+#define TKIP_KEY_SIZE 32 /* size of any TKIP key */
+#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */
+#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */
+#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX /* offset to Supplicant MIC RX key */
+#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX /* offset to Supplicant MIC TX key */
+#define AES_KEY_SIZE 16 /* size of AES key */
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _802_11_H_ */
diff --git a/package/broadcom-wl/src/driver/proto/802.11e.h b/package/broadcom-wl/src/driver/proto/802.11e.h
new file mode 100644
index 0000000000..e1aa5069e8
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/802.11e.h
@@ -0,0 +1,123 @@
+/*
+ * 802.11e protocol header file
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _802_11e_H_
+#define _802_11e_H_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+#ifdef BCMDBG
+extern const char *aci_names[];
+#endif /* BCMDBG */
+
+/* WME Traffic Specification (TSPEC) element */
+#define WME_TSPEC_HDR_LEN 2 /* WME TSPEC header length */
+#define WME_TSPEC_BODY_OFF 2 /* WME TSPEC body offset */
+
+#define WME_CATEGORY_CODE_OFFSET 0 /* WME Category code offset */
+#define WME_ACTION_CODE_OFFSET 1 /* WME Action code offset */
+#define WME_TOKEN_CODE_OFFSET 2 /* WME Token code offset */
+#define WME_STATUS_CODE_OFFSET 3 /* WME Status code offset */
+
+struct tsinfo {
+ uint8 octets[3];
+} PACKED;
+
+typedef struct tsinfo tsinfo_t;
+
+/* 802.11e TSPEC IE */
+typedef struct tspec {
+ uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */
+ uint8 type; /* WME_TYPE */
+ uint8 subtype; /* WME_SUBTYPE_TSPEC */
+ uint8 version; /* WME_VERSION */
+ tsinfo_t tsinfo; /* TS Info bit field */
+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */
+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */
+ uint32 min_srv_interval; /* Minimum Service Interval (us) */
+ uint32 max_srv_interval; /* Maximum Service Interval (us) */
+ uint32 inactivity_interval; /* Inactivity Interval (us) */
+ uint32 suspension_interval; /* Suspension Interval (us) */
+ uint32 srv_start_time; /* Service Start Time (us) */
+ uint32 min_data_rate; /* Minimum Data Rate (bps) */
+ uint32 mean_data_rate; /* Mean Data Rate (bps) */
+ uint32 peak_data_rate; /* Peak Data Rate (bps) */
+ uint32 max_burst_size; /* Maximum Burst Size (bytes) */
+ uint32 delay_bound; /* Delay Bound (us) */
+ uint32 min_phy_rate; /* Minimum PHY Rate (bps) */
+ uint16 surplus_bw; /* Surplus Bandwidth Allowance Factor */
+ uint16 medium_time; /* Medium Time (32 us/s periods) */
+} PACKED tspec_t;
+
+#define WME_TSPEC_LEN (sizeof(tspec_t)) /* not including 2-bytes of header */
+
+/* ts_info */
+/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */
+#define TS_INFO_TID_SHIFT 1 /* TS info. TID shift */
+#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT) /* TS info. TID mask */
+#define TS_INFO_CONTENTION_SHIFT 7 /* TS info. contention shift */
+#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) /* TS info. contention mask */
+#define TS_INFO_DIRECTION_SHIFT 5 /* TS info. direction shift */
+#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) /* TS info. direction mask */
+#define TS_INFO_PSB_SHIFT 2 /* TS info. PSB bit Shift */
+#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT) /* TS info. PSB mask */
+#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) /* TS info. uplink */
+#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) /* TS info. downlink */
+#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) /* TS info. bidirectional */
+#define TS_INFO_USER_PRIO_SHIFT 3 /* TS info. user priority shift */
+/* TS info. user priority mask */
+#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT)
+
+/* Macro to get/set bit(s) field in TSINFO */
+#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT)
+#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \
+ TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT)
+#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & WLC_CAC_PSB_MASK) >> WLC_CAC_PSB_SHIFT)
+#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \
+ TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT)
+
+#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \
+ ((id) << TS_INFO_TID_SHIFT))
+#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & (~TS_INFO_USER_PRIO_MASK)) | \
+ ((prio) << TS_INFO_USER_PRIO_SHIFT))
+
+/* 802.11e QBSS Load IE */
+#define QBSS_LOAD_IE_LEN 5 /* QBSS Load IE length */
+#define QBSS_LOAD_AAC_OFF 3 /* AAC offset in IE */
+
+#define CAC_ADDTS_RESP_TIMEOUT 300 /* default ADDTS response timeout in ms */
+
+/* 802.11e ADDTS status code */
+#define DOT11E_STATUS_ADMISSION_ACCEPTED 0 /* TSPEC Admission accepted status */
+#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */
+#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */
+
+/* 802.11e DELTS status code */
+#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */
+#define DOT11E_STATUS_END_TS 37 /* END TS */
+#define DOT11E_STATUS_UNKNOWN_TS 38 /* UNKNOWN TS */
+#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39 /* STA ADDTS request timeout */
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _802_11e_CAC_H_ */
diff --git a/package/broadcom-wl/src/driver/proto/802.1d.h b/package/broadcom-wl/src/driver/proto/802.1d.h
new file mode 100644
index 0000000000..421b963202
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/802.1d.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * Fundamental types and constants relating to 802.1D
+ *
+ * $Id$
+ */
+
+#ifndef _802_1_D_
+#define _802_1_D_
+
+/* 802.1D priority defines */
+#define PRIO_8021D_NONE 2 /* None = - */
+#define PRIO_8021D_BK 1 /* BK - Background */
+#define PRIO_8021D_BE 0 /* BE - Best-effort */
+#define PRIO_8021D_EE 3 /* EE - Excellent-effort */
+#define PRIO_8021D_CL 4 /* CL - Controlled Load */
+#define PRIO_8021D_VI 5 /* Vi - Video */
+#define PRIO_8021D_VO 6 /* Vo - Voice */
+#define PRIO_8021D_NC 7 /* NC - Network Control */
+#define MAXPRIO 7 /* 0-7 */
+#define NUMPRIO (MAXPRIO + 1)
+
+#define ALLPRIO -1 /* All prioirty */
+
+/* Converts prio to precedence since the numerical value of
+ * PRIO_8021D_BE and PRIO_8021D_NONE are swapped.
+ */
+#define PRIO2PREC(prio) \
+ (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio))
+
+#endif /* _802_1_D__ */
diff --git a/package/broadcom-wl/src/driver/proto/802.3.h b/package/broadcom-wl/src/driver/proto/802.3.h
new file mode 100644
index 0000000000..54a17c24ed
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/802.3.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
+ * the contents of this file may not be disclosed to third parties, copied
+ * or duplicated in any form, in whole or in part, without the prior
+ * written permission of Broadcom Corporation.
+ *
+ * Fundamental constants relating to 802.3
+ *
+ * $Id$
+ */
+
+#ifndef _802_3_h_
+#define _802_3_h_
+
+#define SNAP_HDR_LEN 6 /* 802.3 LLC/SNAP header length */
+
+#endif /* #ifndef _802_3_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/bcmarp.h b/package/broadcom-wl/src/driver/proto/bcmarp.h
new file mode 100644
index 0000000000..f5058b6aa7
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/bcmarp.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
+ * the contents of this file may not be disclosed to third parties, copied
+ * or duplicated in any form, in whole or in part, without the prior
+ * written permission of Broadcom Corporation.
+ *
+ * Fundamental constants relating to ARP Protocol
+ *
+ * $Id$
+ */
+
+#ifndef _bcmarp_h_
+#define _bcmarp_h_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+#define ARP_OPC_OFFSET 6 /* option code offset */
+#define ARP_SRC_ETH_OFFSET 8 /* src h/w address offset */
+#define ARP_SRC_IP_OFFSET 14 /* src IP address offset */
+#define ARP_TGT_ETH_OFFSET 18 /* target h/w address offset */
+#define ARP_TGT_IP_OFFSET 24 /* target IP address offset */
+
+#define ARP_OPC_REQUEST 1 /* ARP request */
+#define ARP_OPC_REPLY 2 /* ARP reply */
+
+#define ARP_DATA_LEN 28 /* ARP data length */
+
+struct bcmarp {
+ uint16 htype; /* Header type (1 = ethernet) */
+ uint16 ptype; /* Protocol type (0x800 = IP) */
+ uint8 hlen; /* Hardware address length (Eth = 6) */
+ uint8 plen; /* Protocol address length (IP = 4) */
+ uint16 oper; /* ARP_OPC_... */
+ uint8 src_eth[ETHER_ADDR_LEN]; /* Source hardware address */
+ uint8 src_ip[IPV4_ADDR_LEN]; /* Source protocol address (not aligned) */
+ uint8 dst_eth[ETHER_ADDR_LEN]; /* Destination hardware address */
+ uint8 dst_ip[IPV4_ADDR_LEN]; /* Destination protocol address */
+} PACKED;
+
+/* Ethernet header + Arp message */
+struct bcmetharp {
+ struct ether_header eh;
+ struct bcmarp arp;
+} PACKED;
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* !defined(_bcmarp_h_) */
diff --git a/package/broadcom-wl/src/driver/proto/bcmdhcp.h b/package/broadcom-wl/src/driver/proto/bcmdhcp.h
new file mode 100644
index 0000000000..a2cdc58fbd
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/bcmdhcp.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
+ * the contents of this file may not be disclosed to third parties, copied
+ * or duplicated in any form, in whole or in part, without the prior
+ * written permission of Broadcom Corporation.
+ *
+ * Fundamental constants relating to DHCP Protocol
+ *
+ * $Id$
+ */
+
+#ifndef _bcmdhcp_h_
+#define _bcmdhcp_h_
+
+/* DHCP params */
+#define DHCP_TYPE_OFFSET 0 /* DHCP type (request|reply) offset */
+#define DHCP_FLAGS_OFFSET 10 /* DHCP flags offset */
+#define DHCP_CIADDR_OFFSET 12 /* DHCP client IP address offset */
+#define DHCP_YIADDR_OFFSET 16 /* DHCP your IP address offset */
+#define DHCP_GIADDR_OFFSET 24 /* DHCP relay agent IP address offset */
+#define DHCP_CHADDR_OFFSET 28 /* DHCP client h/w address offset */
+
+#define DHCP_TYPE_REQUEST 1 /* DHCP request (discover|request) */
+#define DHCP_TYPE_REPLY 2 /* DHCP reply (offset|ack) */
+
+#define DHCP_PORT_SERVER 67 /* DHCP server UDP port */
+#define DHCP_PORT_CLIENT 68 /* DHCP client UDP port */
+
+#define DHCP_FLAG_BCAST 0x8000 /* DHCP broadcast flag */
+
+#define DHCP_FLAGS_LEN 2 /* DHCP flags field length */
+
+#endif /* #ifndef _bcmdhcp_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/bcmeth.h b/package/broadcom-wl/src/driver/proto/bcmeth.h
new file mode 100644
index 0000000000..23aa41159d
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/bcmeth.h
@@ -0,0 +1,101 @@
+/*
+ * Broadcom Ethernettype protocol definitions
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+/*
+ * Broadcom Ethernet protocol defines
+ */
+
+#ifndef _BCMETH_H_
+#define _BCMETH_H_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+/* ETHER_TYPE_BRCM is defined in ethernet.h */
+
+/*
+ * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field
+ * in one of two formats: (only subtypes 32768-65535 are in use now)
+ *
+ * subtypes 0-32767:
+ * 8 bit subtype (0-127)
+ * 8 bit length in bytes (0-255)
+ *
+ * subtypes 32768-65535:
+ * 16 bit big-endian subtype
+ * 16 bit big-endian length in bytes (0-65535)
+ *
+ * length is the number of additional bytes beyond the 4 or 6 byte header
+ *
+ * Reserved values:
+ * 0 reserved
+ * 5-15 reserved for iLine protocol assignments
+ * 17-126 reserved, assignable
+ * 127 reserved
+ * 32768 reserved
+ * 32769-65534 reserved, assignable
+ * 65535 reserved
+ */
+
+/*
+ * While adding the subtypes and their specific processing code make sure
+ * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition
+ */
+
+#define BCMILCP_SUBTYPE_RATE 1
+#define BCMILCP_SUBTYPE_LINK 2
+#define BCMILCP_SUBTYPE_CSA 3
+#define BCMILCP_SUBTYPE_LARQ 4
+#define BCMILCP_SUBTYPE_VENDOR 5
+#define BCMILCP_SUBTYPE_FLH 17
+
+#define BCMILCP_SUBTYPE_VENDOR_LONG 32769
+#define BCMILCP_SUBTYPE_CERT 32770
+#define BCMILCP_SUBTYPE_SES 32771
+
+
+#define BCMILCP_BCM_SUBTYPE_RESERVED 0
+#define BCMILCP_BCM_SUBTYPE_EVENT 1
+#define BCMILCP_BCM_SUBTYPE_SES 2
+/*
+ * The EAPOL type is not used anymore. Instead EAPOL messages are now embedded
+ * within BCMILCP_BCM_SUBTYPE_EVENT type messages
+ */
+/* #define BCMILCP_BCM_SUBTYPE_EAPOL 3 */
+
+#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8
+#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0
+
+/* These fields are stored in network order */
+typedef struct bcmeth_hdr
+{
+ uint16 subtype; /* Vendor specific..32769 */
+ uint16 length;
+ uint8 version; /* Version is 0 */
+ uint8 oui[3]; /* Broadcom OUI */
+ /* user specific Data */
+ uint16 usr_subtype;
+} PACKED bcmeth_hdr_t;
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _BCMETH_H_ */
diff --git a/package/broadcom-wl/src/driver/proto/bcmevent.h b/package/broadcom-wl/src/driver/proto/bcmevent.h
new file mode 100644
index 0000000000..785ef22bb2
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/bcmevent.h
@@ -0,0 +1,166 @@
+/*
+ * Broadcom Event protocol definitions
+ *
+ * Copyright 2007, 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.
+ *
+ *
+ * Dependencies: proto/bcmeth.h
+ *
+ * $Id$
+ *
+ */
+
+/*
+ * Broadcom Ethernet Events protocol defines
+ *
+ */
+
+#ifndef _BCMEVENT_H_
+#define _BCMEVENT_H_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif /* defined(__GNUC__) */
+
+#define BCM_EVENT_MSG_VERSION 1 /* wl_event_msg_t struct version */
+#define BCM_MSG_IFNAME_MAX 16 /* max length of interface name */
+
+/* flags */
+#define WLC_EVENT_MSG_LINK 0x01 /* link is up */
+#define WLC_EVENT_MSG_FLUSHTXQ 0x02 /* flush tx queue on MIC error */
+#define WLC_EVENT_MSG_GROUP 0x04 /* group MIC error */
+
+/* these fields are stored in network order */
+typedef struct
+{
+ uint16 version;
+ uint16 flags; /* see flags below */
+ uint32 event_type; /* Message (see below) */
+ uint32 status; /* Status code (see below) */
+ uint32 reason; /* Reason code (if applicable) */
+ uint32 auth_type; /* WLC_E_AUTH */
+ uint32 datalen; /* data buf */
+ struct ether_addr addr; /* Station address (if applicable) */
+ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */
+} PACKED wl_event_msg_t;
+
+/* used by driver msgs */
+typedef struct bcm_event {
+ struct ether_header eth;
+ bcmeth_hdr_t bcm_hdr;
+ wl_event_msg_t event;
+ /* data portion follows */
+} PACKED bcm_event_t;
+
+#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header))
+
+/* Event messages */
+#define WLC_E_SET_SSID 0 /* indicates status of set SSID */
+#define WLC_E_JOIN 1 /* differentiates join IBSS from found (WLC_E_START) IBSS */
+#define WLC_E_START 2 /* STA founded an IBSS or AP started a BSS */
+#define WLC_E_AUTH 3 /* 802.11 AUTH request */
+#define WLC_E_AUTH_IND 4 /* 802.11 AUTH indication */
+#define WLC_E_DEAUTH 5 /* 802.11 DEAUTH request */
+#define WLC_E_DEAUTH_IND 6 /* 802.11 DEAUTH indication */
+#define WLC_E_ASSOC 7 /* 802.11 ASSOC request */
+#define WLC_E_ASSOC_IND 8 /* 802.11 ASSOC indication */
+#define WLC_E_REASSOC 9 /* 802.11 REASSOC request */
+#define WLC_E_REASSOC_IND 10 /* 802.11 REASSOC indication */
+#define WLC_E_DISASSOC 11 /* 802.11 DISASSOC request */
+#define WLC_E_DISASSOC_IND 12 /* 802.11 DISASSOC indication */
+#define WLC_E_QUIET_START 13 /* 802.11h Quiet period started */
+#define WLC_E_QUIET_END 14 /* 802.11h Quiet period ended */
+#define WLC_E_BEACON_RX 15 /* BEACONS received/lost indication */
+#define WLC_E_LINK 16 /* generic link indication */
+#define WLC_E_MIC_ERROR 17 /* TKIP MIC error occurred */
+#define WLC_E_NDIS_LINK 18 /* NDIS style link indication */
+#define WLC_E_ROAM 19 /* roam attempt occurred: indicate status & reason */
+#define WLC_E_TXFAIL 20 /* change in dot11FailedCount (txfail) */
+#define WLC_E_PMKID_CACHE 21 /* WPA2 pmkid cache indication */
+#define WLC_E_RETROGRADE_TSF 22 /* current AP's TSF value went backward */
+#define WLC_E_PRUNE 23 /* AP was pruned from join list for reason */
+#define WLC_E_AUTOAUTH 24 /* report AutoAuth table entry match for join attempt */
+#define WLC_E_EAPOL_MSG 25 /* Event encapsulating an EAPOL message */
+#define WLC_E_SCAN_COMPLETE 26 /* Scan results are ready or scan was aborted */
+#define WLC_E_ADDTS_IND 27 /* indicate to host addts fail/success */
+#define WLC_E_DELTS_IND 28 /* indicate to host delts fail/success */
+#define WLC_E_BCNSENT_IND 29 /* indicate to host of beacon transmit */
+#define WLC_E_BCNRX_MSG 30 /* Send the received beacon up to the host */
+#define WLC_E_BCNLOST_MSG 31 /* indicate to host loss of beacon */
+#define WLC_E_ROAM_PREP 32 /* before attempting to roam */
+#define WLC_E_PFN_NET_FOUND 33 /* PFN network found event */
+#define WLC_E_PFN_NET_LOST 34 /* PFN network lost event */
+
+#ifdef EXT_STA
+#define WLC_E_RESET_COMPLETE 35
+#define WLC_E_JOIN_START 36
+#define WLC_E_ROAM_START 37
+#define WLC_E_ASSOC_START 38
+#define WLC_E_IBSS_ASSOC 39
+#define WLC_E_RADIO 40
+#define WLC_E_LAST 41 /* highest val + 1 for range checking */
+#else /* EXT_STA */
+#define WLC_E_LAST 35 /* highest val + 1 for range checking */
+#endif /* EXT_STA */
+
+/* Event status codes */
+#define WLC_E_STATUS_SUCCESS 0 /* operation was successful */
+#define WLC_E_STATUS_FAIL 1 /* operation failed */
+#define WLC_E_STATUS_TIMEOUT 2 /* operation timed out */
+#define WLC_E_STATUS_NO_NETWORKS 3 /* failed due to no matching network found */
+#define WLC_E_STATUS_ABORT 4 /* operation was aborted */
+#define WLC_E_STATUS_NO_ACK 5 /* protocol failure: packet not ack'd */
+#define WLC_E_STATUS_UNSOLICITED 6 /* AUTH or ASSOC packet was unsolicited */
+#define WLC_E_STATUS_ATTEMPT 7 /* attempt to assoc to an auto auth configuration */
+#define WLC_E_STATUS_PARTIAL 8 /* scan results are incomplete */
+#define WLC_E_STATUS_NEWSCAN 9 /* scan aborted by another scan */
+#define WLC_E_STATUS_NEWASSOC 10 /* scan aborted due to assoc in progress */
+#define WLC_E_STATUS_11HQUIET 11 /* 802.11h quiet period started */
+#define WLC_E_STATUS_SUPPRESS 12 /* user disabled scanning (WLC_SET_SCANSUPPRESS) */
+#define WLC_E_STATUS_NOCHANS 13 /* no allowable channels to scan */
+#define WLC_E_STATUS_CCXFASTRM 14 /* scan aborted due to CCX fast roam */
+
+/* roam reason codes */
+#define WLC_E_REASON_INITIAL_ASSOC 0 /* initial assoc */
+#define WLC_E_REASON_LOW_RSSI 1 /* roamed due to low RSSI */
+#define WLC_E_REASON_DEAUTH 2 /* roamed due to DEAUTH indication */
+#define WLC_E_REASON_DISASSOC 3 /* roamed due to DISASSOC indication */
+#define WLC_E_REASON_BCNS_LOST 4 /* roamed due to lost beacons */
+#define WLC_E_REASON_FAST_ROAM_FAILED 5 /* roamed due to fast roam failure */
+#define WLC_E_REASON_DIRECTED_ROAM 6 /* roamed due to request by AP */
+#define WLC_E_REASON_TSPEC_REJECTED 7 /* roamed due to TSPEC rejection */
+#define WLC_E_REASON_BETTER_AP 8 /* roamed due to finding better AP */
+
+/* prune reason codes */
+#define WLC_E_PRUNE_ENCR_MISMATCH 1 /* encryption mismatch */
+#define WLC_E_PRUNE_BCAST_BSSID 2 /* AP uses a broadcast BSSID */
+#define WLC_E_PRUNE_MAC_DENY 3 /* STA's MAC addr is in AP's MAC deny list */
+#define WLC_E_PRUNE_MAC_NA 4 /* STA's MAC addr is not in AP's MAC allow list */
+#define WLC_E_PRUNE_REG_PASSV 5 /* AP not allowed due to regulatory restriction */
+#define WLC_E_PRUNE_SPCT_MGMT 6 /* AP does not support STA locale spectrum mgmt */
+#define WLC_E_PRUNE_RADAR 7 /* AP is on a radar channel of STA locale */
+#define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */
+#define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */
+#define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */
+#define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */
+#define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */
+#define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */
+#define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */
+#define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif /* PACKED */
+
+#endif /* _BCMEVENT_H_ */
diff --git a/package/broadcom-wl/src/driver/proto/bcmip.h b/package/broadcom-wl/src/driver/proto/bcmip.h
new file mode 100644
index 0000000000..4169060da3
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/bcmip.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * Fundamental constants relating to IP Protocol
+ *
+ * $Id$
+ */
+
+#ifndef _bcmip_h_
+#define _bcmip_h_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+
+/* IPV4 and IPV6 common */
+#define IP_VER_OFFSET 0x0 /* offset to version field */
+#define IP_VER_MASK 0xf0 /* version mask */
+#define IP_VER_SHIFT 4 /* version shift */
+#define IP_VER_4 4 /* version number for IPV4 */
+#define IP_VER_6 6 /* version number for IPV6 */
+
+#define IP_VER(ip_body) \
+ ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT)
+
+#define IP_PROT_ICMP 0x1 /* ICMP protocol */
+#define IP_PROT_TCP 0x6 /* TCP protocol */
+#define IP_PROT_UDP 0x11 /* UDP protocol type */
+
+/* IPV4 field offsets */
+#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */
+#define IPV4_TOS_OFFSET 1 /* type of service offset */
+#define IPV4_PKTLEN_OFFSET 2 /* packet length offset */
+#define IPV4_PKTFLAG_OFFSET 6 /* more-frag,dont-frag flag offset */
+#define IPV4_PROT_OFFSET 9 /* protocol type offset */
+#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */
+#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */
+#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */
+#define IPV4_OPTIONS_OFFSET 20 /* IP options offset */
+
+/* IPV4 field decodes */
+#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */
+#define IPV4_VER_SHIFT 4 /* IPV4 version shift */
+
+#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */
+#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK))
+
+#define IPV4_ADDR_LEN 4 /* IPV4 address length */
+
+#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \
+ ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0)
+
+#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \
+ ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff)
+
+#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */
+#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */
+
+#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET])
+
+#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */
+#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */
+
+#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */
+#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */
+#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */
+
+#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET])
+
+#define IPV4_FRAG_RESV 0x8000 /* Reserved */
+#define IPV4_FRAG_DONT 0x4000 /* Don't fragment */
+#define IPV4_FRAG_MORE 0x2000 /* More fragments */
+#define IPV4_FRAG_OFFSET_MASK 0x1fff /* Fragment offset */
+
+#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */
+
+/* IPv4, no options only. */
+#define IPV4_NO_OPTIONS_HDR_LEN 20
+#define IPV4_NO_OPTIONS_PAYLOAD(ip_hdr) (&(((uint8 *)(ip_hdr))[IPV4_NO_OPTIONS_HDR_LEN]))
+
+#define IPV4_PAYLOAD_LEN(ip_body) \
+ (((int)(((uint8 *)(ip_body))[IPV4_PKTLEN_OFFSET + 0]) << 8) | \
+ ((uint8 *)(ip_body))[IPV4_PKTLEN_OFFSET + 1])
+
+/* IPV4 packet formats */
+struct ipv4_addr {
+ uint8 addr[IPV4_ADDR_LEN];
+} PACKED;
+
+struct ipv4_hdr {
+ uint8 version_ihl; /* Version and Internet Header Length */
+ uint8 tos; /* Type Of Service */
+ uint16 tot_len; /* Number of bytes in packet (max 65535) */
+ uint16 id;
+ uint16 frag; /* 3 flag bits and fragment offset */
+ uint8 ttl; /* Time To Live */
+ uint8 prot; /* Protocol */
+ uint16 hdr_chksum; /* IP header checksum */
+ uint8 src_ip[IPV4_ADDR_LEN]; /* Source IP Address */
+ uint8 dst_ip[IPV4_ADDR_LEN]; /* Destination IP Address */
+} PACKED;
+
+/* IPV6 field offsets */
+#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */
+#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */
+#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */
+#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */
+#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */
+
+/* IPV6 field decodes */
+#define IPV6_TRAFFIC_CLASS(ipv6_body) \
+ (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \
+ ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4))
+
+#define IPV6_FLOW_LABEL(ipv6_body) \
+ (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \
+ (((uint8 *)(ipv6_body))[2] << 8) | \
+ (((uint8 *)(ipv6_body))[3]))
+
+#define IPV6_PAYLOAD_LEN(ipv6_body) \
+ ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \
+ ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1])
+
+#define IPV6_NEXT_HDR(ipv6_body) \
+ (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET])
+
+#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body)
+
+#define IPV6_ADDR_LEN 16 /* IPV6 address length */
+
+/* IPV4 TOS or IPV6 Traffic Classifier or 0 */
+#define IP_TOS(ip_body) \
+ (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \
+ IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0)
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _bcmip_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/bcmtcp.h b/package/broadcom-wl/src/driver/proto/bcmtcp.h
new file mode 100644
index 0000000000..832fd434c0
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/bcmtcp.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * Fundamental constants relating to TCP Protocol
+ *
+ * $Id$
+ */
+
+#ifndef _bcmtcp_h_
+#define _bcmtcp_h_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+#define TCP_SRC_PORT_OFFSET 0 /* TCP source port offset */
+#define TCP_DEST_PORT_OFFSET 2 /* TCP dest port offset */
+#define TCP_CHKSUM_OFFSET 16 /* TCP body checksum offset */
+
+/* These fields are stored in network order */
+struct bcmtcp_hdr
+{
+ uint16 src_port; /* Source Port Address */
+ uint16 dst_port; /* Destination Port Address */
+ uint32 seq_num; /* TCP Sequence Number */
+ uint32 ack_num; /* TCP Sequence Number */
+ uint16 hdrlen_rsvd_flags; /* Header length, reserved bits and flags */
+ uint16 tcpwin; /* TCP window */
+ uint16 chksum; /* Segment checksum with pseudoheader */
+ uint16 urg_ptr; /* Points to seq-num of byte following urg data */
+} PACKED;
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+/* Byte offset of flags in TCP header */
+#define TCP_FLAGS_OFFSET 13
+
+#define TCP_FLAGS_FIN 0x01
+#define TCP_FLAGS_SYN 0x02
+#define TCP_FLAGS_RST 0x03
+#define TCP_FLAGS_PSH 0x04
+#define TCP_FLAGS_ACK 0x10
+#define TCP_FLAGS_URG 0x20
+#define TCP_FLAGS_ECN 0x40
+#define TCP_FLAGS_CWR 0x80
+
+#define TCP_FLAGS(tcp_hdr) (((uint8 *)(tcp_hdr))[TCP_FLAGS_OFFSET])
+#define TCP_IS_ACK(tcp_hdr) (TCP_FLAGS(tcp_hdr) & TCP_FLAGS_ACK)
+
+#define TCP_SRC_PORT(tcp_hdr) (ntoh16(((struct bcmtcp_hdr*)(tcp_hdr))->src_port))
+#define TCP_DST_PORT(tcp_hdr) (ntoh16(((struct bcmtcp_hdr*)(tcp_hdr))->dst_port))
+#define TCP_SEQ_NUM(tcp_hdr) (ntoh32(((struct bcmtcp_hdr*)(tcp_hdr))->seq_num))
+#define TCP_ACK_NUM(tcp_hdr) (ntoh32(((struct bcmtcp_hdr*)(tcp_hdr))->ack_num))
+
+#endif /* #ifndef _bcmtcp_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/bcmudp.h b/package/broadcom-wl/src/driver/proto/bcmudp.h
new file mode 100644
index 0000000000..5464284cf7
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/bcmudp.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
+ * the contents of this file may not be disclosed to third parties, copied
+ * or duplicated in any form, in whole or in part, without the prior
+ * written permission of Broadcom Corporation.
+ *
+ * Fundamental constants relating to UDP Protocol
+ *
+ * $Id$
+ */
+
+#ifndef _bcmudp_h_
+#define _bcmudp_h_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+/* UDP header */
+#define UDP_DEST_PORT_OFFSET 2 /* UDP dest port offset */
+#define UDP_LEN_OFFSET 4 /* UDP length offset */
+#define UDP_CHKSUM_OFFSET 6 /* UDP body checksum offset */
+
+#define UDP_HDR_LEN 8 /* UDP header length */
+#define UDP_PORT_LEN 2 /* UDP port length */
+
+/* These fields are stored in network order */
+struct bcmudp_hdr
+{
+ uint16 src_port; /* Source Port Address */
+ uint16 dst_port; /* Destination Port Address */
+ uint16 len; /* Number of bytes in datagram including header */
+ uint16 chksum; /* entire datagram checksum with pseudoheader */
+} PACKED;
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* #ifndef _bcmudp_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/eap.h b/package/broadcom-wl/src/driver/proto/eap.h
new file mode 100644
index 0000000000..5548e2fb54
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/eap.h
@@ -0,0 +1,45 @@
+/*
+ * Extensible Authentication Protocol (EAP) definitions
+ *
+ * See
+ * RFC 2284: PPP Extensible Authentication Protocol (EAP)
+ *
+ * Copyright (C) 2002 Broadcom Corporation
+ *
+ * $Id$
+ */
+
+#ifndef _eap_h_
+#define _eap_h_
+
+/* EAP packet format */
+typedef struct {
+ unsigned char code; /* EAP code */
+ unsigned char id; /* Current request ID */
+ unsigned short length; /* Length including header */
+ unsigned char type; /* EAP type (optional) */
+ unsigned char data[1]; /* Type data (optional) */
+} eap_header_t;
+
+#define EAP_HEADER_LEN 4
+
+/* EAP codes */
+#define EAP_REQUEST 1
+#define EAP_RESPONSE 2
+#define EAP_SUCCESS 3
+#define EAP_FAILURE 4
+
+/* EAP types */
+#define EAP_IDENTITY 1
+#define EAP_NOTIFICATION 2
+#define EAP_NAK 3
+#define EAP_MD5 4
+#define EAP_OTP 5
+#define EAP_GTC 6
+#define EAP_TLS 13
+#define EAP_EXPANDED 254
+#define BCM_EAP_SES 10
+#define BCM_EAP_EXP_LEN 12 /* EAP_LEN 5 + 3 bytes for SMI ID + 4 bytes for ven type */
+#define BCM_SMI_ID 0x113d
+
+#endif /* _eap_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/eapol.h b/package/broadcom-wl/src/driver/proto/eapol.h
new file mode 100644
index 0000000000..9a1a58da83
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/eapol.h
@@ -0,0 +1,179 @@
+/*
+ * 802.1x EAPOL definitions
+ *
+ * See
+ * IEEE Std 802.1X-2001
+ * IEEE 802.1X RADIUS Usage Guidelines
+ *
+ * Copyright (C) 2002 Broadcom Corporation
+ *
+ * $Id$
+ */
+
+#ifndef _eapol_h_
+#define _eapol_h_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+#include <bcmcrypto/aeskeywrap.h>
+
+/* EAPOL for 802.3/Ethernet */
+typedef struct {
+ struct ether_header eth; /* 802.3/Ethernet header */
+ unsigned char version; /* EAPOL protocol version */
+ unsigned char type; /* EAPOL type */
+ unsigned short length; /* Length of body */
+ unsigned char body[1]; /* Body (optional) */
+} eapol_header_t;
+
+#define EAPOL_HEADER_LEN 18
+
+/* EAPOL version */
+#define WPA2_EAPOL_VERSION 2
+#define WPA_EAPOL_VERSION 1
+#define LEAP_EAPOL_VERSION 1
+#define SES_EAPOL_VERSION 1
+
+/* EAPOL types */
+#define EAP_PACKET 0
+#define EAPOL_START 1
+#define EAPOL_LOGOFF 2
+#define EAPOL_KEY 3
+#define EAPOL_ASF 4
+
+/* EAPOL-Key types */
+#define EAPOL_RC4_KEY 1
+#ifdef BCMWPA2
+#define EAPOL_WPA2_KEY 2 /* 802.11i/WPA2 */
+#endif
+#define EAPOL_WPA_KEY 254 /* WPA */
+
+/* RC4 EAPOL-Key header field sizes */
+#define EAPOL_KEY_REPLAY_LEN 8
+#define EAPOL_KEY_IV_LEN 16
+#define EAPOL_KEY_SIG_LEN 16
+
+/* RC4 EAPOL-Key */
+typedef struct {
+ unsigned char type; /* Key Descriptor Type */
+ unsigned short length; /* Key Length (unaligned) */
+ unsigned char replay[EAPOL_KEY_REPLAY_LEN]; /* Replay Counter */
+ unsigned char iv[EAPOL_KEY_IV_LEN]; /* Key IV */
+ unsigned char index; /* Key Flags & Index */
+ unsigned char signature[EAPOL_KEY_SIG_LEN]; /* Key Signature */
+ unsigned char key[1]; /* Key (optional) */
+} PACKED eapol_key_header_t;
+
+#define EAPOL_KEY_HEADER_LEN 44
+
+/* RC4 EAPOL-Key flags */
+#define EAPOL_KEY_FLAGS_MASK 0x80
+#define EAPOL_KEY_BROADCAST 0
+#define EAPOL_KEY_UNICAST 0x80
+
+/* RC4 EAPOL-Key index */
+#define EAPOL_KEY_INDEX_MASK 0x7f
+
+/* WPA/802.11i/WPA2 EAPOL-Key header field sizes */
+#define EAPOL_WPA_KEY_REPLAY_LEN 8
+#define EAPOL_WPA_KEY_NONCE_LEN 32
+#define EAPOL_WPA_KEY_IV_LEN 16
+#define EAPOL_WPA_KEY_RSC_LEN 8
+#define EAPOL_WPA_KEY_ID_LEN 8
+#define EAPOL_WPA_KEY_MIC_LEN 16
+#define EAPOL_WPA_KEY_DATA_LEN (EAPOL_WPA_MAX_KEY_SIZE + AKW_BLOCK_LEN)
+#define EAPOL_WPA_MAX_KEY_SIZE 32
+
+/* WPA EAPOL-Key */
+typedef struct {
+ unsigned char type; /* Key Descriptor Type */
+ unsigned short key_info; /* Key Information (unaligned) */
+ unsigned short key_len; /* Key Length (unaligned) */
+ unsigned char replay[EAPOL_WPA_KEY_REPLAY_LEN]; /* Replay Counter */
+ unsigned char nonce[EAPOL_WPA_KEY_NONCE_LEN]; /* Nonce */
+ unsigned char iv[EAPOL_WPA_KEY_IV_LEN]; /* Key IV */
+ unsigned char rsc[EAPOL_WPA_KEY_RSC_LEN]; /* Key RSC */
+ unsigned char id[EAPOL_WPA_KEY_ID_LEN]; /* WPA:Key ID, 802.11i/WPA2: Reserved */
+ unsigned char mic[EAPOL_WPA_KEY_MIC_LEN]; /* Key MIC */
+ unsigned short data_len; /* Key Data Length */
+ unsigned char data[EAPOL_WPA_KEY_DATA_LEN]; /* Key data */
+} PACKED eapol_wpa_key_header_t;
+
+#define EAPOL_WPA_KEY_LEN 95
+
+/* WPA/802.11i/WPA2 KEY KEY_INFO bits */
+#define WPA_KEY_DESC_V1 0x01
+#define WPA_KEY_DESC_V2 0x02
+#define WPA_KEY_PAIRWISE 0x08
+#define WPA_KEY_INSTALL 0x40
+#define WPA_KEY_ACK 0x80
+#define WPA_KEY_MIC 0x100
+#define WPA_KEY_SECURE 0x200
+#define WPA_KEY_ERROR 0x400
+#define WPA_KEY_REQ 0x800
+
+/* WPA-only KEY KEY_INFO bits */
+#define WPA_KEY_INDEX_0 0x00
+#define WPA_KEY_INDEX_1 0x10
+#define WPA_KEY_INDEX_2 0x20
+#define WPA_KEY_INDEX_3 0x30
+#define WPA_KEY_INDEX_MASK 0x30
+#define WPA_KEY_INDEX_SHIFT 0x04
+
+#ifdef BCMWPA2
+/* 802.11i/WPA2-only KEY KEY_INFO bits */
+#define WPA_KEY_ENCRYPTED_DATA 0x1000
+
+/* Key Data encapsulation */
+typedef struct {
+ uint8 type;
+ uint8 length;
+ uint8 oui[3];
+ uint8 subtype;
+ uint8 data[1];
+} PACKED eapol_wpa2_encap_data_t;
+
+#define EAPOL_WPA2_ENCAP_DATA_HDR_LEN 6
+
+#define WPA2_KEY_DATA_SUBTYPE_GTK 1
+#define WPA2_KEY_DATA_SUBTYPE_STAKEY 2
+#define WPA2_KEY_DATA_SUBTYPE_MAC 3
+#define WPA2_KEY_DATA_SUBTYPE_PMKID 4
+
+/* GTK encapsulation */
+typedef struct {
+ uint8 flags;
+ uint8 reserved;
+ uint8 gtk[EAPOL_WPA_MAX_KEY_SIZE];
+} PACKED eapol_wpa2_key_gtk_encap_t;
+
+#define EAPOL_WPA2_KEY_GTK_ENCAP_HDR_LEN 2
+
+#define WPA2_GTK_INDEX_MASK 0x03
+#define WPA2_GTK_INDEX_SHIFT 0x00
+
+#define WPA2_GTK_TRANSMIT 0x04
+
+/* STAKey encapsulation */
+typedef struct {
+ uint8 reserved[2];
+ uint8 mac[ETHER_ADDR_LEN];
+ uint8 stakey[EAPOL_WPA_MAX_KEY_SIZE];
+} PACKED eapol_wpa2_key_stakey_encap_t;
+
+#define WPA2_KEY_DATA_PAD 0xdd
+
+#endif /* BCMWPA2 */
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _eapol_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/ethernet.h b/package/broadcom-wl/src/driver/proto/ethernet.h
new file mode 100644
index 0000000000..b674e0ce36
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/ethernet.h
@@ -0,0 +1,175 @@
+/*
+ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet.
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */
+#define _NET_ETHERNET_H_
+
+#ifndef _TYPEDEFS_H_
+#include "typedefs.h"
+#endif
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+/*
+ * The number of bytes in an ethernet (MAC) address.
+ */
+#define ETHER_ADDR_LEN 6
+
+/*
+ * The number of bytes in the type field.
+ */
+#define ETHER_TYPE_LEN 2
+
+/*
+ * The number of bytes in the trailing CRC field.
+ */
+#define ETHER_CRC_LEN 4
+
+/*
+ * The length of the combined header.
+ */
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
+
+/*
+ * The minimum packet length.
+ */
+#define ETHER_MIN_LEN 64
+
+/*
+ * The minimum packet user data length.
+ */
+#define ETHER_MIN_DATA 46
+
+/*
+ * The maximum packet length.
+ */
+#define ETHER_MAX_LEN 1518
+
+/*
+ * The maximum packet user data length.
+ */
+#define ETHER_MAX_DATA 1500
+
+/* ether types */
+#define ETHER_TYPE_MIN 0x0600 /* Anything less than MIN is a length */
+#define ETHER_TYPE_IP 0x0800 /* IP */
+#define ETHER_TYPE_ARP 0x0806 /* ARP */
+#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */
+#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */
+#define ETHER_TYPE_802_1X 0x888e /* 802.1x */
+#ifdef BCMWPA2
+#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */
+#endif
+
+/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */
+#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */
+#define ETHER_BRCM_CRAM 0x1 /* Broadcom subtype cram protocol */
+
+/* ether header */
+#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) /* dest address offset */
+#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) /* src address offset */
+#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) /* ether type offset */
+
+/*
+ * A macro to validate a length with
+ */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+
+#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+struct ether_header {
+ uint8 ether_dhost[ETHER_ADDR_LEN];
+ uint8 ether_shost[ETHER_ADDR_LEN];
+ uint16 ether_type;
+} PACKED;
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+#ifndef NOETHREQ /* Quick and ugly hack for VxWorks */
+struct ether_addr {
+ uint8 octet[ETHER_ADDR_LEN];
+} PACKED;
+#endif
+#endif /* !__INCif_etherh Quick and ugly hack for VxWorks */
+
+/*
+ * Takes a pointer, set, test, clear, toggle locally admininistered
+ * address bit in the 48-bit Ethernet address.
+ */
+#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2))
+#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2)
+#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xd))
+#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2))
+
+/* Takes a pointer, marks unicast address bit in the MAC address */
+#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1))
+
+/*
+ * Takes a pointer, returns true if a 48-bit multicast address
+ * (including broadcast, since it is all ones)
+ */
+#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1)
+
+
+/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */
+#define ether_cmp(a, b) (!(((short*)a)[0] == ((short*)b)[0]) | \
+ !(((short*)a)[1] == ((short*)b)[1]) | \
+ !(((short*)a)[2] == ((short*)b)[2]))
+
+/* copy an ethernet address - assumes the pointers can be referenced as shorts */
+#define ether_copy(s, d) { \
+ ((short*)d)[0] = ((short*)s)[0]; \
+ ((short*)d)[1] = ((short*)s)[1]; \
+ ((short*)d)[2] = ((short*)s)[2]; }
+
+/*
+ * Takes a pointer, returns true if a 48-bit broadcast (all ones)
+ */
+#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \
+ ((uint8 *)(ea))[1] & \
+ ((uint8 *)(ea))[2] & \
+ ((uint8 *)(ea))[3] & \
+ ((uint8 *)(ea))[4] & \
+ ((uint8 *)(ea))[5]) == 0xff)
+
+static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}};
+static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}};
+
+/*
+ * Takes a pointer, returns true if a 48-bit null address (all zeros)
+ */
+#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \
+ ((uint8 *)(ea))[1] | \
+ ((uint8 *)(ea))[2] | \
+ ((uint8 *)(ea))[3] | \
+ ((uint8 *)(ea))[4] | \
+ ((uint8 *)(ea))[5]) == 0)
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _NET_ETHERNET_H_ */
diff --git a/package/broadcom-wl/src/driver/proto/vlan.h b/package/broadcom-wl/src/driver/proto/vlan.h
new file mode 100644
index 0000000000..2854b72c6f
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/vlan.h
@@ -0,0 +1,52 @@
+/*
+ * 802.1Q VLAN protocol definitions
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _vlan_h_
+#define _vlan_h_
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */
+#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */
+#define VLAN_PRI_SHIFT 13 /* user priority */
+
+#define VLAN_PRI_MASK 7 /* 3 bits of priority */
+
+#define VLAN_TAG_LEN 4
+#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) /* offset in Ethernet II packet only */
+
+#define VLAN_TPID 0x8100 /* VLAN ethertype/Tag Protocol ID */
+
+struct ethervlan_header {
+ uint8 ether_dhost[ETHER_ADDR_LEN];
+ uint8 ether_shost[ETHER_ADDR_LEN];
+ uint16 vlan_type; /* 0x8100 */
+ uint16 vlan_tag; /* priority, cfi and vid */
+ uint16 ether_type;
+};
+
+#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN)
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _vlan_h_ */
diff --git a/package/broadcom-wl/src/driver/proto/wpa.h b/package/broadcom-wl/src/driver/proto/wpa.h
new file mode 100644
index 0000000000..c4b6dd1db1
--- /dev/null
+++ b/package/broadcom-wl/src/driver/proto/wpa.h
@@ -0,0 +1,158 @@
+/*
+ * Fundamental types and constants relating to WPA
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _proto_wpa_h_
+#define _proto_wpa_h_
+
+#include <typedefs.h>
+#include <proto/ethernet.h>
+
+/* enable structure packing */
+#if defined(__GNUC__)
+#define PACKED __attribute__((packed))
+#else
+#pragma pack(1)
+#define PACKED
+#endif
+
+/* Reason Codes */
+
+/* 13 through 23 taken from IEEE Std 802.11i-2004 */
+#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */
+#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */
+#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */
+#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */
+#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from
+ * (re-)assoc. request/probe response
+ */
+#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */
+#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */
+#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */
+#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */
+#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */
+#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */
+
+#define WPA2_PMKID_LEN 16
+
+/* WPA IE fixed portion */
+typedef struct
+{
+ uint8 tag; /* TAG */
+ uint8 length; /* TAG length */
+ uint8 oui[3]; /* IE OUI */
+ uint8 oui_type; /* OUI type */
+ struct {
+ uint8 low;
+ uint8 high;
+ } PACKED version; /* IE version */
+} PACKED wpa_ie_fixed_t;
+#define WPA_IE_OUITYPE_LEN 4
+#define WPA_IE_FIXED_LEN 8
+#define WPA_IE_TAG_FIXED_LEN 6
+
+#ifdef BCMWPA2
+typedef struct {
+ uint8 tag; /* TAG */
+ uint8 length; /* TAG length */
+ struct {
+ uint8 low;
+ uint8 high;
+ } PACKED version; /* IE version */
+} PACKED wpa_rsn_ie_fixed_t;
+#define WPA_RSN_IE_FIXED_LEN 4
+#define WPA_RSN_IE_TAG_FIXED_LEN 2
+typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN];
+#endif
+
+/* WPA suite/multicast suite */
+typedef struct
+{
+ uint8 oui[3];
+ uint8 type;
+} PACKED wpa_suite_t, wpa_suite_mcast_t;
+#define WPA_SUITE_LEN 4
+
+/* WPA unicast suite list/key management suite list */
+typedef struct
+{
+ struct {
+ uint8 low;
+ uint8 high;
+ } PACKED count;
+ wpa_suite_t list[1];
+} PACKED wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t;
+#define WPA_IE_SUITE_COUNT_LEN 2
+#ifdef BCMWPA2
+typedef struct
+{
+ struct {
+ uint8 low;
+ uint8 high;
+ } PACKED count;
+ wpa_pmkid_t list[1];
+} PACKED wpa_pmkid_list_t;
+#endif
+
+/* WPA cipher suites */
+#define WPA_CIPHER_NONE 0 /* None */
+#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
+#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
+#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */
+#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
+#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
+
+#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \
+ (cipher) == WPA_CIPHER_WEP_40 || \
+ (cipher) == WPA_CIPHER_WEP_104 || \
+ (cipher) == WPA_CIPHER_TKIP || \
+ (cipher) == WPA_CIPHER_AES_OCB || \
+ (cipher) == WPA_CIPHER_AES_CCM)
+
+/* WPA TKIP countermeasures parameters */
+#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */
+#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */
+
+/* RSN IE defines */
+#define RSN_CAP_LEN 2 /* Length of RSN capabilities field (2 octets) */
+
+/* RSN Capabilities defined in 802.11i */
+#define RSN_CAP_PREAUTH 0x0001
+#define RSN_CAP_NOPAIRWISE 0x0002
+#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
+#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2
+#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030
+#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4
+#define RSN_CAP_1_REPLAY_CNTR 0
+#define RSN_CAP_2_REPLAY_CNTRS 1
+#define RSN_CAP_4_REPLAY_CNTRS 2
+#define RSN_CAP_16_REPLAY_CNTRS 3
+
+/* WPA capabilities defined in 802.11i */
+#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS
+#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS
+#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT
+#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK
+
+/* WPA Specific defines */
+#define WPA_CAP_LEN RSN_CAP_LEN /* Length of RSN capabilities in RSN IE (2 octets) */
+
+#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH
+
+
+#undef PACKED
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#endif /* _proto_wpa_h_ */
diff --git a/package/broadcom-wl/src/driver/sbhnddma.h b/package/broadcom-wl/src/driver/sbhnddma.h
index a26db7395e..b83baeb614 100644
--- a/package/broadcom-wl/src/driver/sbhnddma.h
+++ b/package/broadcom-wl/src/driver/sbhnddma.h
@@ -2,7 +2,7 @@
* Generic Broadcom Home Networking Division (HND) DMA engine HW interface
* This supports the following chips: BCM42xx, 44xx, 47xx .
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -10,7 +10,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbhnddma.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _sbhnddma_h_
diff --git a/package/broadcom-wl/src/wlc/wlc.c b/package/broadcom-wl/src/wlc/wlc.c
index f5db9a7638..aa9a559f73 100644
--- a/package/broadcom-wl/src/wlc/wlc.c
+++ b/package/broadcom-wl/src/wlc/wlc.c
@@ -56,7 +56,6 @@
static char wlbuf[8192];
static char interface[16] = "wl0";
-static unsigned long ptable[128];
static unsigned long kmem_offset = 0;
static int vif = 0, debug = 1, fromstdin = 0;
@@ -98,205 +97,6 @@ static inline int my_ether_ntoa(unsigned char *ea, char *buf)
ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]);
}
-/*
- * find the starting point of wl.o in memory
- * by reading /proc/ksyms
- */
-static inline void wlc_get_mem_offset(void)
-{
- FILE *f;
- char s[64];
-
- /* yes, i'm lazy ;) */
- f = popen("grep '\\[wl]' /proc/ksyms | sort", "r");
- if (fgets(s, 64, f) == 0)
- return;
-
- pclose(f);
-
- s[8] = 0;
- kmem_offset = strtoul(s, NULL, 16);
-
- /* sanity check */
- if (kmem_offset < 0xc0000000)
- kmem_offset = 0;
-}
-
-
-static int ptable_init(void)
-{
- glob_t globbuf;
- struct stat statbuf;
- int fd;
-
- if (ptable[0] == PTABLE_MAGIC)
- return 0;
-
- glob("/lib/modules/2.4.*/wl.o.patch", 0, NULL, &globbuf);
-
- if (globbuf.gl_pathv[0] == NULL)
- return -1;
-
- if ((fd = open(globbuf.gl_pathv[0], O_RDONLY)) < 0)
- return -1;
-
- if (fstat(fd, &statbuf) < 0)
- goto failed;
-
- if (statbuf.st_size < 512)
- goto failed;
-
- if (read(fd, ptable, 512) < 512)
- goto failed;
-
- if (ptable[0] != PTABLE_MAGIC)
- goto failed;
-
- close(fd);
-
- wlc_get_mem_offset();
- if (kmem_offset == 0)
- return -1;
-
- return 0;
-
-failed:
- close(fd);
-
- return -1;
-}
-
-static inline unsigned long wlc_kmem_read(unsigned long offset)
-{
- int fd;
- unsigned long ret;
-
- if ((fd = open("/dev/kmem", O_RDONLY )) < 0)
- return -1;
-
- lseek(fd, 0x70000000, SEEK_SET);
- lseek(fd, (kmem_offset - 0x70000000) + offset, SEEK_CUR);
- read(fd, &ret, 4);
- close(fd);
-
- return ret;
-}
-
-static inline void wlc_kmem_write(unsigned long offset, unsigned long value)
-{
- int fd;
-
- if ((fd = open("/dev/kmem", O_WRONLY )) < 0)
- return;
-
- lseek(fd, 0x70000000, SEEK_SET);
- lseek(fd, (kmem_offset - 0x70000000) + offset, SEEK_CUR);
- write(fd, &value, 4);
- close(fd);
-}
-
-static int wlc_patcher_getval(unsigned long key, unsigned long *val)
-{
- unsigned long *pt = &ptable[1];
- unsigned long tmp;
-
- if (ptable_init() < 0) {
- fprintf(stderr, "Could not load the ptable\n");
- return -1;
- }
-
- while (*pt != PTABLE_END) {
- if (*pt == key) {
- tmp = wlc_kmem_read(pt[1]);
-
- if (tmp == pt[2])
- *val = 0xffffffff;
- else
- *val = tmp;
-
- return 0;
- }
- pt += 3;
- }
-
- return -1;
-}
-
-static int wlc_patcher_setval(unsigned long key, unsigned long val)
-{
- unsigned long *pt = &ptable[1];
-
- if (ptable_init() < 0) {
- fprintf(stderr, "Could not load the ptable\n");
- return -1;
- }
-
- if (val != 0xffffffff)
- val = (pt[2] & ~(0xffff)) | (val & 0xffff);
-
- while (*pt != PTABLE_END) {
- if (*pt == key) {
- if (val == 0xffffffff) /* default */
- val = pt[2];
-
- wlc_kmem_write(pt[1], val);
- }
- pt += 3;
- }
-
- return 0;
-}
-
-static int wlc_slottime(wlc_param param, void *data, void *value)
-{
- int *val = (int *) value;
- int ret = 0;
-
- if ((param & PARAM_MODE) == SET) {
- wlc_patcher_setval(PTABLE_SLT1, *val);
- wlc_patcher_setval(PTABLE_SLT2, ((*val == -1) ? *val : *val + 510));
- } else if ((param & PARAM_MODE) == GET) {
- ret = wlc_patcher_getval(PTABLE_SLT1, (unsigned long *) val);
- if (*val != 0xffffffff)
- *val &= 0xffff;
- }
-
- return ret;
-}
-
-static int wlc_noack(wlc_param param, void *data, void *value)
-{
- int *val = (int *) value;
- int ret = 0;
-
- if ((param & PARAM_MODE) == SET) {
- wlc_patcher_setval(PTABLE_ACKW, ((*val) ? 1 : 0));
- } else if ((param & PARAM_MODE) == GET) {
- ret = wlc_patcher_getval(PTABLE_ACKW, (unsigned long *) val);
- *val &= 0xffff;
- *val = (*val ? 1 : 0);
- }
-
- return ret;
-}
-
-static int wlc_ibss_merge(wlc_param param, void *data, void *value)
-{
- int *val = (int *) value;
- int ret = 0;
-
- if ((param & PARAM_MODE) == SET) {
- /* overwrite the instruction with 'lui v0,0x0' - fake a return
- * status of 0 for wlc_bcn_tsf_later */
- wlc_patcher_setval(PTABLE_ACKW, ((*val) ? -1 : 0x3c020000));
- } else if ((param & PARAM_MODE) == GET) {
- ret = wlc_patcher_getval(PTABLE_ACKW, (unsigned long *) val);
- *val = ((*val == -1) ? 1 : 0);
- }
-
- return ret;
-}
-
static int wlc_ioctl(wlc_param param, void *data, void *value)
{
unsigned int *var = ((unsigned int *) data);
@@ -957,6 +757,13 @@ static const struct wlc_call wlc_calls[] = {
.desc = "RTS threshold"
},
{
+ .name = "slottime",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "acktiming",
+ .desc = "Slot time"
+ },
+ {
.name = "rxant",
.param = INT,
.handler = wlc_ioctl,
@@ -1052,24 +859,6 @@ static const struct wlc_call wlc_calls[] = {
.handler = wlc_afterburner,
.desc = "Broadcom Afterburner"
},
- {
- .name = "slottime",
- .param = INT,
- .handler = wlc_slottime,
- .desc = "Slot time (-1 = auto)"
- },
- {
- .name = "txack",
- .param = INT,
- .handler = wlc_noack,
- .desc = "Tx ACK enabled flag"
- },
- {
- .name = "ibss_merge",
- .param = INT,
- .handler = wlc_ibss_merge,
- .desc = "Allow IBSS merge in Ad-Hoc mode"
- }
};
#define wlc_calls_size (sizeof(wlc_calls) / sizeof(struct wlc_call))
diff --git a/package/broadcom-wl/src/wlcompat/Makefile b/package/broadcom-wl/src/wlcompat/Makefile
index 6f3224df14..31e54244e8 100644
--- a/package/broadcom-wl/src/wlcompat/Makefile
+++ b/package/broadcom-wl/src/wlcompat/Makefile
@@ -15,6 +15,9 @@ ifneq ($(DEBUG),)
EXTRA_CFLAGS += -DDEBUG=1
_D=-debug
endif
+ifneq ($(WL_WEXT),)
+ EXTRA_CFLAGS += -DWL_WEXT=1
+endif
obj-m := wlcompat$(_D).o
modules: wlcompat$(_D).o
diff --git a/package/broadcom-wl/src/wlcompat/wlcompat.c b/package/broadcom-wl/src/wlcompat/wlcompat.c
index 2694a851c0..5d2e74d412 100644
--- a/package/broadcom-wl/src/wlcompat/wlcompat.c
+++ b/package/broadcom-wl/src/wlcompat/wlcompat.c
@@ -30,6 +30,7 @@
#include <linux/wireless.h>
#include <linux/timer.h>
#include <linux/delay.h>
+#include <linux/random.h>
#include <net/iw_handler.h>
#include <asm/uaccess.h>
@@ -37,14 +38,15 @@
#include <bcmutils.h>
#include <wlioctl.h>
+char buf[WLC_IOCTL_MAXLEN];
static struct net_device *dev;
-static struct iw_statistics wstats;
#ifndef DEBUG
static int random = 1;
#endif
+#ifndef WL_WEXT
+static struct iw_statistics wstats;
static int last_mode = -1;
static int scan_cur = 0;
-char buf[WLC_IOCTL_MAXLEN];
/* The frequency of each channel in MHz */
const long channel_frequency[] = {
@@ -52,6 +54,7 @@ const long channel_frequency[] = {
2447, 2452, 2457, 2462, 2467, 2472, 2484
};
#define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )
+#endif
#define SCAN_RETRY_MAX 5
#define RNG_POLL_FREQ 1
@@ -88,6 +91,7 @@ static int wl_ioctl(struct net_device *dev, int cmd, void *buf, int len)
return ret;
}
+#if !defined(DEBUG) || !defined(WL_WEXT)
static int
wl_iovar_getbuf(struct net_device *dev, char *iovar, void *param, int paramlen, void *bufptr, int buflen)
{
@@ -268,6 +272,9 @@ wl_bssiovar_get(struct net_device *dev, char *iovar, int bssidx, void *outbuf, i
return err;
}
#endif
+#endif
+
+#ifndef WL_WEXT
int get_primary_key(struct net_device *dev)
{
@@ -903,6 +910,7 @@ static const struct iw_handler_def wlcompat_handler_def =
.num_standard = sizeof(wlcompat_handler)/sizeof(iw_handler),
};
+#endif
#ifdef DEBUG
void print_buffer(int len, unsigned char *buf) {
@@ -923,8 +931,6 @@ void print_buffer(int len, unsigned char *buf) {
static int (*old_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
static int new_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) {
int ret = 0;
- struct iwreq *iwr = (struct iwreq *) ifr;
- struct iw_request_info info;
#ifdef DEBUG
printk("dev: %s ioctl: 0x%04x\n",dev->name,cmd);
@@ -975,23 +981,25 @@ static int __init wlcompat_init()
{
int found = 0, i;
char devname[4] = "wl0";
-
+
while (!found && (dev = dev_get_by_name(devname))) {
- if ((dev->wireless_handlers == NULL) && ((wl_ioctl(dev, WLC_GET_MAGIC, &i, sizeof(i)) == 0) && i == WLC_IOCTL_MAGIC))
+ if ((wl_ioctl(dev, WLC_GET_MAGIC, &i, sizeof(i)) == 0) && (i == WLC_IOCTL_MAGIC))
found = 1;
devname[2]++;
}
-
+
+
if (!found) {
printk("No Broadcom devices found.\n");
return -ENODEV;
}
-
old_ioctl = dev->do_ioctl;
dev->do_ioctl = new_ioctl;
+#ifndef WL_WEXT
dev->wireless_handlers = (struct iw_handler_def *)&wlcompat_handler_def;
dev->get_wireless_stats = wlcompat_get_wireless_stats;
+#endif
#ifndef DEBUG
if (random) {
@@ -1014,8 +1022,10 @@ static void __exit wlcompat_exit()
if (random)
del_timer(&rng_timer);
#endif
+#ifndef WL_WEXT
dev->get_wireless_stats = NULL;
dev->wireless_handlers = NULL;
+#endif
dev->do_ioctl = old_ioctl;
return;
}