-+ return 0;
-+}
-+
-+bool
-+dma_txstopped(dma_info_t *di)
-+{
-+ return ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) == XS_XS_STOPPED);
-+}
-+
-+bool
-+dma_rxstopped(dma_info_t *di)
-+{
-+ return ((R_REG(&di->regs->rcvstatus) & RS_RS_MASK) == RS_RS_STOPPED);
-+}
-+
-+void
-+dma_fifoloopbackenable(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
-+ OR_REG(&di->regs->xmtcontrol, XC_LE);
-+}
-+
-+void
-+dma_rxinit(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_rxinit\n", di->name));
-+
-+ di->rxin = di->rxout = 0;
-+
-+ /* clear rx descriptor ring */
-+ BZERO_SM((void*)di->rxd, (di->nrxd * sizeof (dmadd_t)));
-+
-+ dma_rxenable(di);
-+ W_REG(&di->regs->rcvaddr, (di->rxdpa + di->ddoffset));
-+}
-+
-+void
-+dma_rxenable(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_rxenable\n", di->name));
-+ W_REG(&di->regs->rcvcontrol, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
-+}
-+
-+bool
-+dma_rxenabled(dma_info_t *di)
-+{
-+ uint32 rc;
-+
-+ rc = R_REG(&di->regs->rcvcontrol);
-+ return ((rc != 0xffffffff) && (rc & RC_RE));
-+}
-+
-+/*
-+ * The BCM47XX family supports full 32bit dma engine buffer addressing so
-+ * dma buffers can cross 4 Kbyte page boundaries.
-+ */
-+int
-+dma_txfast(dma_info_t *di, void *p0, uint32 coreflags)
-+{
-+ void *p, *next;
-+ uchar *data;
-+ uint len;
-+ uint txout;
-+ uint32 ctrl;
-+ uint32 pa;
-+
-+ DMA_TRACE(("%s: dma_txfast\n", di->name));
-+
-+ txout = di->txout;
-+ ctrl = 0;
-+
-+ /*
-+ * Walk the chain of packet buffers
-+ * allocating and initializing transmit descriptor entries.
-+ */
-+ for (p = p0; p; p = next) {
-+ data = PKTDATA(di->drv, p);
-+ len = PKTLEN(di->drv, p);
-+ next = PKTNEXT(di->drv, p);
-+
-+ /* return nonzero if out of tx descriptors */
-+ if (NEXTTXD(txout) == di->txin)
-+ goto outoftxd;
-+
-+ if (len == 0)
-+ continue;
-+
-+ /* get physical address of buffer start */
-+ pa = (uint32) DMA_MAP(di->dev, data, len, DMA_TX, p);
-+
-+ /* build the descriptor control value */
-+ ctrl = len & CTRL_BC_MASK;
-+
-+ ctrl |= coreflags;
-+
-+ if (p == p0)
-+ ctrl |= CTRL_SOF;
-+ if (next == NULL)
-+ ctrl |= (CTRL_IOC | CTRL_EOF);
-+ if (txout == (di->ntxd - 1))
-+ ctrl |= CTRL_EOT;
-+
-+ /* init the tx descriptor */
-+ W_SM(&di->txd[txout].ctrl, BUS_SWAP32(ctrl));
-+ W_SM(&di->txd[txout].addr, BUS_SWAP32(pa + di->dataoffset));
-+
-+ ASSERT(di->txp[txout] == NULL);
-+
-+ txout = NEXTTXD(txout);
-+ }
-+
-+ /* if last txd eof not set, fix it */
-+ if (!(ctrl & CTRL_EOF))
-+ W_SM(&di->txd[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF));
-+
-+ /* save the packet */
-+ di->txp[PREVTXD(txout)] = p0;
-+
-+ /* bump the tx descriptor index */
-+ di->txout = txout;
-+
-+ /* kick the chip */
-+ W_REG(&di->regs->xmtptr, I2B(txout));
-+
-+ /* tx flow control */
-+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-+
-+ return (0);
-+
-+outoftxd:
-+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
-+ PKTFREE(di->drv, p0, TRUE);
-+ di->txavail = 0;
-+ di->hnddma.txnobuf++;
-+ return (-1);
-+}
-+
-+#define PAGESZ 4096
-+#define PAGEBASE(x) ((uint)(x) & ~4095)
-+
-+/*
-+ * Just like above except go through the extra effort of splitting
-+ * buffers that cross 4Kbyte boundaries into multiple tx descriptors.
-+ */
-+int
-+dma_tx(dma_info_t *di, void *p0, uint32 coreflags)
-+{
-+ void *p, *next;
-+ uchar *data;
-+ uint plen, len;
-+ uchar *page, *start, *end;
-+ uint txout;
-+ uint32 ctrl;
-+ uint32 pa;
-+
-+ DMA_TRACE(("%s: dma_tx\n", di->name));
-+
-+ txout = di->txout;
-+ ctrl = 0;
-+
-+ /*
-+ * Walk the chain of packet buffers
-+ * splitting those that cross 4 Kbyte boundaries
-+ * allocating and initializing transmit descriptor entries.
-+ */
-+ for (p = p0; p; p = next) {
-+ data = PKTDATA(di->drv, p);
-+ plen = PKTLEN(di->drv, p);
-+ next = PKTNEXT(di->drv, p);
-+
-+ if (plen == 0)
-+ continue;
-+
-+ for (page = (uchar*)PAGEBASE(data);
-+ page <= (uchar*)PAGEBASE(data + plen - 1);
-+ page += PAGESZ) {
-+
-+ /* return nonzero if out of tx descriptors */
-+ if (NEXTTXD(txout) == di->txin)
-+ goto outoftxd;
-+
-+ start = (page == (uchar*)PAGEBASE(data))? data: page;
-+ end = (page == (uchar*)PAGEBASE(data + plen))?
-+ (data + plen): (page + PAGESZ);
-+ len = end - start;
-+
-+ /* build the descriptor control value */
-+ ctrl = len & CTRL_BC_MASK;
-+
-+ ctrl |= coreflags;
-+
-+ if ((p == p0) && (start == data))
-+ ctrl |= CTRL_SOF;
-+ if ((next == NULL) && (end == (data + plen)))
-+ ctrl |= (CTRL_IOC | CTRL_EOF);
-+ if (txout == (di->ntxd - 1))
-+ ctrl |= CTRL_EOT;
-+
-+ /* get physical address of buffer start */
-+ pa = (uint32) DMA_MAP(di->dev, start, len, DMA_TX, p);
-+
-+ /* init the tx descriptor */
-+ W_SM(&di->txd[txout].ctrl, BUS_SWAP32(ctrl));
-+ W_SM(&di->txd[txout].addr, BUS_SWAP32(pa + di->dataoffset));
-+
-+ ASSERT(di->txp[txout] == NULL);
-+
-+ txout = NEXTTXD(txout);
-+ }
-+ }
-+
-+ /* if last txd eof not set, fix it */
-+ if (!(ctrl & CTRL_EOF))
-+ W_SM(&di->txd[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF));
-+
-+ /* save the packet */
-+ di->txp[PREVTXD(txout)] = p0;
-+
-+ /* bump the tx descriptor index */
-+ di->txout = txout;
-+
-+ /* kick the chip */
-+ W_REG(&di->regs->xmtptr, I2B(txout));
-+
-+ /* tx flow control */
-+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-+
-+ return (0);
-+
-+outoftxd:
-+ DMA_ERROR(("%s: dma_tx: out of txds\n", di->name));
-+ PKTFREE(di->drv, p0, TRUE);
-+ di->txavail = 0;
-+ di->hnddma.txnobuf++;
-+ return (-1);
-+}
-+
-+/* returns a pointer to the next frame received, or NULL if there are no more */
-+void*
-+dma_rx(dma_info_t *di)
-+{
-+ void *p;
-+ uint len;
-+ int skiplen = 0;
-+
-+ while ((p = dma_getnextrxp(di, FALSE))) {
-+ /* skip giant packets which span multiple rx descriptors */
-+ if (skiplen > 0) {
-+ skiplen -= di->rxbufsize;
-+ if (skiplen < 0)
-+ skiplen = 0;
-+ PKTFREE(di->drv, p, FALSE);
-+ continue;
-+ }
-+
-+ len = ltoh16(*(uint16*)(PKTDATA(di->drv, p)));
-+ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
-+
-+ /* bad frame length check */
-+ if (len > (di->rxbufsize - di->rxoffset)) {
-+ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len));
-+ if (len > 0)
-+ skiplen = len - (di->rxbufsize - di->rxoffset);
-+ PKTFREE(di->drv, p, FALSE);
-+ di->hnddma.rxgiants++;
-+ continue;
-+ }
-+
-+ /* set actual length */
-+ PKTSETLEN(di->drv, p, (di->rxoffset + len));
-+
-+ break;
-+ }
-+
-+ return (p);
-+}
-+
-+/* post receive buffers */
-+void
-+dma_rxfill(dma_info_t *di)
-+{
-+ void *p;
-+ uint rxin, rxout;
-+ uint ctrl;
-+ uint n;
-+ uint i;
-+ uint32 pa;
-+ uint rxbufsize;
-+
-+ /*
-+ * Determine how many receive buffers we're lacking
-+ * from the full complement, allocate, initialize,
-+ * and post them, then update the chip rx lastdscr.
-+ */
-+
-+ rxin = di->rxin;
-+ rxout = di->rxout;
-+ rxbufsize = di->rxbufsize;
-+
-+ n = di->nrxpost - NRXDACTIVE(rxin, rxout);
-+
-+ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
-+
-+ for (i = 0; i < n; i++) {
-+ if ((p = PKTGET(di->drv, rxbufsize, FALSE)) == NULL) {
-+ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
-+ di->hnddma.rxnobuf++;
-+ break;
-+ }
-+
-+ *(uint32*)(OSL_UNCACHED(PKTDATA(di->drv, p))) = 0;
-+
-+ pa = (uint32) DMA_MAP(di->dev, PKTDATA(di->drv, p), rxbufsize, DMA_RX, p);
-+ ASSERT(ISALIGNED(pa, 4));
-+
-+ /* save the free packet pointer */
-+ ASSERT(di->rxp[rxout] == NULL);
-+ di->rxp[rxout] = p;
-+
-+ /* prep the descriptor control value */
-+ ctrl = rxbufsize;
-+ if (rxout == (di->nrxd - 1))
-+ ctrl |= CTRL_EOT;
-+
-+ /* init the rx descriptor */
-+ W_SM(&di->rxd[rxout].ctrl, BUS_SWAP32(ctrl));
-+ W_SM(&di->rxd[rxout].addr, BUS_SWAP32(pa + di->dataoffset));
-+
-+ rxout = NEXTRXD(rxout);
-+ }
-+
-+ di->rxout = rxout;
-+
-+ /* update the chip lastdscr pointer */
-+ W_REG(&di->regs->rcvptr, I2B(rxout));
-+}
-+
-+void
-+dma_txreclaim(dma_info_t *di, bool forceall)
-+{
-+ void *p;
-+
-+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
-+
-+ while ((p = dma_getnexttxp(di, forceall)))
-+ PKTFREE(di->drv, p, TRUE);
-+}
-+
-+/*
-+ * Reclaim next completed txd (txds if using chained buffers) and
-+ * return associated packet.
-+ * If 'force' is true, reclaim txd(s) and return associated packet
-+ * regardless of the value of the hardware "curr" pointer.
-+ */
-+void*
-+dma_getnexttxp(dma_info_t *di, bool forceall)
-+{
-+ uint start, end, i;
-+ void *txp;
-+
-+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
-+
-+ txp = NULL;
-+
-+ start = di->txin;
-+ if (forceall)
-+ end = di->txout;
-+ else
-+ end = B2I(R_REG(&di->regs->xmtstatus) & XS_CD_MASK);
-+
-+ if ((start == 0) && (end > di->txout))
-+ goto bogus;
-+
-+ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
-+ DMA_UNMAP(di->dev, (BUS_SWAP32(R_SM(&di->txd[i].addr)) - di->dataoffset),
-+ (BUS_SWAP32(R_SM(&di->txd[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]);
-+ W_SM(&di->txd[i].addr, 0xdeadbeef);
-+ txp = di->txp[i];
-+ di->txp[i] = NULL;
-+ }
-+
-+ di->txin = i;
-+
-+ /* tx flow control */
-+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-+
-+ return (txp);
-+
-+bogus:
-+/*
-+ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
-+ start, end, di->txout, forceall));
-+*/
-+ return (NULL);
-+}
-+
-+void
-+dma_rxreclaim(dma_info_t *di)
-+{
-+ void *p;
-+
-+ DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
-+
-+ while ((p = dma_getnextrxp(di, TRUE)))
-+ PKTFREE(di->drv, p, FALSE);
-+}
-+
-+void *
-+dma_getnextrxp(dma_info_t *di, bool forceall)
-+{
-+ uint i;
-+ void *rxp;
-+
-+ /* if forcing, dma engine must be disabled */
-+ ASSERT(!forceall || !dma_rxenabled(di));
-+
-+ i = di->rxin;
-+
-+ /* return if no packets posted */
-+ if (i == di->rxout)
-+ return (NULL);
-+
-+ /* ignore curr if forceall */
-+ if (!forceall && (i == B2I(R_REG(&di->regs->rcvstatus) & RS_CD_MASK)))
-+ return (NULL);
-+
-+ /* get the packet pointer that corresponds to the rx descriptor */
-+ rxp = di->rxp[i];
-+ ASSERT(rxp);
-+ di->rxp[i] = NULL;
-+
-+ /* clear this packet from the descriptor ring */
-+ DMA_UNMAP(di->dev, (BUS_SWAP32(R_SM(&di->rxd[i].addr)) - di->dataoffset),
-+ di->rxbufsize, DMA_RX, rxp);
-+ W_SM(&di->rxd[i].addr, 0xdeadbeef);
-+
-+ di->rxin = NEXTRXD(i);
-+
-+ return (rxp);
-+}
-+
-+char*
-+dma_dumptx(dma_info_t *di, char *buf)
-+{
-+ buf += sprintf(buf, "txd 0x%lx txdpa 0x%lx txp 0x%lx txin %d txout %d txavail %d\n",
-+ (ulong)di->txd, di->txdpa, (ulong)di->txp, di->txin, di->txout, di->txavail);
-+ buf += sprintf(buf, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n",
-+ R_REG(&di->regs->xmtcontrol),
-+ R_REG(&di->regs->xmtaddr),
-+ R_REG(&di->regs->xmtptr),
-+ R_REG(&di->regs->xmtstatus));
-+ return (buf);
-+}
-+
-+char*
-+dma_dumprx(dma_info_t *di, char *buf)
-+{
-+ buf += sprintf(buf, "rxd 0x%lx rxdpa 0x%lx rxp 0x%lx rxin %d rxout %d\n",
-+ (ulong)di->rxd, di->rxdpa, (ulong)di->rxp, di->rxin, di->rxout);
-+ buf += sprintf(buf, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n",
-+ R_REG(&di->regs->rcvcontrol),
-+ R_REG(&di->regs->rcvaddr),
-+ R_REG(&di->regs->rcvptr),
-+ R_REG(&di->regs->rcvstatus));
-+ return (buf);
-+}
-+
-+char*
-+dma_dump(dma_info_t *di, char *buf)
-+{
-+ buf = dma_dumptx(di, buf);
-+ buf = dma_dumprx(di, buf);
-+ return (buf);
-+}
-+
-+uint
-+dma_getvar(dma_info_t *di, char *name)
-+{
-+ if (!strcmp(name, "&txavail"))
-+ return ((uint) &di->txavail);
-+ else {
-+ ASSERT(0);
-+ }
-+ return (0);
-+}
-+
-+void
-+dma_txblock(dma_info_t *di)
-+{
-+ di->txavail = 0;
-+}
-+
-+void
-+dma_txunblock(dma_info_t *di)
-+{
-+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-+}
-+
-+uint
-+dma_txactive(dma_info_t *di)
-+{
-+ return (NTXDACTIVE(di->txin, di->txout));
-+}
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c 2005-09-16 10:29:18.166593160 +0200
-@@ -0,0 +1,420 @@
-+/*
-+ * Linux OS Independent Layer
-+ *
-+ * Copyright 2001-2003, 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.2 2005/02/28 13:34:25 jolt Exp $
-+ */
-+
-+#define LINUX_OSL
-+
-+#include <typedefs.h>
-+#include <bcmendian.h>
-+#include <linuxver.h>
-+#include <linux_osl.h>
-+#include <bcmutils.h>
-+#include <linux/delay.h>
-+#ifdef mips
-+#include <asm/paccess.h>
-+#endif
-+#include <pcicfg.h>
-+
-+#define PCI_CFG_RETRY 10
-+
-+void*
-+osl_pktget(void *drv, uint len, bool send)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = dev_alloc_skb(len)) == NULL)
-+ return (NULL);
-+
-+ skb_put(skb, len);
-+
-+ /* ensure the cookie field is cleared */
-+ PKTSETCOOKIE(skb, NULL);
-+
-+ return ((void*) skb);
-+}
-+
-+void
-+osl_pktfree(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;
-+ 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);
-+ }
-+ skb = nskb;
-+ }
-+}
-+
-+uint32
-+osl_pci_read_config(void *loc, uint offset, uint size)
-+{
-+ struct pci_dev *pdev;
-+ uint val;
-+ uint retry=PCI_CFG_RETRY;
-+
-+ /* only 4byte access supported */
-+ ASSERT(size == 4);
-+
-+ pdev = (struct pci_dev*)loc;
-+ do {
-+ pci_read_config_dword(pdev, offset, &val);
-+ if (val != 0xffffffff)
-+ break;
-+ } while (retry--);
-+
-+
-+ return (val);
-+}
-+
-+void
-+osl_pci_write_config(void *loc, uint offset, uint size, uint val)
-+{
-+ struct pci_dev *pdev;
-+ uint retry=PCI_CFG_RETRY;
-+
-+ /* only 4byte access supported */
-+ ASSERT(size == 4);
-+
-+ pdev = (struct pci_dev*)loc;
-+
-+ do {
-+ pci_write_config_dword(pdev, offset, val);
-+ if (offset!=PCI_BAR0_WIN)
-+ break;
-+ if (osl_pci_read_config(loc,offset,size) == val)
-+ break;
-+ } while (retry--);
-+
-+}
-+
-+void
-+osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size)
-+{
-+ ASSERT(0);
-+}
-+
-+void
-+osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size)
-+{
-+ ASSERT(0);
-+}
-+
-+void
-+osl_assert(char *exp, char *file, int line)
-+{
-+ char tempbuf[255];
-+
-+ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line);
-+ panic(tempbuf);
-+}
-+
-+/*
-+ * BINOSL selects the slightly slower function-call-based binary compatible osl.
-+ */
-+#ifdef BINOSL
-+
-+int
-+osl_printf(const char *format, ...)
-+{
-+ va_list args;
-+ char buf[1024];
-+ int len;
-+
-+ /* sprintf into a local buffer because there *is* no "vprintk()".. */
-+ va_start(args, format);
-+ len = vsprintf(buf, format, args);
-+ va_end(args);
-+
-+ if (len > sizeof (buf)) {
-+ printk("osl_printf: buffer overrun\n");
-+ return (0);
-+ }
-+
-+ return (printk(buf));
-+}
-+
-+int
-+osl_sprintf(char *buf, const char *format, ...)
-+{
-+ va_list args;
-+ int rc;
-+
-+ va_start(args, format);
-+ rc = vsprintf(buf, format, args);
-+ va_end(args);
-+ return (rc);
-+}
-+
-+int
-+osl_strcmp(const char *s1, const char *s2)
-+{
-+ return (strcmp(s1, s2));
-+}
-+
-+int
-+osl_strncmp(const char *s1, const char *s2, uint n)
-+{
-+ return (strncmp(s1, s2, n));
-+}
-+
-+int
-+osl_strlen(char *s)
-+{
-+ return (strlen(s));
-+}
-+
-+char*
-+osl_strcpy(char *d, const char *s)
-+{
-+ return (strcpy(d, s));
-+}
-+
-+char*
-+osl_strncpy(char *d, const char *s, uint n)
-+{
-+ return (strncpy(d, s, n));
-+}
-+
-+void
-+bcopy(const void *src, void *dst, int len)
-+{
-+ memcpy(dst, src, len);
-+}
-+
-+int
-+bcmp(const void *b1, const void *b2, int len)
-+{
-+ return (memcmp(b1, b2, len));
-+}
-+
-+void
-+bzero(void *b, int len)
-+{
-+ memset(b, '\0', len);
-+}
-+
-+void*
-+osl_malloc(uint size)
-+{
-+ return (kmalloc(size, GFP_ATOMIC));
-+}
-+
-+void
-+osl_mfree(void *addr, uint size)
-+{
-+ kfree(addr);
-+}
-+
-+uint32
-+osl_readl(volatile uint32 *r)
-+{
-+ return (readl(r));
-+}
-+
-+uint16
-+osl_readw(volatile uint16 *r)
-+{
-+ return (readw(r));
-+}
-+
-+uint8
-+osl_readb(volatile uint8 *r)
-+{
-+ return (readb(r));
-+}
-+
-+void
-+osl_writel(uint32 v, volatile uint32 *r)
-+{
-+ writel(v, r);
-+}
-+
-+void
-+osl_writew(uint16 v, volatile uint16 *r)
-+{
-+ writew(v, r);
-+}
-+
-+void
-+osl_writeb(uint8 v, volatile uint8 *r)
-+{
-+ writeb(v, r);
-+}
-+
-+void *
-+osl_uncached(void *va)
-+{
-+#ifdef mips
-+ return ((void*)KSEG1ADDR(va));
-+#else
-+ return ((void*)va);
-+#endif
-+}
-+
-+uint
-+osl_getcycles(void)
-+{
-+ uint cycles;
-+
-+#if defined(mips)
-+ cycles = read_c0_count() * 2;
-+#elif defined(__i386__)
-+ rdtscl(cycles);
-+#else
-+ cycles = 0;
-+#endif
-+ return cycles;
-+}
-+
-+void *
-+osl_reg_map(uint32 pa, uint size)
-+{
-+ return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
-+}
-+
-+void
-+osl_reg_unmap(void *va)
-+{
-+ iounmap(va);
-+}
-+
-+int
-+osl_busprobe(uint32 *val, uint32 addr)
-+{
-+#ifdef mips
-+ return get_dbe(*val, (uint32*)addr);
-+#else
-+ *val = readl(addr);
-+ return 0;
-+#endif
-+}
-+
-+void*
-+osl_dma_alloc_consistent(void *dev, uint size, ulong *pap)
-+{
-+ return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap));
-+}
-+
-+void
-+osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa)
-+{
-+ pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa);
-+}
-+
-+uint
-+osl_dma_map(void *dev, void *va, uint size, int direction)
-+{
-+ int dir;
-+
-+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
-+ return (pci_map_single(dev, va, size, dir));
-+}
-+
-+void
-+osl_dma_unmap(void *dev, uint pa, uint size, int direction)
-+{
-+ int dir;
-+
-+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
-+ pci_unmap_single(dev, (uint32)pa, size, dir);
-+}
-+
-+void
-+osl_delay(uint usec)
-+{
-+ udelay(usec);
-+}
-+
-+uchar*
-+osl_pktdata(void *drv, void *skb)
-+{
-+ return (((struct sk_buff*)skb)->data);
-+}
-+
-+uint
-+osl_pktlen(void *drv, void *skb)
-+{
-+ return (((struct sk_buff*)skb)->len);
-+}
-+
-+void*
-+osl_pktnext(void *drv, void *skb)
-+{
-+ return (((struct sk_buff*)skb)->next);
-+}
-+
-+void
-+osl_pktsetnext(void *skb, void *x)
-+{
-+ ((struct sk_buff*)skb)->next = (struct sk_buff*)x;
-+}
-+
-+void
-+osl_pktsetlen(void *drv, void *skb, uint len)
-+{
-+ __skb_trim((struct sk_buff*)skb, len);
-+}
-+
-+uchar*
-+osl_pktpush(void *drv, void *skb, int bytes)
-+{
-+ return (skb_push((struct sk_buff*)skb, bytes));
-+}
-+
-+uchar*
-+osl_pktpull(void *drv, void *skb, int bytes)
-+{
-+ return (skb_pull((struct sk_buff*)skb, bytes));
-+}
-+
-+void*
-+osl_pktdup(void *drv, void *skb)
-+{
-+ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC));
-+}
-+
-+void*
-+osl_pktcookie(void *skb)
-+{
-+ return ((void*)((struct sk_buff*)skb)->csum);
-+}
-+
-+void
-+osl_pktsetcookie(void *skb, void *x)
-+{
-+ ((struct sk_buff*)skb)->csum = (uint)x;
-+}
-+
-+void*
-+osl_pktlink(void *skb)
-+{
-+ return (((struct sk_buff*)skb)->prev);
-+}
-+
-+void
-+osl_pktsetlink(void *skb, void *x)
-+{
-+ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x;
-+}
-+
-+#endif
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c 2005-09-16 10:29:18.168592856 +0200
-@@ -0,0 +1,950 @@
-+/*
-+ * BCM47XX Sonics SiliconBackplane MIPS core routines
-+ *
-+ * Copyright 2001-2003, 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: sbmips.c,v 1.1 2005/02/28 13:33:32 jolt Exp $
-+ */
-+
-+#include <typedefs.h>
-+#include <osl.h>
-+#include <sbutils.h>
-+#include <bcmdevs.h>
-+#include <bcmnvram.h>
-+#include <bcmutils.h>
-+#include <hndmips.h>
-+#include <sbconfig.h>
-+#include <sbextif.h>
-+#include <sbchipc.h>
-+#include <sbmemc.h>
-+
-+/*
-+ * Memory segments (32bit kernel mode addresses)
-+ */
-+#undef KUSEG
-+#undef KSEG0
-+#undef KSEG1
-+#undef KSEG2
-+#undef KSEG3
-+#define KUSEG 0x00000000
-+#define KSEG0 0x80000000
-+#define KSEG1 0xa0000000
-+#define KSEG2 0xc0000000
-+#define KSEG3 0xe0000000
-+
-+/*
-+ * Map an address to a certain kernel segment
-+ */
-+#undef KSEG0ADDR
-+#undef KSEG1ADDR
-+#undef KSEG2ADDR
-+#undef KSEG3ADDR
-+#define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0)
-+#define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1)
-+#define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2)
-+#define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3)
-+
-+/*
-+ * The following macros are especially useful for __asm__
-+ * inline assembler.
-+ */
-+#ifndef __STR
-+#define __STR(x) #x
-+#endif
-+#ifndef STR
-+#define STR(x) __STR(x)
-+#endif
-+
-+/* *********************************************************************
-+ * CP0 Registers
-+ ********************************************************************* */
-+
-+#define C0_INX 0 /* CP0: TLB Index */
-+#define C0_RAND 1 /* CP0: TLB Random */
-+#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */
-+#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */
-+#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */
-+#define C0_CTEXT 4 /* CP0: Context */
-+#define C0_PGMASK 5 /* CP0: TLB PageMask */
-+#define C0_WIRED 6 /* CP0: TLB Wired */
-+#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */
-+#define C0_COUNT 9 /* CP0: Count */
-+#define C0_TLBHI 10 /* CP0: TLB EntryHi */
-+#define C0_COMPARE 11 /* CP0: Compare */
-+#define C0_SR 12 /* CP0: Processor Status */
-+#define C0_STATUS C0_SR /* CP0: Processor Status */
-+#define C0_CAUSE 13 /* CP0: Exception Cause */
-+#define C0_EPC 14 /* CP0: Exception PC */
-+#define C0_PRID 15 /* CP0: Processor Revision Indentifier */
-+#define C0_CONFIG 16 /* CP0: Config */
-+#define C0_LLADDR 17 /* CP0: LLAddr */
-+#define C0_WATCHLO 18 /* CP0: WatchpointLo */
-+#define C0_WATCHHI 19 /* CP0: WatchpointHi */
-+#define C0_XCTEXT 20 /* CP0: XContext */
-+#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */
-+#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */
-+#define C0_ECC 26 /* CP0: ECC */
-+#define C0_CACHEERR 27 /* CP0: CacheErr */
-+#define C0_TAGLO 28 /* CP0: TagLo */
-+#define C0_TAGHI 29 /* CP0: TagHi */
-+#define C0_ERREPC 30 /* CP0: ErrorEPC */
-+
-+/*
-+ * Macros to access the system control coprocessor
-+ */
-+
-+#define MFC0(source, sel) \
-+({ \
-+ int __res; \
-+ __asm__ __volatile__( \
-+ ".set\tnoreorder\n\t" \
-+ ".set\tnoat\n\t" \
-+ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \
-+ "move\t%0,$1\n\t" \
-+ ".set\tat\n\t" \
-+ ".set\treorder" \
-+ :"=r" (__res) \
-+ : \
-+ :"$1"); \
-+ __res; \
-+})