mirror of https://github.com/hak5/openwrt.git
remove the wl.o build from the kernel patch and move the driver along with wl, nas and wlc into packages/broadcom-wl
SVN-Revision: 4009lede-17.01
parent
0c327ae79d
commit
3763da2cc5
|
@ -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_ */
|
|
@ -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
Loading…
Reference in New Issue