mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2025-04-21 12:27:27 +03:00
remove the wl.o build from the kernel patch and move the driver along with wl, nas and wlc into packages/broadcom-wl
git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@4009 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
1 parent
44b110a903
commit
8afe76304a
29 files changed
+3275
-3341
No files matched your search
@@ -0,0 +1,96 @@
|
||||
# $Id: Makefile 2480 2005-11-14 02:07:33Z nbd $
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(TOPDIR)/package/kernel.mk
|
||||
|
||||
PKG_NAME:=broadcom-wl
|
||||
PKG_VERSION:=4.80.9.2
|
||||
PKG_RELEASE:=1
|
||||
WLC_VERSION:=0.1
|
||||
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:=http://downloads.openwrt.org/sources
|
||||
PKG_MD5SUM:=8ff7481425e0b04fc66f2bf950474cbc
|
||||
PKG_CAT:=bzcat
|
||||
|
||||
include $(TOPDIR)/package/rules.mk
|
||||
|
||||
define Package/kmod-brcm-wl
|
||||
SECTION:=drivers
|
||||
CATEGORY:=Drivers
|
||||
DEPENDS:=@LINUX_2_4_BRCM
|
||||
DEFAULT:=y
|
||||
MENU:=1
|
||||
TITLE:=Proprietary BCM43xx WiFi driver
|
||||
DESCRIPTION:=Proprietary Wireless driver for the Broadcom BCM43xx chipset
|
||||
VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(PKG_RELEASE)
|
||||
endef
|
||||
|
||||
define Package/wlc
|
||||
$(call Package/kmod-brcm-wl)
|
||||
DEPENDS:=kmod-brcm-wl
|
||||
TITLE:=Setup utility
|
||||
DESCRIPTION:=Utility for initializing the Broadcom wl driver
|
||||
VERSION:=$(WLC_VERSION)-$(PKG_RELEASE)
|
||||
endef
|
||||
|
||||
define Package/wl
|
||||
$(call Package/wlc)
|
||||
TITLE:=Utility for changing the driver's parameters
|
||||
DESCRIPTION:=Utility for changing the Broadcom wl driver's parameters
|
||||
VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
|
||||
endef
|
||||
|
||||
define Package/nas
|
||||
$(call Package/wl)
|
||||
TITLE:=Proprietary WPA/WPA2 authenticator
|
||||
DESCRIPTION:=Proprietary WPA/WPA2 authenticator for the Broadcom wl driver
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
$(CP) src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
# Compile the kernel part
|
||||
$(MAKE) -C "$(LINUX_DIR)" \
|
||||
CROSS_COMPILE="$(TARGET_CROSS)" \
|
||||
ARCH="$(LINUX_KARCH)" \
|
||||
PATH="$(TARGET_PATH)" \
|
||||
SUBDIRS="$(PKG_BUILD_DIR)/kmod" \
|
||||
modules
|
||||
|
||||
# Compile wlc
|
||||
$(MAKE) -C $(PKG_BUILD_DIR)/wlc \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
CC="$(TARGET_CC)" \
|
||||
CFLAGS="-I$(PKG_BUILD_DIR)/wlc/include $(TARGET_CFLAGS)" \
|
||||
all
|
||||
endef
|
||||
|
||||
define Package/kmod-brcm-wl/install
|
||||
install -d -m0755 $(1)/lib/modules/$(LINUX_VERSION)
|
||||
install -m0644 $(PKG_BUILD_DIR)/kmod/wl.o $(1)/lib/modules/$(LINUX_VERSION)/
|
||||
endef
|
||||
|
||||
define Package/wlc/install
|
||||
install -d -m0755 $(1)/sbin
|
||||
install -m0755 $(PKG_BUILD_DIR)/wlc/wlc $(1)/sbin/
|
||||
endef
|
||||
|
||||
define Package/wl/install
|
||||
install -d -m0755 $(1)/usr/sbin
|
||||
install -m0755 $(PKG_BUILD_DIR)/wl $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
define Package/nas/install
|
||||
install -d -m0755 $(1)/usr/sbin
|
||||
install -m0755 $(PKG_BUILD_DIR)/nas $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,kmod-brcm-wl))
|
||||
$(eval $(call BuildPackage,wlc))
|
||||
$(eval $(call BuildPackage,wl))
|
||||
$(eval $(call BuildPackage,nas))
|
||||
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# Makefile for the Broadcom wl driver
|
||||
#
|
||||
# Copyright 2004, Broadcom Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
|
||||
# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
|
||||
#
|
||||
# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $
|
||||
|
||||
EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
|
||||
|
||||
O_TARGET := wl_link.o
|
||||
|
||||
obj-y := wl_mod.o
|
||||
obj-y += bcmutils.o hnddma.o linux_osl.o
|
||||
|
||||
obj-m := $(O_TARGET)
|
||||
|
||||
wl_mod.o: wl_apsta.o
|
||||
sed -e 's,eth%d,wl%d\x00,g' < $< > $@
|
||||
|
||||
wl.o: wl_link.o
|
||||
$(OBJDUMP) -d $< | perl patchtable.pl > patchtable.bin
|
||||
cat wl_link.o patchtable.bin > $@
|
||||
|
||||
modules: wl.o
|
||||
|
||||
include $(TOPDIR)/Rules.make
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Fundamental constants relating to IP Protocol
|
||||
*
|
||||
* $Id: bcmip.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $
|
||||
*/
|
||||
|
||||
#ifndef _bcmip_h_
|
||||
#define _bcmip_h_
|
||||
|
||||
/* 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_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 */
|
||||
|
||||
/* 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_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_ADDR_STR_LEN 16 /* Max IP address length in string format */
|
||||
|
||||
/* 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)
|
||||
|
||||
#endif /* _bcmip_h_ */
|
||||
@@ -0,0 +1,857 @@
|
||||
/*
|
||||
* Misc useful OS-independent routines.
|
||||
*
|
||||
* 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.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmdefs.h>
|
||||
#include <stdarg.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;
|
||||
};
|
||||
|
||||
/* copy a pkt buffer chain into a buffer */
|
||||
uint
|
||||
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;
|
||||
}
|
||||
|
||||
/* return total length of buffer chain */
|
||||
uint
|
||||
pkttotlen(osl_t *osh, void *p)
|
||||
{
|
||||
uint 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)
|
||||
{
|
||||
for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p))
|
||||
;
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* osl multiple-precedence packet queue
|
||||
* hi_prec is always >= the number of the highest non-empty queue
|
||||
*/
|
||||
void *
|
||||
pktq_penq(struct pktq *pq, int prec, void *p)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
|
||||
ASSERT(prec >= 0 && prec < pq->num_prec);
|
||||
ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
|
||||
|
||||
ASSERT(!pktq_full(pq));
|
||||
ASSERT(!pktq_pfull(pq, prec));
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if (q->head)
|
||||
PKTSETLINK(q->tail, p);
|
||||
else
|
||||
q->head = p;
|
||||
|
||||
q->tail = p;
|
||||
q->len++;
|
||||
|
||||
pq->len++;
|
||||
|
||||
if (pq->hi_prec < prec)
|
||||
pq->hi_prec = (uint8)prec;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
pktq_penq_head(struct pktq *pq, int prec, void *p)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
|
||||
ASSERT(prec >= 0 && prec < pq->num_prec);
|
||||
ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
|
||||
|
||||
ASSERT(!pktq_full(pq));
|
||||
ASSERT(!pktq_pfull(pq, prec));
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if (q->head == NULL)
|
||||
q->tail = p;
|
||||
|
||||
PKTSETLINK(p, q->head);
|
||||
q->head = p;
|
||||
q->len++;
|
||||
|
||||
pq->len++;
|
||||
|
||||
if (pq->hi_prec < prec)
|
||||
pq->hi_prec = (uint8)prec;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
pktq_pdeq(struct pktq *pq, int prec)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
void *p;
|
||||
|
||||
ASSERT(prec >= 0 && prec < pq->num_prec);
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if ((p = q->head) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((q->head = PKTLINK(p)) == NULL)
|
||||
q->tail = NULL;
|
||||
|
||||
q->len--;
|
||||
|
||||
pq->len--;
|
||||
|
||||
PKTSETLINK(p, NULL);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
pktq_pdeq_tail(struct pktq *pq, int prec)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
void *p, *prev;
|
||||
|
||||
ASSERT(prec >= 0 && prec < pq->num_prec);
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if ((p = q->head) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (prev = NULL; p != q->tail; p = PKTLINK(p))
|
||||
prev = p;
|
||||
|
||||
if (prev)
|
||||
PKTSETLINK(prev, NULL);
|
||||
else
|
||||
q->head = NULL;
|
||||
|
||||
q->tail = prev;
|
||||
q->len--;
|
||||
|
||||
pq->len--;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
pktq_pdel(struct pktq *pq, void *pktbuf, int prec)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
void *p;
|
||||
|
||||
ASSERT(prec >= 0 && prec < pq->num_prec);
|
||||
|
||||
if (!pktbuf)
|
||||
return FALSE;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
pktq_init(struct pktq *pq, int num_prec, int max_len)
|
||||
{
|
||||
int prec;
|
||||
|
||||
ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC);
|
||||
|
||||
bzero(pq, sizeof(*pq));
|
||||
|
||||
pq->num_prec = (uint16)num_prec;
|
||||
|
||||
pq->max = (uint16)max_len;
|
||||
|
||||
for (prec = 0; prec < num_prec; prec++)
|
||||
pq->q[prec].max = pq->max;
|
||||
}
|
||||
|
||||
void *
|
||||
pktq_deq(struct pktq *pq, int *prec_out)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
void *p;
|
||||
int prec;
|
||||
|
||||
if (pq->len == 0)
|
||||
return NULL;
|
||||
|
||||
while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
|
||||
pq->hi_prec--;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if ((p = q->head) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((q->head = PKTLINK(p)) == NULL)
|
||||
q->tail = NULL;
|
||||
|
||||
q->len--;
|
||||
|
||||
pq->len--;
|
||||
|
||||
if (prec_out)
|
||||
*prec_out = prec;
|
||||
|
||||
PKTSETLINK(p, NULL);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
pktq_deq_tail(struct pktq *pq, int *prec_out)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
void *p, *prev;
|
||||
int prec;
|
||||
|
||||
if (pq->len == 0)
|
||||
return NULL;
|
||||
|
||||
for (prec = 0; prec < pq->hi_prec; prec++)
|
||||
if (pq->q[prec].head)
|
||||
break;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if ((p = q->head) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (prev = NULL; p != q->tail; p = PKTLINK(p))
|
||||
prev = p;
|
||||
|
||||
if (prev)
|
||||
PKTSETLINK(prev, NULL);
|
||||
else
|
||||
q->head = NULL;
|
||||
|
||||
q->tail = prev;
|
||||
q->len--;
|
||||
|
||||
pq->len--;
|
||||
|
||||
if (prec_out)
|
||||
*prec_out = prec;
|
||||
|
||||
PKTSETLINK(p, NULL);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
pktq_peek(struct pktq *pq, int *prec_out)
|
||||
{
|
||||
int prec;
|
||||
|
||||
if (pq->len == 0)
|
||||
return NULL;
|
||||
|
||||
while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
|
||||
pq->hi_prec--;
|
||||
|
||||
if (prec_out)
|
||||
*prec_out = prec;
|
||||
|
||||
return (pq->q[prec].head);
|
||||
}
|
||||
|
||||
void *
|
||||
pktq_peek_tail(struct pktq *pq, int *prec_out)
|
||||
{
|
||||
int prec;
|
||||
|
||||
if (pq->len == 0)
|
||||
return NULL;
|
||||
|
||||
for (prec = 0; prec < pq->hi_prec; prec++)
|
||||
if (pq->q[prec].head)
|
||||
break;
|
||||
|
||||
if (prec_out)
|
||||
*prec_out = prec;
|
||||
|
||||
return (pq->q[prec].tail);
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
/* Return sum of lengths of a specific set of precedences */
|
||||
int
|
||||
pktq_mlen(struct pktq *pq, uint prec_bmp)
|
||||
{
|
||||
int prec, len;
|
||||
|
||||
len = 0;
|
||||
|
||||
for (prec = 0; prec <= pq->hi_prec; prec++)
|
||||
if (prec_bmp & (1 << prec))
|
||||
len += pq->q[prec].len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Priority dequeue from a specific set of precedences */
|
||||
void *
|
||||
pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
void *p;
|
||||
int prec;
|
||||
|
||||
if (pq->len == 0)
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if ((p = q->head) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((q->head = PKTLINK(p)) == NULL)
|
||||
q->tail = NULL;
|
||||
|
||||
q->len--;
|
||||
|
||||
if (prec_out)
|
||||
*prec_out = prec;
|
||||
|
||||
pq->len--;
|
||||
|
||||
PKTSETLINK(p, NULL);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
char*
|
||||
bcmstrcat(char *dest, const char *src)
|
||||
{
|
||||
strcpy(&dest[strlen(dest)], src);
|
||||
return (dest);
|
||||
}
|
||||
|
||||
char*
|
||||
bcm_ether_ntoa(struct ether_addr *ea, char *buf)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
|
||||
int
|
||||
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);
|
||||
}
|
||||
|
||||
/* Takes an Ethernet frame and sets out-of-bound PKTPRIO
|
||||
* Also updates the inplace vlan tag if requested
|
||||
*/
|
||||
void
|
||||
pktsetprio(void *pkt, bool update_vtag)
|
||||
{
|
||||
struct ether_header *eh;
|
||||
struct ethervlan_header *evh;
|
||||
uint8 *pktdata;
|
||||
int priority = 0;
|
||||
|
||||
pktdata = (uint8 *) PKTDATA(NULL, pkt);
|
||||
ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16)));
|
||||
|
||||
eh = (struct ether_header *) pktdata;
|
||||
|
||||
if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) {
|
||||
uint16 vlan_tag;
|
||||
int vlan_prio, dscp_prio = 0;
|
||||
|
||||
evh = (struct ethervlan_header *)eh;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
static char bcm_undeferrstr[BCME_STRLEN];
|
||||
|
||||
static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
|
||||
|
||||
/* Convert the Error codes into related Error strings */
|
||||
const char *
|
||||
bcmerrorstr(int bcmerror)
|
||||
{
|
||||
int abs_bcmerror;
|
||||
|
||||
abs_bcmerror = ABS(bcmerror);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN);
|
||||
|
||||
return bcmerrorstrtable[abs_bcmerror];
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
/* unknown type for length check in iovar info */
|
||||
ASSERT(0);
|
||||
bcmerror = BCME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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 *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++);
|
||||
#endif /* __mips__ */
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Advance from the current 1-byte tag/1-byte length/variable-length value
|
||||
* triple, to the next, returning a pointer to the next.
|
||||
* 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.
|
||||
*/
|
||||
bcm_tlv_t *
|
||||
bcm_next_tlv(bcm_tlv_t *elt, int *buflen)
|
||||
{
|
||||
int len;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* validate next elt */
|
||||
if (!bcm_valid_tlv(elt, *buflen))
|
||||
return NULL;
|
||||
|
||||
return elt;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
bcm_tlv_t *
|
||||
bcm_parse_tlvs(void *buf, int buflen, uint key)
|
||||
{
|
||||
bcm_tlv_t *elt;
|
||||
int totlen;
|
||||
|
||||
elt = (bcm_tlv_t*)buf;
|
||||
totlen = buflen;
|
||||
|
||||
/* find tagged parameter */
|
||||
while (totlen >= 2) {
|
||||
int len = elt->len;
|
||||
|
||||
/* validate remaining totlen */
|
||||
if ((elt->id == key) && (totlen >= (len + 2)))
|
||||
return (elt);
|
||||
|
||||
elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
|
||||
totlen -= (len + 2);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 *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;
|
||||
}
|
||||
|
||||
|
||||
/* Initialization of bcmstrbuf structure */
|
||||
void
|
||||
bcm_binit(struct bcmstrbuf *b, char *buf, uint size)
|
||||
{
|
||||
b->origsize = b->size = size;
|
||||
b->origbuf = b->buf = buf;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Generic Broadcom Home Networking Division (HND) DMA engine SW interface
|
||||
* This supports the following chips: BCM42xx, 44xx, 47xx .
|
||||
*
|
||||
* 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: hnddma.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $
|
||||
*/
|
||||
|
||||
#ifndef _hnddma_h_
|
||||
#define _hnddma_h_
|
||||
|
||||
typedef const struct hnddma_pub hnddma_t;
|
||||
|
||||
/* dma function type */
|
||||
typedef void (*di_detach_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_txreset_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_rxreset_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_rxidle_t)(hnddma_t *dmah);
|
||||
typedef void (*di_txinit_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_txenabled_t)(hnddma_t *dmah);
|
||||
typedef void (*di_rxinit_t)(hnddma_t *dmah);
|
||||
typedef void (*di_txsuspend_t)(hnddma_t *dmah);
|
||||
typedef void (*di_txresume_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_txsuspended_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_txsuspendedidle_t)(hnddma_t *dmah);
|
||||
typedef int (*di_txfast_t)(hnddma_t *dmah, void *p, bool commit);
|
||||
typedef void (*di_fifoloopbackenable_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_txstopped_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_rxstopped_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_rxenable_t)(hnddma_t *dmah);
|
||||
typedef bool (*di_rxenabled_t)(hnddma_t *dmah);
|
||||
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 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);
|
||||
typedef void (*di_txblock_t)(hnddma_t *dmah);
|
||||
typedef void (*di_txunblock_t)(hnddma_t *dmah);
|
||||
typedef uint (*di_txactive_t)(hnddma_t *dmah);
|
||||
typedef void (*di_txrotate_t)(hnddma_t *dmah);
|
||||
typedef void (*di_counterreset_t)(hnddma_t *dmah);
|
||||
typedef char* (*di_dump_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring);
|
||||
typedef char* (*di_dumptx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring);
|
||||
typedef char* (*di_dumprx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring);
|
||||
|
||||
/* dma opsvec */
|
||||
typedef struct di_fcn_s {
|
||||
di_detach_t detach;
|
||||
di_txinit_t txinit;
|
||||
di_txreset_t txreset;
|
||||
di_txenabled_t txenabled;
|
||||
di_txsuspend_t txsuspend;
|
||||
di_txresume_t txresume;
|
||||
di_txsuspended_t txsuspended;
|
||||
di_txsuspendedidle_t txsuspendedidle;
|
||||
di_txfast_t txfast;
|
||||
di_txstopped_t txstopped;
|
||||
di_txreclaim_t txreclaim;
|
||||
di_getnexttxp_t getnexttxp;
|
||||
di_peeknexttxp_t peeknexttxp;
|
||||
di_txblock_t txblock;
|
||||
di_txunblock_t txunblock;
|
||||
di_txactive_t txactive;
|
||||
di_txrotate_t txrotate;
|
||||
|
||||
di_rxinit_t rxinit;
|
||||
di_rxreset_t rxreset;
|
||||
di_rxidle_t rxidle;
|
||||
di_rxstopped_t rxstopped;
|
||||
di_rxenable_t rxenable;
|
||||
di_rxenabled_t rxenabled;
|
||||
di_rx_t rx;
|
||||
di_rxfill_t rxfill;
|
||||
di_rxreclaim_t rxreclaim;
|
||||
di_getnextrxp_t getnextrxp;
|
||||
|
||||
di_fifoloopbackenable_t fifoloopbackenable;
|
||||
di_getvar_t d_getvar;
|
||||
di_counterreset_t counterreset;
|
||||
di_dump_t dump;
|
||||
di_dumptx_t dumptx;
|
||||
di_dumprx_t dumprx;
|
||||
uint endnum;
|
||||
} di_fcn_t;
|
||||
|
||||
/*
|
||||
* Exported data structure (read-only)
|
||||
*/
|
||||
/* export structure */
|
||||
struct hnddma_pub {
|
||||
di_fcn_t di_fn; /* DMA function pointers */
|
||||
uint txavail; /* # free tx descriptors */
|
||||
|
||||
/* rx error counters */
|
||||
uint rxgiants; /* rx giant frames */
|
||||
uint rxnobuf; /* rx out of dma descriptors */
|
||||
/* tx error counters */
|
||||
uint txnobuf; /* tx out of dma descriptors */
|
||||
};
|
||||
|
||||
|
||||
extern 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);
|
||||
#define dma_detach(di) ((di)->di_fn.detach(di))
|
||||
#define dma_txreset(di) ((di)->di_fn.txreset(di))
|
||||
#define dma_rxreset(di) ((di)->di_fn.rxreset(di))
|
||||
#define dma_rxidle(di) ((di)->di_fn.rxidle(di))
|
||||
#define dma_txinit(di) ((di)->di_fn.txinit(di))
|
||||
#define dma_txenabled(di) ((di)->di_fn.txenabled(di))
|
||||
#define dma_rxinit(di) ((di)->di_fn.rxinit(di))
|
||||
#define dma_txsuspend(di) ((di)->di_fn.txsuspend(di))
|
||||
#define dma_txresume(di) ((di)->di_fn.txresume(di))
|
||||
#define dma_txsuspended(di) ((di)->di_fn.txsuspended(di))
|
||||
#define dma_txsuspendedidle(di) ((di)->di_fn.txsuspendedidle(di))
|
||||
#define dma_txfast(di, p, commit) ((di)->di_fn.txfast(di, p, commit))
|
||||
#define dma_fifoloopbackenable(di) ((di)->di_fn.fifoloopbackenable(di))
|
||||
#define dma_txstopped(di) ((di)->di_fn.txstopped(di))
|
||||
#define dma_rxstopped(di) ((di)->di_fn.rxstopped(di))
|
||||
#define dma_rxenable(di) ((di)->di_fn.rxenable(di))
|
||||
#define dma_rxenabled(di) ((di)->di_fn.rxenabled(di))
|
||||
#define dma_rx(di) ((di)->di_fn.rx(di))
|
||||
#define dma_rxfill(di) ((di)->di_fn.rxfill(di))
|
||||
#define dma_txreclaim(di, forceall) ((di)->di_fn.txreclaim(di, forceall))
|
||||
#define dma_rxreclaim(di) ((di)->di_fn.rxreclaim(di))
|
||||
#define dma_getvar(di, name) ((di)->di_fn.d_getvar(di, name))
|
||||
#define dma_getnexttxp(di, forceall) ((di)->di_fn.getnexttxp(di, forceall))
|
||||
#define dma_getnextrxp(di, forceall) ((di)->di_fn.getnextrxp(di, forceall))
|
||||
#define dma_peeknexttxp(di) ((di)->di_fn.peeknexttxp(di))
|
||||
#define dma_txblock(di) ((di)->di_fn.txblock(di))
|
||||
#define dma_txunblock(di) ((di)->di_fn.txunblock(di))
|
||||
#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))
|
||||
|
||||
#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
|
||||
* This info is needed by DMA_ALLOC_CONSISTENT in dma attach
|
||||
*/
|
||||
extern uint dma_addrwidth(sb_t *sbh, void *dmaregs);
|
||||
|
||||
/* pio helpers */
|
||||
void dma_txpioloopback(osl_t *osh, dma32regs_t *);
|
||||
|
||||
#endif /* _hnddma_h_ */
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Linux OS Independent Layer
|
||||
*
|
||||
* 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: linux_osl.c,v 1.1.1.14 2006/04/08 06:13:39 honor Exp $
|
||||
*/
|
||||
|
||||
#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 <linux/delay.h>
|
||||
#ifdef mips
|
||||
#include <asm/paccess.h>
|
||||
#endif /* mips */
|
||||
#include <pcicfg.h>
|
||||
|
||||
#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];
|
||||
} 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 */
|
||||
};
|
||||
|
||||
/* translate bcmerrors into linux errors */
|
||||
int
|
||||
osl_error(int bcmerror)
|
||||
{
|
||||
int abs_bcmerror;
|
||||
int array_size = ARRAYSIZE(linuxbcmerrormap);
|
||||
|
||||
abs_bcmerror = ABS(bcmerror);
|
||||
|
||||
if (bcmerror > 0)
|
||||
abs_bcmerror = 0;
|
||||
|
||||
else if (abs_bcmerror >= array_size)
|
||||
abs_bcmerror = BCME_ERROR;
|
||||
|
||||
return linuxbcmerrormap[abs_bcmerror];
|
||||
}
|
||||
|
||||
osl_t *
|
||||
osl_attach(void *pdev, bool pkttag)
|
||||
{
|
||||
osl_t *osh;
|
||||
|
||||
osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
|
||||
ASSERT(osh);
|
||||
|
||||
bzero(osh, sizeof(osl_t));
|
||||
|
||||
/*
|
||||
* 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));
|
||||
|
||||
osh->magic = OS_HANDLE_MAGIC;
|
||||
osh->malloced = 0;
|
||||
osh->failed = 0;
|
||||
osh->dbgmem_list = NULL;
|
||||
osh->pdev = pdev;
|
||||
osh->pub.pkttag = pkttag;
|
||||
|
||||
return osh;
|
||||
}
|
||||
|
||||
void
|
||||
osl_detach(osl_t *osh)
|
||||
{
|
||||
if (osh == NULL)
|
||||
return;
|
||||
|
||||
ASSERT(osh->magic == OS_HANDLE_MAGIC);
|
||||
kfree(osh);
|
||||
}
|
||||
|
||||
/* Return a new packet. zero out pkttag */
|
||||
void*
|
||||
osl_pktget(osl_t *osh, uint len, bool send)
|
||||
{
|
||||
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)
|
||||
{
|
||||
struct sk_buff *skb, *nskb;
|
||||
|
||||
skb = (struct sk_buff*) p;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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_mfree(osl_t *osh, void *addr, uint size)
|
||||
{
|
||||
if (osh) {
|
||||
ASSERT(osh->magic == OS_HANDLE_MAGIC);
|
||||
osh->malloced -= size;
|
||||
}
|
||||
kfree(addr);
|
||||
}
|
||||
|
||||
uint
|
||||
osl_malloced(osl_t *osh)
|
||||
{
|
||||
ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
|
||||
return (osh->malloced);
|
||||
}
|
||||
|
||||
uint osl_malloc_failed(osl_t *osh)
|
||||
{
|
||||
ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
|
||||
return (osh->failed);
|
||||
}
|
||||
|
||||
#undef osl_delay
|
||||
void
|
||||
osl_delay(uint usec)
|
||||
{
|
||||
OSL_DELAY(usec);
|
||||
}
|
||||
|
||||
/* Clone a packet.
|
||||
* The pkttag contents are NOT cloned.
|
||||
*/
|
||||
void *
|
||||
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++;
|
||||
return (p);
|
||||
}
|
||||
|
||||
uint
|
||||
osl_pktalloced(osl_t *osh)
|
||||
{
|
||||
return (osh->pub.pktalloced);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Linux OS Independent Layer
|
||||
*
|
||||
* 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: linux_osl.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $
|
||||
*/
|
||||
|
||||
#ifndef _linux_osl_h_
|
||||
#define _linux_osl_h_
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <linuxver.h>
|
||||
#include <osl.h>
|
||||
|
||||
#define OSL_PKTTAG_SZ 32 /* Size of PktTag */
|
||||
|
||||
/* osl handle type forward declaration */
|
||||
typedef struct osl_dmainfo osldma_t;
|
||||
|
||||
/* OSL initialization */
|
||||
extern osl_t *osl_attach(void *pdev, bool pkttag);
|
||||
extern void osl_detach(osl_t *osh);
|
||||
|
||||
/* 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);
|
||||
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)
|
||||
#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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* 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) */
|
||||
|
||||
/* packet primitives */
|
||||
#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send))
|
||||
#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb))
|
||||
#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data)
|
||||
#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len)
|
||||
#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head))
|
||||
#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
|
||||
#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next)
|
||||
#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
|
||||
#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len))
|
||||
#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes))
|
||||
#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 PKTLIST_DUMP(osh, buf)
|
||||
|
||||
/* 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(struct osl_pubinfo *osh, struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
if (osh->pkttag)
|
||||
bzero((void*)skb->cb, OSL_PKTTAG_SZ);
|
||||
|
||||
/* Increment the packet counter */
|
||||
for (nskb = skb; nskb; nskb = nskb->next) {
|
||||
osh->pktalloced++;
|
||||
}
|
||||
|
||||
return (void *)skb;
|
||||
}
|
||||
#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((struct osl_pubinfo *)osh), \
|
||||
(struct sk_buff*)(skb))
|
||||
|
||||
/* 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
|
||||
*/
|
||||
static INLINE struct sk_buff *
|
||||
osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
if (osh->pkttag)
|
||||
bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ);
|
||||
|
||||
/* Decrement the packet counter */
|
||||
for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
|
||||
osh->pktalloced--;
|
||||
}
|
||||
|
||||
return (struct sk_buff *)pkt;
|
||||
}
|
||||
#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((struct osl_pubinfo *)(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 PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned)
|
||||
|
||||
extern void *osl_pktget(osl_t *osh, uint len, bool send);
|
||||
extern void osl_pktfree(osl_t *osh, void *skb);
|
||||
extern void *osl_pktdup(osl_t *osh, void *skb);
|
||||
extern uint osl_pktalloced(osl_t *osh);
|
||||
|
||||
#define OSL_ERROR(bcmerror) osl_error(bcmerror)
|
||||
extern int osl_error(int bcmerror);
|
||||
|
||||
/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
|
||||
#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */
|
||||
|
||||
#endif /* _linux_osl_h_ */
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/perl
|
||||
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;
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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_ */
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Generic Broadcom Home Networking Division (HND) DMA engine HW interface
|
||||
* This supports the following chips: BCM42xx, 44xx, 47xx .
|
||||
*
|
||||
* 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: sbhnddma.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $
|
||||
*/
|
||||
|
||||
#ifndef _sbhnddma_h_
|
||||
#define _sbhnddma_h_
|
||||
|
||||
/* DMA structure:
|
||||
* support two DMA engines: 32 bits address or 64 bit addressing
|
||||
* basic DMA register set is per channel(transmit or receive)
|
||||
* a pair of channels is defined for convenience
|
||||
*/
|
||||
|
||||
|
||||
/* 32 bits addressing */
|
||||
|
||||
/* dma registers per channel(xmt or rcv) */
|
||||
typedef volatile struct {
|
||||
uint32 control; /* enable, et al */
|
||||
uint32 addr; /* descriptor ring base address (4K aligned) */
|
||||
uint32 ptr; /* last descriptor posted to chip */
|
||||
uint32 status; /* current active descriptor, et al */
|
||||
} dma32regs_t;
|
||||
|
||||
typedef volatile struct {
|
||||
dma32regs_t xmt; /* dma tx channel */
|
||||
dma32regs_t rcv; /* dma rx channel */
|
||||
} dma32regp_t;
|
||||
|
||||
typedef volatile struct { /* diag access */
|
||||
uint32 fifoaddr; /* diag address */
|
||||
uint32 fifodatalow; /* low 32bits of data */
|
||||
uint32 fifodatahigh; /* high 32bits of data */
|
||||
uint32 pad; /* reserved */
|
||||
} dma32diag_t;
|
||||
|
||||
/*
|
||||
* DMA Descriptor
|
||||
* Descriptors are only read by the hardware, never written back.
|
||||
*/
|
||||
typedef volatile struct {
|
||||
uint32 ctrl; /* misc control bits & bufcount */
|
||||
uint32 addr; /* data buffer address */
|
||||
} dma32dd_t;
|
||||
|
||||
/*
|
||||
* Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
|
||||
*/
|
||||
#define D32MAXRINGSZ 4096
|
||||
#define D32RINGALIGN 4096
|
||||
#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t))
|
||||
|
||||
/* transmit channel control */
|
||||
#define XC_XE ((uint32)1 << 0) /* transmit enable */
|
||||
#define XC_SE ((uint32)1 << 1) /* transmit suspend request */
|
||||
#define XC_LE ((uint32)1 << 2) /* loopback enable */
|
||||
#define XC_FL ((uint32)1 << 4) /* flush request */
|
||||
#define XC_AE ((uint32)3 << 16) /* address extension bits */
|
||||
#define XC_AE_SHIFT 16
|
||||
|
||||
/* transmit descriptor table pointer */
|
||||
#define XP_LD_MASK 0xfff /* last valid descriptor */
|
||||
|
||||
/* transmit channel status */
|
||||
#define XS_CD_MASK 0x0fff /* current descriptor pointer */
|
||||
#define XS_XS_MASK 0xf000 /* transmit state */
|
||||
#define XS_XS_SHIFT 12
|
||||
#define XS_XS_DISABLED 0x0000 /* disabled */
|
||||
#define XS_XS_ACTIVE 0x1000 /* active */
|
||||
#define XS_XS_IDLE 0x2000 /* idle wait */
|
||||
#define XS_XS_STOPPED 0x3000 /* stopped */
|
||||
#define XS_XS_SUSP 0x4000 /* suspend pending */
|
||||
#define XS_XE_MASK 0xf0000 /* transmit errors */
|
||||
#define XS_XE_SHIFT 16
|
||||
#define XS_XE_NOERR 0x00000 /* no error */
|
||||
#define XS_XE_DPE 0x10000 /* descriptor protocol error */
|
||||
#define XS_XE_DFU 0x20000 /* data fifo underrun */
|
||||
#define XS_XE_BEBR 0x30000 /* bus error on buffer read */
|
||||
#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */
|
||||
#define XS_AD_MASK 0xfff00000 /* active descriptor */
|
||||
#define XS_AD_SHIFT 20
|
||||
|
||||
/* receive channel control */
|
||||
#define RC_RE ((uint32)1 << 0) /* receive enable */
|
||||
#define RC_RO_MASK 0xfe /* receive frame offset */
|
||||
#define RC_RO_SHIFT 1
|
||||
#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */
|
||||
#define RC_AE ((uint32)3 << 16) /* address extension bits */
|
||||
#define RC_AE_SHIFT 16
|
||||
|
||||
/* receive descriptor table pointer */
|
||||
#define RP_LD_MASK 0xfff /* last valid descriptor */
|
||||
|
||||
/* receive channel status */
|
||||
#define RS_CD_MASK 0x0fff /* current descriptor pointer */
|
||||
#define RS_RS_MASK 0xf000 /* receive state */
|
||||
#define RS_RS_SHIFT 12
|
||||
#define RS_RS_DISABLED 0x0000 /* disabled */
|
||||
#define RS_RS_ACTIVE 0x1000 /* active */
|
||||
#define RS_RS_IDLE 0x2000 /* idle wait */
|
||||
#define RS_RS_STOPPED 0x3000 /* reserved */
|
||||
#define RS_RE_MASK 0xf0000 /* receive errors */
|
||||
#define RS_RE_SHIFT 16
|
||||
#define RS_RE_NOERR 0x00000 /* no error */
|
||||
#define RS_RE_DPE 0x10000 /* descriptor protocol error */
|
||||
#define RS_RE_DFO 0x20000 /* data fifo overflow */
|
||||
#define RS_RE_BEBW 0x30000 /* bus error on buffer write */
|
||||
#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */
|
||||
#define RS_AD_MASK 0xfff00000 /* active descriptor */
|
||||
#define RS_AD_SHIFT 20
|
||||
|
||||
/* fifoaddr */
|
||||
#define FA_OFF_MASK 0xffff /* offset */
|
||||
#define FA_SEL_MASK 0xf0000 /* select */
|
||||
#define FA_SEL_SHIFT 16
|
||||
#define FA_SEL_XDD 0x00000 /* transmit dma data */
|
||||
#define FA_SEL_XDP 0x10000 /* transmit dma pointers */
|
||||
#define FA_SEL_RDD 0x40000 /* receive dma data */
|
||||
#define FA_SEL_RDP 0x50000 /* receive dma pointers */
|
||||
#define FA_SEL_XFD 0x80000 /* transmit fifo data */
|
||||
#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */
|
||||
#define FA_SEL_RFD 0xc0000 /* receive fifo data */
|
||||
#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */
|
||||
#define FA_SEL_RSD 0xe0000 /* receive frame status data */
|
||||
#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */
|
||||
|
||||
/* descriptor control flags */
|
||||
#define CTRL_BC_MASK 0x1fff /* buffer byte count */
|
||||
#define CTRL_AE ((uint32)3 << 16) /* address extension bits */
|
||||
#define CTRL_AE_SHIFT 16
|
||||
#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */
|
||||
#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */
|
||||
#define CTRL_EOF ((uint32)1 << 30) /* end of frame */
|
||||
#define CTRL_SOF ((uint32)1 << 31) /* start of frame */
|
||||
|
||||
/* control flags in the range [27:20] are core-specific and not defined here */
|
||||
#define CTRL_CORE_MASK 0x0ff00000
|
||||
|
||||
/* 64 bits addressing */
|
||||
|
||||
/* dma registers per channel(xmt or rcv) */
|
||||
typedef volatile struct {
|
||||
uint32 control; /* enable, et al */
|
||||
uint32 ptr; /* last descriptor posted to chip */
|
||||
uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
|
||||
uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
|
||||
uint32 status0; /* current descriptor, xmt state */
|
||||
uint32 status1; /* active descriptor, xmt error */
|
||||
} dma64regs_t;
|
||||
|
||||
typedef volatile struct {
|
||||
dma64regs_t tx; /* dma64 tx channel */
|
||||
dma64regs_t rx; /* dma64 rx channel */
|
||||
} dma64regp_t;
|
||||
|
||||
typedef volatile struct { /* diag access */
|
||||
uint32 fifoaddr; /* diag address */
|
||||
uint32 fifodatalow; /* low 32bits of data */
|
||||
uint32 fifodatahigh; /* high 32bits of data */
|
||||
uint32 pad; /* reserved */
|
||||
} dma64diag_t;
|
||||
|
||||
/*
|
||||
* DMA Descriptor
|
||||
* Descriptors are only read by the hardware, never written back.
|
||||
*/
|
||||
typedef volatile struct {
|
||||
uint32 ctrl1; /* misc control bits & bufcount */
|
||||
uint32 ctrl2; /* buffer count and address extension */
|
||||
uint32 addrlow; /* memory address of the date buffer, bits 31:0 */
|
||||
uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */
|
||||
} dma64dd_t;
|
||||
|
||||
/*
|
||||
* Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss.
|
||||
*/
|
||||
#define D64MAXRINGSZ 8192
|
||||
#define D64RINGALIGN 8192
|
||||
#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t))
|
||||
|
||||
/* transmit channel control */
|
||||
#define D64_XC_XE 0x00000001 /* transmit enable */
|
||||
#define D64_XC_SE 0x00000002 /* transmit suspend request */
|
||||
#define D64_XC_LE 0x00000004 /* loopback enable */
|
||||
#define D64_XC_FL 0x00000010 /* flush request */
|
||||
#define D64_XC_AE 0x00030000 /* address extension bits */
|
||||
#define D64_XC_AE_SHIFT 16
|
||||
|
||||
/* transmit descriptor table pointer */
|
||||
#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */
|
||||
|
||||
/* transmit channel status */
|
||||
#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
|
||||
#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
|
||||
#define D64_XS0_XS_SHIFT 28
|
||||
#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
|
||||
#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
|
||||
#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
|
||||
#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
|
||||
#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
|
||||
|
||||
#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */
|
||||
#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
|
||||
#define D64_XS1_XE_SHIFT 28
|
||||
#define D64_XS1_XE_NOERR 0x00000000 /* no error */
|
||||
#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
|
||||
#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
|
||||
#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
|
||||
#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
|
||||
#define D64_XS1_XE_COREE 0x50000000 /* core error */
|
||||
|
||||
/* receive channel control */
|
||||
#define D64_RC_RE 0x00000001 /* receive enable */
|
||||
#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */
|
||||
#define D64_RC_RO_SHIFT 1
|
||||
#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */
|
||||
#define D64_RC_AE 0x00030000 /* address extension bits */
|
||||
#define D64_RC_AE_SHIFT 16
|
||||
|
||||
/* receive descriptor table pointer */
|
||||
#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */
|
||||
|
||||
/* receive channel status */
|
||||
#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
|
||||
#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
|
||||
#define D64_RS0_RS_SHIFT 28
|
||||
#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
|
||||
#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
|
||||
#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
|
||||
#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
|
||||
#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
|
||||
|
||||
#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
|
||||
#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
|
||||
#define D64_RS1_RE_SHIFT 28
|
||||
#define D64_RS1_RE_NOERR 0x00000000 /* no error */
|
||||
#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
|
||||
#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
|
||||
#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
|
||||
#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
|
||||
#define D64_RS1_RE_COREE 0x50000000 /* core error */
|
||||
|
||||
/* fifoaddr */
|
||||
#define D64_FA_OFF_MASK 0xffff /* offset */
|
||||
#define D64_FA_SEL_MASK 0xf0000 /* select */
|
||||
#define D64_FA_SEL_SHIFT 16
|
||||
#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
|
||||
#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
|
||||
#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
|
||||
#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
|
||||
#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
|
||||
#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
|
||||
#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
|
||||
#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
|
||||
#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
|
||||
#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
|
||||
|
||||
/* descriptor control flags 1 */
|
||||
#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */
|
||||
#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */
|
||||
#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */
|
||||
#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */
|
||||
|
||||
/* descriptor control flags 2 */
|
||||
#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */
|
||||
#define D64_CTRL2_AE 0x00030000 /* address extension bits */
|
||||
#define D64_CTRL2_AE_SHIFT 16
|
||||
|
||||
/* control flags in the range [27:20] are core-specific and not defined here */
|
||||
#define D64_CTRL_CORE_MASK 0x0ff00000
|
||||
|
||||
|
||||
#endif /* _sbhnddma_h_ */
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,40 +0,0 @@
|
||||
# $Id: Makefile 2480 2005-11-14 02:07:33Z nbd $
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wlc
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/wlc
|
||||
|
||||
include $(TOPDIR)/package/rules.mk
|
||||
|
||||
define Package/wlc
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=@PACKAGE_KMOD_BRCM_WL
|
||||
DEFAULT:=y
|
||||
TITLE:=Utility for configuring the Broadcom wl driver
|
||||
DESCRIPTION:=Utility for configuring the Broadcom wl driver
|
||||
endef
|
||||
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(CP) src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C $(PKG_BUILD_DIR)\
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
CC="$(TARGET_CC)" \
|
||||
CFLAGS="-I$(PKG_BUILD_DIR)/include $(TARGET_CFLAGS)" \
|
||||
all
|
||||
endef
|
||||
|
||||
define Package/wlc/install
|
||||
install -d -m0755 $(1)/sbin
|
||||
install -m0755 $(PKG_BUILD_DIR)/wlc $(1)/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,wlc))
|
||||
@@ -1,8 +0,0 @@
|
||||
config PACKAGE_KMOD_BRCM_WL
|
||||
prompt "kmod-brcm-wl...................... Broadcom Wireless Network Driver"
|
||||
tristate
|
||||
depends LINUX_2_4_BRCM
|
||||
default y
|
||||
help
|
||||
Proprietary driver for Broadcom Wireless chipsets
|
||||
|
||||
@@ -8,10 +8,6 @@ include ../rules.mk
|
||||
include ./config
|
||||
|
||||
# broadcom specific kmod packages
|
||||
$(eval $(call KMOD_template,BRCM_WL,brcm-wl,\
|
||||
$(MODULES_DIR)/kernel/drivers/net/wl/wl.o \
|
||||
,CONFIG_WL,,20,wl))
|
||||
|
||||
$(eval $(call KMOD_template,LP,lp,\
|
||||
$(MODULES_DIR)/kernel/drivers/parport/parport.o \
|
||||
$(MODULES_DIR)/kernel/drivers/parport/parport_splink.o \
|
||||
@@ -29,38 +25,3 @@ $(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked
|
||||
@$(CP) config $(LINUX_DIR)/.config
|
||||
touch $@
|
||||
|
||||
|
||||
###############################################
|
||||
# Proprietary driver for BCM43xx
|
||||
###############################################
|
||||
|
||||
LINUX_BINARY_DRIVER_SITE=http://downloads.openwrt.org/sources
|
||||
# proprietary driver, extracted from Linksys GPL sourcetree WRT54GS 4.70.6
|
||||
LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.7.tar.gz
|
||||
LINUX_BINARY_WL_MD5SUM=ff50130914790cbae9b73a13513da5ee
|
||||
|
||||
$(DL_DIR)/$(LINUX_BINARY_WL_DRIVER):
|
||||
$(SCRIPT_DIR)/download.pl $(DL_DIR) $(LINUX_BINARY_WL_DRIVER) $(LINUX_BINARY_WL_MD5SUM) $(LINUX_BINARY_DRIVER_SITE)
|
||||
|
||||
$(LINUX_DIR)/.unpacked: $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER)
|
||||
$(LINUX_DIR)/.depend_done: $(LINUX_DIR)/.drivers-unpacked
|
||||
$(LINUX_DIR)/.modules_done: $(LINUX_DIR)/.drivers-unpacked
|
||||
$(STAMP_DIR)/.linux-compile: $(LINUX_DIR)/.drivers-installed
|
||||
|
||||
$(LINUX_DIR)/.drivers-unpacked: $(LINUX_DIR)/.unpacked
|
||||
-mkdir -p $(BUILD_DIR)
|
||||
zcat $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) -
|
||||
# copy binary wlan driver
|
||||
mkdir -p $(LINUX_DIR)/drivers/net/wl
|
||||
$(CP) $(BUILD_DIR)/kernel-binary-wl/*.o $(LINUX_DIR)/drivers/net/wl
|
||||
touch $@
|
||||
|
||||
$(LINUX_DIR)/.drivers-installed: $(LINUX_DIR)/.modules_done
|
||||
mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl
|
||||
@-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/wl.o ] || $(CP) $(LINUX_DIR)/drivers/net/wl/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/
|
||||
touch $@
|
||||
|
||||
linux-dirclean: drivers-clean
|
||||
|
||||
drivers-clean: FORCE
|
||||
rm -rf $(BUILD_DIR)/kernel-binary-wl
|
||||
@@ -91,7 +91,6 @@ CONFIG_PCI=y
|
||||
CONFIG_NONCOHERENT_IO=y
|
||||
CONFIG_NEW_TIME_C=y
|
||||
CONFIG_NEW_IRQ=y
|
||||
CONFIG_HND=y
|
||||
# CONFIG_MIPS_AU1000 is not set
|
||||
|
||||
#
|
||||
@@ -726,7 +725,6 @@ CONFIG_SCSI_MULTI_LUN=y
|
||||
# Network device support
|
||||
#
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_HND=y
|
||||
|
||||
#
|
||||
# ARCnet devices
|
||||
@@ -832,7 +830,6 @@ CONFIG_NET_RADIO=y
|
||||
# CONFIG_AIRONET4500_PROC is not set
|
||||
# CONFIG_AIRO is not set
|
||||
# CONFIG_HERMES is not set
|
||||
CONFIG_WL=m
|
||||
# CONFIG_PLX_HERMES is not set
|
||||
# CONFIG_TMD_HERMES is not set
|
||||
# CONFIG_PCI_HERMES is not set
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user