* Generic Broadcom Home Networking Division (HND) DMA module.
* This supports the following chips: BCM42xx, 44xx, 47xx .
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: hnddma.c,v 1.11 2006/04/08 07:12:42 honor Exp $
*/
#include <typedefs.h>
#include "linux_osl.h"
#include <bcmendian.h>
#include <sbconfig.h>
-#include <bcmutils.h>
+#include "bcmutils.h"
#include <bcmdevs.h>
#include <sbutils.h>
#include "hnddma.h"
/* debug/trace */
+#ifdef BCMDBG
+#define DMA_ERROR(args) if (!(*di->msg_level & 1)); else printf args
+#define DMA_TRACE(args) if (!(*di->msg_level & 2)); else printf args
+#else
#define DMA_ERROR(args)
#define DMA_TRACE(args)
+#endif
/* default dma message level (if input msg_level pointer is null in dma_attach()) */
-static uint dma_msg_level =
- 0;
+static uint dma_msg_level = 0;
-#define MAXNAMEL 8 /* 8 char names */
+#define MAXNAMEL 8 /* 8 char names */
#define DI_INFO(dmah) (dma_info_t *)dmah
+typedef struct osl_dmainfo osldma_t;
/* dma engine software state */
-typedef struct dma_info {
- struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t,
- * which could be const
- */
- uint *msg_level; /* message level pointer */
- char name[MAXNAMEL]; /* callers name for diag msgs */
-
- void *osh; /* os handle */
- sb_t *sbh; /* sb handle */
-
- bool dma64; /* dma64 enabled */
- bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
-
- dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */
- dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */
- dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */
- dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */
-
- uint32 dma64align; /* either 8k or 4k depends on number of dd */
- dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */
- dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */
- uint ntxd; /* # tx descriptors tunable */
- uint txin; /* index of next descriptor to reclaim */
- uint txout; /* index of next descriptor to post */
- void **txp; /* pointer to parallel array of pointers to packets */
- osldma_t *tx_dmah; /* DMA TX descriptor ring handle */
- osldma_t **txp_dmah; /* DMA TX packet data handle */
- ulong txdpa; /* physical address of descriptor ring */
- uint txdalign; /* #bytes added to alloc'd mem to align txd */
- uint txdalloc; /* #bytes allocated for the ring */
-
- dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */
- dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */
- uint nrxd; /* # rx descriptors tunable */
- uint rxin; /* index of next descriptor to reclaim */
- uint rxout; /* index of next descriptor to post */
- void **rxp; /* pointer to parallel array of pointers to packets */
- osldma_t *rx_dmah; /* DMA RX descriptor ring handle */
- osldma_t **rxp_dmah; /* DMA RX packet data handle */
- ulong rxdpa; /* physical address of descriptor ring */
- uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
- uint rxdalloc; /* #bytes allocated for the ring */
-
- /* tunables */
- uint rxbufsize; /* rx buffer size in bytes,
- not including the extra headroom
- */
- uint nrxpost; /* # rx buffers to keep posted */
- uint rxoffset; /* rxcontrol offset */
- uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
- uint ddoffsethigh; /* high 32 bits */
- uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
- uint dataoffsethigh; /* high 32 bits */
+typedef struct dma_info
+{
+ struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t,
+ * which could be const
+ */
+ uint *msg_level; /* message level pointer */
+ char name[MAXNAMEL]; /* callers name for diag msgs */
+
+ void *osh; /* os handle */
+ sb_t *sbh; /* sb handle */
+
+ bool dma64; /* dma64 enabled */
+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
+
+ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */
+ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */
+ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */
+ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */
+
+ uint32 dma64align; /* either 8k or 4k depends on number of dd */
+ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */
+ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */
+ uint ntxd; /* # tx descriptors tunable */
+ uint txin; /* index of next descriptor to reclaim */
+ uint txout; /* index of next descriptor to post */
+ void **txp; /* pointer to parallel array of pointers to packets */
+ osldma_t *tx_dmah; /* DMA TX descriptor ring handle */
+ osldma_t **txp_dmah; /* DMA TX packet data handle */
+ ulong txdpa; /* physical address of descriptor ring */
+ uint txdalign; /* #bytes added to alloc'd mem to align txd */
+ uint txdalloc; /* #bytes allocated for the ring */
+
+ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */
+ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */
+ uint nrxd; /* # rx descriptors tunable */
+ uint rxin; /* index of next descriptor to reclaim */
+ uint rxout; /* index of next descriptor to post */
+ void **rxp; /* pointer to parallel array of pointers to packets */
+ osldma_t *rx_dmah; /* DMA RX descriptor ring handle */
+ osldma_t **rxp_dmah; /* DMA RX packet data handle */
+ ulong rxdpa; /* physical address of descriptor ring */
+ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
+ uint rxdalloc; /* #bytes allocated for the ring */
+
+ /* tunables */
+ uint rxbufsize; /* rx buffer size in bytes,
+ not including the extra headroom
+ */
+ uint nrxpost; /* # rx buffers to keep posted */
+ uint rxoffset; /* rxcontrol offset */
+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
+ uint ddoffsethigh; /* high 32 bits */
+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
+ uint dataoffsethigh; /* high 32 bits */
} dma_info_t;
#ifdef BCMDMA64
#define I2B(index, type) ((index) * sizeof(type))
#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
-#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */
+#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */
/* common prototypes */
-static bool _dma_isaddrext(dma_info_t *di);
-static bool _dma_alloc(dma_info_t *di, uint direction);
-static void _dma_detach(dma_info_t *di);
-static void _dma_ddtable_init(dma_info_t *di, uint direction, ulong pa);
-static void _dma_rxinit(dma_info_t *di);
-static void *_dma_rx(dma_info_t *di);
-static void _dma_rxfill(dma_info_t *di);
-static void _dma_rxreclaim(dma_info_t *di);
-static void _dma_rxenable(dma_info_t *di);
-static void * _dma_getnextrxp(dma_info_t *di, bool forceall);
-
-static void _dma_txblock(dma_info_t *di);
-static void _dma_txunblock(dma_info_t *di);
-static uint _dma_txactive(dma_info_t *di);
-
-static void* _dma_peeknexttxp(dma_info_t *di);
-static uintptr _dma_getvar(dma_info_t *di, const char *name);
-static void _dma_counterreset(dma_info_t *di);
-static void _dma_fifoloopbackenable(dma_info_t *di);
+static bool _dma_isaddrext (dma_info_t * di);
+static bool _dma_alloc (dma_info_t * di, uint direction);
+static void _dma_detach (dma_info_t * di);
+static void _dma_ddtable_init (dma_info_t * di, uint direction, ulong pa);
+static void _dma_rxinit (dma_info_t * di);
+static void *_dma_rx (dma_info_t * di);
+static void _dma_rxfill (dma_info_t * di);
+static void _dma_rxreclaim (dma_info_t * di);
+static void _dma_rxenable (dma_info_t * di);
+static void *_dma_getnextrxp (dma_info_t * di, bool forceall);
+
+static void _dma_txblock (dma_info_t * di);
+static void _dma_txunblock (dma_info_t * di);
+static uint _dma_txactive (dma_info_t * di);
+
+static void *_dma_peeknexttxp (dma_info_t * di);
+static uintptr _dma_getvar (dma_info_t * di, const char *name);
+static void _dma_counterreset (dma_info_t * di);
+static void _dma_fifoloopbackenable (dma_info_t * di);
/* ** 32 bit DMA prototypes */
-static bool dma32_alloc(dma_info_t *di, uint direction);
-static bool dma32_txreset(dma_info_t *di);
-static bool dma32_rxreset(dma_info_t *di);
-static bool dma32_txsuspendedidle(dma_info_t *di);
-static int dma32_txfast(dma_info_t *di, void *p0, bool commit);
-static void *dma32_getnexttxp(dma_info_t *di, bool forceall);
-static void *dma32_getnextrxp(dma_info_t *di, bool forceall);
-static void dma32_txrotate(dma_info_t *di);
-static bool dma32_rxidle(dma_info_t *di);
-static void dma32_txinit(dma_info_t *di);
-static bool dma32_txenabled(dma_info_t *di);
-static void dma32_txsuspend(dma_info_t *di);
-static void dma32_txresume(dma_info_t *di);
-static bool dma32_txsuspended(dma_info_t *di);
-static void dma32_txreclaim(dma_info_t *di, bool forceall);
-static bool dma32_txstopped(dma_info_t *di);
-static bool dma32_rxstopped(dma_info_t *di);
-static bool dma32_rxenabled(dma_info_t *di);
-static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs);
+static bool dma32_alloc (dma_info_t * di, uint direction);
+static bool dma32_txreset (dma_info_t * di);
+static bool dma32_rxreset (dma_info_t * di);
+static bool dma32_txsuspendedidle (dma_info_t * di);
+static int dma32_txfast (dma_info_t * di, void *p0, bool commit);
+static void *dma32_getnexttxp (dma_info_t * di, bool forceall);
+static void *dma32_getnextrxp (dma_info_t * di, bool forceall);
+static void dma32_txrotate (dma_info_t * di);
+static bool dma32_rxidle (dma_info_t * di);
+static void dma32_txinit (dma_info_t * di);
+static bool dma32_txenabled (dma_info_t * di);
+static void dma32_txsuspend (dma_info_t * di);
+static void dma32_txresume (dma_info_t * di);
+static bool dma32_txsuspended (dma_info_t * di);
+static void dma32_txreclaim (dma_info_t * di, bool forceall);
+static bool dma32_txstopped (dma_info_t * di);
+static bool dma32_rxstopped (dma_info_t * di);
+static bool dma32_rxenabled (dma_info_t * di);
+static bool _dma32_addrext (osl_t * osh, dma32regs_t * dma32regs);
/* ** 64 bit DMA prototypes and stubs */
#ifdef BCMDMA64
-static bool dma64_alloc(dma_info_t *di, uint direction);
-static bool dma64_txreset(dma_info_t *di);
-static bool dma64_rxreset(dma_info_t *di);
-static bool dma64_txsuspendedidle(dma_info_t *di);
-static int dma64_txfast(dma_info_t *di, void *p0, bool commit);
-static void *dma64_getnexttxp(dma_info_t *di, bool forceall);
-static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
-static void dma64_txrotate(dma_info_t *di);
-
-static bool dma64_rxidle(dma_info_t *di);
-static void dma64_txinit(dma_info_t *di);
-static bool dma64_txenabled(dma_info_t *di);
-static void dma64_txsuspend(dma_info_t *di);
-static void dma64_txresume(dma_info_t *di);
-static bool dma64_txsuspended(dma_info_t *di);
-static void dma64_txreclaim(dma_info_t *di, bool forceall);
-static bool dma64_txstopped(dma_info_t *di);
-static bool dma64_rxstopped(dma_info_t *di);
-static bool dma64_rxenabled(dma_info_t *di);
-static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs);
+static bool dma64_alloc (dma_info_t * di, uint direction);
+static bool dma64_txreset (dma_info_t * di);
+static bool dma64_rxreset (dma_info_t * di);
+static bool dma64_txsuspendedidle (dma_info_t * di);
+static int dma64_txfast (dma_info_t * di, void *p0, bool commit);
+static void *dma64_getnexttxp (dma_info_t * di, bool forceall);
+static void *dma64_getnextrxp (dma_info_t * di, bool forceall);
+static void dma64_txrotate (dma_info_t * di);
+
+static bool dma64_rxidle (dma_info_t * di);
+static void dma64_txinit (dma_info_t * di);
+static bool dma64_txenabled (dma_info_t * di);
+static void dma64_txsuspend (dma_info_t * di);
+static void dma64_txresume (dma_info_t * di);
+static bool dma64_txsuspended (dma_info_t * di);
+static void dma64_txreclaim (dma_info_t * di, bool forceall);
+static bool dma64_txstopped (dma_info_t * di);
+static bool dma64_rxstopped (dma_info_t * di);
+static bool dma64_rxenabled (dma_info_t * di);
+static bool _dma64_addrext (osl_t * osh, dma64regs_t * dma64regs);
#else
-static bool dma64_alloc(dma_info_t *di, uint direction) { return FALSE; }
-static bool dma64_txreset(dma_info_t *di) { return FALSE; }
-static bool dma64_rxreset(dma_info_t *di) { return FALSE; }
-static bool dma64_txsuspendedidle(dma_info_t *di) { return FALSE;}
-static int dma64_txfast(dma_info_t *di, void *p0, bool commit) { return 0; }
-static void *dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; }
-static void *dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; }
-static void dma64_txrotate(dma_info_t *di) { return; }
-
-static bool dma64_rxidle(dma_info_t *di) { return FALSE; }
-static void dma64_txinit(dma_info_t *di) { return; }
-static bool dma64_txenabled(dma_info_t *di) { return FALSE; }
-static void dma64_txsuspend(dma_info_t *di) { return; }
-static void dma64_txresume(dma_info_t *di) { return; }
-static bool dma64_txsuspended(dma_info_t *di) {return FALSE; }
-static void dma64_txreclaim(dma_info_t *di, bool forceall) { return; }
-static bool dma64_txstopped(dma_info_t *di) { return FALSE; }
-static bool dma64_rxstopped(dma_info_t *di) { return FALSE; }
-static bool dma64_rxenabled(dma_info_t *di) { return FALSE; }
-static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs) { return FALSE; }
-
-#endif /* BCMDMA64 */
+static bool
+dma64_alloc (dma_info_t * di, uint direction)
+{
+ return FALSE;
+}
+static bool
+dma64_txreset (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+dma64_rxreset (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+dma64_txsuspendedidle (dma_info_t * di)
+{
+ return FALSE;
+}
+static int
+dma64_txfast (dma_info_t * di, void *p0, bool commit)
+{
+ return 0;
+}
+static void *
+dma64_getnexttxp (dma_info_t * di, bool forceall)
+{
+ return NULL;
+}
+static void *
+dma64_getnextrxp (dma_info_t * di, bool forceall)
+{
+ return NULL;
+}
+static void
+dma64_txrotate (dma_info_t * di)
+{
+ return;
+}
+static bool
+dma64_rxidle (dma_info_t * di)
+{
+ return FALSE;
+}
+static void
+dma64_txinit (dma_info_t * di)
+{
+ return;
+}
+static bool
+dma64_txenabled (dma_info_t * di)
+{
+ return FALSE;
+}
+static void
+dma64_txsuspend (dma_info_t * di)
+{
+ return;
+}
+static void
+dma64_txresume (dma_info_t * di)
+{
+ return;
+}
+static bool
+dma64_txsuspended (dma_info_t * di)
+{
+ return FALSE;
+}
+static void
+dma64_txreclaim (dma_info_t * di, bool forceall)
+{
+ return;
+}
+static bool
+dma64_txstopped (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+dma64_rxstopped (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+dma64_rxenabled (dma_info_t * di)
+{
+ return FALSE;
+}
+static bool
+_dma64_addrext (osl_t * osh, dma64regs_t * dma64regs)
+{
+ return FALSE;
+}
+
+#endif /* BCMDMA64 */
+
+#ifdef BCMDBG
+static void dma32_dumpring (dma_info_t * di, struct bcmstrbuf *b,
+ dma32dd_t * ring, uint start, uint end,
+ uint max_num);
+static void dma32_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring);
+static void dma32_dumptx (dma_info_t * di, struct bcmstrbuf *b,
+ bool dumpring);
+static void dma32_dumprx (dma_info_t * di, struct bcmstrbuf *b,
+ bool dumpring);
+
+static void dma64_dumpring (dma_info_t * di, struct bcmstrbuf *b,
+ dma64dd_t * ring, uint start, uint end,
+ uint max_num);
+static void dma64_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring);
+static void dma64_dumptx (dma_info_t * di, struct bcmstrbuf *b,
+ bool dumpring);
+static void dma64_dumprx (dma_info_t * di, struct bcmstrbuf *b,
+ bool dumpring);
+#endif
static di_fcn_t dma64proc = {
- (di_detach_t)_dma_detach,
- (di_txinit_t)dma64_txinit,
- (di_txreset_t)dma64_txreset,
- (di_txenabled_t)dma64_txenabled,
- (di_txsuspend_t)dma64_txsuspend,
- (di_txresume_t)dma64_txresume,
- (di_txsuspended_t)dma64_txsuspended,
- (di_txsuspendedidle_t)dma64_txsuspendedidle,
- (di_txfast_t)dma64_txfast,
- (di_txstopped_t)dma64_txstopped,
- (di_txreclaim_t)dma64_txreclaim,
- (di_getnexttxp_t)dma64_getnexttxp,
- (di_peeknexttxp_t)_dma_peeknexttxp,
- (di_txblock_t)_dma_txblock,
- (di_txunblock_t)_dma_txunblock,
- (di_txactive_t)_dma_txactive,
- (di_txrotate_t)dma64_txrotate,
-
- (di_rxinit_t)_dma_rxinit,
- (di_rxreset_t)dma64_rxreset,
- (di_rxidle_t)dma64_rxidle,
- (di_rxstopped_t)dma64_rxstopped,
- (di_rxenable_t)_dma_rxenable,
- (di_rxenabled_t)dma64_rxenabled,
- (di_rx_t)_dma_rx,
- (di_rxfill_t)_dma_rxfill,
- (di_rxreclaim_t)_dma_rxreclaim,
- (di_getnextrxp_t)_dma_getnextrxp,
-
- (di_fifoloopbackenable_t)_dma_fifoloopbackenable,
- (di_getvar_t)_dma_getvar,
- (di_counterreset_t)_dma_counterreset,
-
- NULL,
- NULL,
- NULL,
- 34
+ (di_detach_t) _dma_detach,
+ (di_txinit_t) dma64_txinit,
+ (di_txreset_t) dma64_txreset,
+ (di_txenabled_t) dma64_txenabled,
+ (di_txsuspend_t) dma64_txsuspend,
+ (di_txresume_t) dma64_txresume,
+ (di_txsuspended_t) dma64_txsuspended,
+ (di_txsuspendedidle_t) dma64_txsuspendedidle,
+ (di_txfast_t) dma64_txfast,
+ (di_txstopped_t) dma64_txstopped,
+ (di_txreclaim_t) dma64_txreclaim,
+ (di_getnexttxp_t) dma64_getnexttxp,
+ (di_peeknexttxp_t) _dma_peeknexttxp,
+ (di_txblock_t) _dma_txblock,
+ (di_txunblock_t) _dma_txunblock,
+ (di_txactive_t) _dma_txactive,
+ (di_txrotate_t) dma64_txrotate,
+
+ (di_rxinit_t) _dma_rxinit,
+ (di_rxreset_t) dma64_rxreset,
+ (di_rxidle_t) dma64_rxidle,
+ (di_rxstopped_t) dma64_rxstopped,
+ (di_rxenable_t) _dma_rxenable,
+ (di_rxenabled_t) dma64_rxenabled,
+ (di_rx_t) _dma_rx,
+ (di_rxfill_t) _dma_rxfill,
+ (di_rxreclaim_t) _dma_rxreclaim,
+ (di_getnextrxp_t) _dma_getnextrxp,
+
+ (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+ (di_getvar_t) _dma_getvar,
+ (di_counterreset_t) _dma_counterreset,
+
+#ifdef BCMDBG
+ (di_dump_t) dma64_dump,
+ (di_dumptx_t) dma64_dumptx,
+ (di_dumprx_t) dma64_dumprx,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+ 34
};
static di_fcn_t dma32proc = {
- (di_detach_t)_dma_detach,
- (di_txinit_t)dma32_txinit,
- (di_txreset_t)dma32_txreset,
- (di_txenabled_t)dma32_txenabled,
- (di_txsuspend_t)dma32_txsuspend,
- (di_txresume_t)dma32_txresume,
- (di_txsuspended_t)dma32_txsuspended,
- (di_txsuspendedidle_t)dma32_txsuspendedidle,
- (di_txfast_t)dma32_txfast,
- (di_txstopped_t)dma32_txstopped,
- (di_txreclaim_t)dma32_txreclaim,
- (di_getnexttxp_t)dma32_getnexttxp,
- (di_peeknexttxp_t)_dma_peeknexttxp,
- (di_txblock_t)_dma_txblock,
- (di_txunblock_t)_dma_txunblock,
- (di_txactive_t)_dma_txactive,
- (di_txrotate_t)dma32_txrotate,
-
- (di_rxinit_t)_dma_rxinit,
- (di_rxreset_t)dma32_rxreset,
- (di_rxidle_t)dma32_rxidle,
- (di_rxstopped_t)dma32_rxstopped,
- (di_rxenable_t)_dma_rxenable,
- (di_rxenabled_t)dma32_rxenabled,
- (di_rx_t)_dma_rx,
- (di_rxfill_t)_dma_rxfill,
- (di_rxreclaim_t)_dma_rxreclaim,
- (di_getnextrxp_t)_dma_getnextrxp,
-
- (di_fifoloopbackenable_t)_dma_fifoloopbackenable,
- (di_getvar_t)_dma_getvar,
- (di_counterreset_t)_dma_counterreset,
-
- NULL,
- NULL,
- NULL,
- 34
+ (di_detach_t) _dma_detach,
+ (di_txinit_t) dma32_txinit,
+ (di_txreset_t) dma32_txreset,
+ (di_txenabled_t) dma32_txenabled,
+ (di_txsuspend_t) dma32_txsuspend,
+ (di_txresume_t) dma32_txresume,
+ (di_txsuspended_t) dma32_txsuspended,
+ (di_txsuspendedidle_t) dma32_txsuspendedidle,
+ (di_txfast_t) dma32_txfast,
+ (di_txstopped_t) dma32_txstopped,
+ (di_txreclaim_t) dma32_txreclaim,
+ (di_getnexttxp_t) dma32_getnexttxp,
+ (di_peeknexttxp_t) _dma_peeknexttxp,
+ (di_txblock_t) _dma_txblock,
+ (di_txunblock_t) _dma_txunblock,
+ (di_txactive_t) _dma_txactive,
+ (di_txrotate_t) dma32_txrotate,
+
+ (di_rxinit_t) _dma_rxinit,
+ (di_rxreset_t) dma32_rxreset,
+ (di_rxidle_t) dma32_rxidle,
+ (di_rxstopped_t) dma32_rxstopped,
+ (di_rxenable_t) _dma_rxenable,
+ (di_rxenabled_t) dma32_rxenabled,
+ (di_rx_t) _dma_rx,
+ (di_rxfill_t) _dma_rxfill,
+ (di_rxreclaim_t) _dma_rxreclaim,
+ (di_getnextrxp_t) _dma_getnextrxp,
+
+ (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+ (di_getvar_t) _dma_getvar,
+ (di_counterreset_t) _dma_counterreset,
+
+#ifdef BCMDBG
+ (di_dump_t) dma32_dump,
+ (di_dumptx_t) dma32_dumptx,
+ (di_dumprx_t) dma32_dumprx,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+ 34
};
hnddma_t *
-dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx,
- uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level)
+dma_attach (osl_t * osh, char *name, sb_t * sbh, void *dmaregstx,
+ void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize,
+ uint nrxpost, uint rxoffset, uint * msg_level)
{
- dma_info_t *di;
- uint size;
+ dma_info_t *di;
+ uint size;
+
+ /* allocate private info structure */
+ if ((di = MALLOC (osh, sizeof (dma_info_t))) == NULL)
+ {
+#ifdef BCMDBG
+ printf ("dma_attach: out of memory, malloced %d bytes\n",
+ MALLOCED (osh));
+#endif
+ return (NULL);
+ }
+ bzero ((char *) di, sizeof (dma_info_t));
- /* allocate private info structure */
- if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) {
- return (NULL);
- }
- bzero((char *)di, sizeof(dma_info_t));
+ di->msg_level = msg_level ? msg_level : &dma_msg_level;
- di->msg_level = msg_level ? msg_level : &dma_msg_level;
+ /* old chips w/o sb is no longer supported */
+ ASSERT (sbh != NULL);
- /* old chips w/o sb is no longer supported */
- ASSERT(sbh != NULL);
-
- di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64);
+ di->dma64 = ((sb_coreflagshi (sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64);
#ifndef BCMDMA64
- if (di->dma64) {
- DMA_ERROR(("dma_attach: driver doesn't have the capability to support "
- "64 bits DMA\n"));
- goto fail;
- }
+ if (di->dma64)
+ {
+ DMA_ERROR (("dma_attach: driver doesn't have the capability to support "
+ "64 bits DMA\n"));
+ goto fail;
+ }
#endif
- /* check arguments */
- ASSERT(ISPOWEROF2(ntxd));
- ASSERT(ISPOWEROF2(nrxd));
- if (nrxd == 0)
- ASSERT(dmaregsrx == NULL);
- if (ntxd == 0)
- ASSERT(dmaregstx == NULL);
-
-
- /* init dma reg pointer */
- if (di->dma64) {
- ASSERT(ntxd <= D64MAXDD);
- ASSERT(nrxd <= D64MAXDD);
- di->d64txregs = (dma64regs_t *)dmaregstx;
- di->d64rxregs = (dma64regs_t *)dmaregsrx;
-
- di->dma64align = D64RINGALIGN;
- if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
- /* for smaller dd table, HW relax the alignment requirement */
- di->dma64align = D64RINGALIGN / 2;
- }
- } else {
- ASSERT(ntxd <= D32MAXDD);
- ASSERT(nrxd <= D32MAXDD);
- di->d32txregs = (dma32regs_t *)dmaregstx;
- di->d32rxregs = (dma32regs_t *)dmaregsrx;
+ /* check arguments */
+ ASSERT (ISPOWEROF2 (ntxd));
+ ASSERT (ISPOWEROF2 (nrxd));
+ if (nrxd == 0)
+ ASSERT (dmaregsrx == NULL);
+ if (ntxd == 0)
+ ASSERT (dmaregstx == NULL);
+
+
+ /* init dma reg pointer */
+ if (di->dma64)
+ {
+ ASSERT (ntxd <= D64MAXDD);
+ ASSERT (nrxd <= D64MAXDD);
+ di->d64txregs = (dma64regs_t *) dmaregstx;
+ di->d64rxregs = (dma64regs_t *) dmaregsrx;
+
+ di->dma64align = D64RINGALIGN;
+ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2))
+ {
+ /* for smaller dd table, HW relax the alignment requirement */
+ di->dma64align = D64RINGALIGN / 2;
}
-
- DMA_TRACE(("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d "
- "rxoffset %d dmaregstx %p dmaregsrx %p\n",
- name, (di->dma64 ? "DMA64" : "DMA32"), osh, ntxd, nrxd, rxbufsize,
- nrxpost, rxoffset, dmaregstx, dmaregsrx));
-
- /* make a private copy of our callers name */
- strncpy(di->name, name, MAXNAMEL);
- di->name[MAXNAMEL-1] = '\0';
-
- di->osh = osh;
- di->sbh = sbh;
-
- /* save tunables */
- di->ntxd = ntxd;
- di->nrxd = nrxd;
-
- /* the actual dma size doesn't include the extra headroom */
- if (rxbufsize > BCMEXTRAHDROOM)
- di->rxbufsize = rxbufsize - BCMEXTRAHDROOM;
- else
- di->rxbufsize = rxbufsize;
-
- di->nrxpost = nrxpost;
- di->rxoffset = rxoffset;
-
- /*
- * figure out the DMA physical address offset for dd and data
- * for old chips w/o sb, use zero
- * for new chips w sb,
- * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
- * Other bus: use zero
- * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
- */
- di->ddoffsetlow = 0;
- di->dataoffsetlow = 0;
- /* for pci bus, add offset */
- if (sbh->bustype == PCI_BUS) {
- if ((sbh->buscoretype == SB_PCIE) && di->dma64) {
- /* pcie with DMA64 */
- di->ddoffsetlow = 0;
- di->ddoffsethigh = SB_PCIE_DMA_H32;
- } else {
- /* pci(DMA32/DMA64) or pcie with DMA32 */
- di->ddoffsetlow = SB_PCI_DMA;
- di->ddoffsethigh = 0;
- }
- di->dataoffsetlow = di->ddoffsetlow;
- di->dataoffsethigh = di->ddoffsethigh;
+ }
+ else
+ {
+ ASSERT (ntxd <= D32MAXDD);
+ ASSERT (nrxd <= D32MAXDD);
+ di->d32txregs = (dma32regs_t *) dmaregstx;
+ di->d32rxregs = (dma32regs_t *) dmaregsrx;
+ }
+
+ DMA_TRACE (("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d " "rxoffset %d dmaregstx %p dmaregsrx %p\n", name, (di->dma64 ? "DMA64" : "DMA32"), osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, dmaregstx, dmaregsrx));
+
+ /* make a private copy of our callers name */
+ strncpy (di->name, name, MAXNAMEL);
+ di->name[MAXNAMEL - 1] = '\0';
+
+ di->osh = osh;
+ di->sbh = sbh;
+
+ /* save tunables */
+ di->ntxd = ntxd;
+ di->nrxd = nrxd;
+
+ /* the actual dma size doesn't include the extra headroom */
+ if (rxbufsize > BCMEXTRAHDROOM)
+ di->rxbufsize = rxbufsize - BCMEXTRAHDROOM;
+ else
+ di->rxbufsize = rxbufsize;
+
+ di->nrxpost = nrxpost;
+ di->rxoffset = rxoffset;
+
+ /*
+ * figure out the DMA physical address offset for dd and data
+ * for old chips w/o sb, use zero
+ * for new chips w sb,
+ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
+ * Other bus: use zero
+ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
+ */
+ di->ddoffsetlow = 0;
+ di->dataoffsetlow = 0;
+ /* for pci bus, add offset */
+ if (sbh->bustype == PCI_BUS)
+ {
+ if ((sbh->buscoretype == SB_PCIE) && di->dma64)
+ {
+ /* pcie with DMA64 */
+ di->ddoffsetlow = 0;
+ di->ddoffsethigh = SB_PCIE_DMA_H32;
}
+ else
+ {
+ /* pci(DMA32/DMA64) or pcie with DMA32 */
+ di->ddoffsetlow = SB_PCI_DMA;
+ di->ddoffsethigh = 0;
+ }
+ di->dataoffsetlow = di->ddoffsetlow;
+ di->dataoffsethigh = di->ddoffsethigh;
+ }
#if defined(__mips__) && defined(IL_BIGENDIAN)
- di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED;
+ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED;
#endif
- di->addrext = _dma_isaddrext(di);
-
- /* allocate tx packet pointer vector */
- if (ntxd) {
- size = ntxd * sizeof(void *);
- if ((di->txp = MALLOC(osh, size)) == NULL) {
- DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n",
- di->name, MALLOCED(osh)));
- goto fail;
- }
- bzero((char *)di->txp, size);
+ di->addrext = _dma_isaddrext (di);
+
+ /* allocate tx packet pointer vector */
+ if (ntxd)
+ {
+ size = ntxd * sizeof (void *);
+ if ((di->txp = MALLOC (osh, size)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: out of tx memory, malloced %d bytes\n",
+ di->name, MALLOCED (osh)));
+ goto fail;
}
-
- /* allocate rx packet pointer vector */
- if (nrxd) {
- size = nrxd * sizeof(void *);
- if ((di->rxp = MALLOC(osh, size)) == NULL) {
- DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n",
- di->name, MALLOCED(osh)));
- goto fail;
- }
- bzero((char *)di->rxp, size);
+ bzero ((char *) di->txp, size);
+ }
+
+ /* allocate rx packet pointer vector */
+ if (nrxd)
+ {
+ size = nrxd * sizeof (void *);
+ if ((di->rxp = MALLOC (osh, size)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: out of rx memory, malloced %d bytes\n",
+ di->name, MALLOCED (osh)));
+ goto fail;
}
-
- /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
- if (ntxd) {
- if (!_dma_alloc(di, DMA_TX))
- goto fail;
- }
-
- /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
- if (nrxd) {
- if (!_dma_alloc(di, DMA_RX))
- goto fail;
- }
-
- if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) {
- DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n",
- di->name, di->txdpa));
- goto fail;
- }
- if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) {
- DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n",
- di->name, di->rxdpa));
- goto fail;
- }
-
- DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh "
- "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow,
- di->dataoffsethigh, di->addrext));
-
- /* allocate tx packet pointer vector and DMA mapping vectors */
- if (ntxd) {
-
- size = ntxd * sizeof(osldma_t **);
- if ((di->txp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL)
- goto fail;
- bzero((char*)di->txp_dmah, size);
- }else
- di->txp_dmah = NULL;
-
- /* allocate rx packet pointer vector and DMA mapping vectors */
- if (nrxd) {
-
- size = nrxd * sizeof(osldma_t **);
- if ((di->rxp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL)
- goto fail;
- bzero((char*)di->rxp_dmah, size);
-
- } else
- di->rxp_dmah = NULL;
-
- /* initialize opsvec of function pointers */
- di->hnddma.di_fn = DMA64_ENAB(di) ? dma64proc : dma32proc;
-
- return ((hnddma_t *)di);
+ bzero ((char *) di->rxp, size);
+ }
+
+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
+ if (ntxd)
+ {
+ if (!_dma_alloc (di, DMA_TX))
+ goto fail;
+ }
+
+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
+ if (nrxd)
+ {
+ if (!_dma_alloc (di, DMA_RX))
+ goto fail;
+ }
+
+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ)
+ && !di->addrext)
+ {
+ DMA_ERROR (("%s: dma_attach: txdpa 0x%lx: addrext not supported\n",
+ di->name, di->txdpa));
+ goto fail;
+ }
+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ)
+ && !di->addrext)
+ {
+ DMA_ERROR (("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n",
+ di->name, di->rxdpa));
+ goto fail;
+ }
+
+ DMA_TRACE (("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
+
+ /* allocate tx packet pointer vector and DMA mapping vectors */
+ if (ntxd)
+ {
+
+ size = ntxd * sizeof (osldma_t **);
+ if ((di->txp_dmah = (osldma_t **) MALLOC (osh, size)) == NULL)
+ goto fail;
+ bzero ((char *) di->txp_dmah, size);
+ }
+ else
+ di->txp_dmah = NULL;
+
+ /* allocate rx packet pointer vector and DMA mapping vectors */
+ if (nrxd)
+ {
+
+ size = nrxd * sizeof (osldma_t **);
+ if ((di->rxp_dmah = (osldma_t **) MALLOC (osh, size)) == NULL)
+ goto fail;
+ bzero ((char *) di->rxp_dmah, size);
+
+ }
+ else
+ di->rxp_dmah = NULL;
+
+ /* initialize opsvec of function pointers */
+ di->hnddma.di_fn = DMA64_ENAB (di) ? dma64proc : dma32proc;
+
+ return ((hnddma_t *) di);
fail:
- _dma_detach(di);
- return (NULL);
+ _dma_detach (di);
+ return (NULL);
}
/* init the tx or rx descriptor */
static INLINE void
-dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *flags,
- uint32 bufcount)
-{
- /* dma32 uses 32 bits control to fit both flags and bufcounter */
- *flags = *flags | (bufcount & CTRL_BC_MASK);
-
- if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
- W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow));
- W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags));
- } else {
- /* address extension */
- uint32 ae;
- ASSERT(di->addrext);
- ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
- pa &= ~PCI32ADDR_HIGH;
-
- *flags |= (ae << CTRL_AE_SHIFT);
- W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow));
- W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags));
- }
+dma32_dd_upd (dma_info_t * di, dma32dd_t * ddring, ulong pa, uint outidx,
+ uint32 * flags, uint32 bufcount)
+{
+ /* dma32 uses 32 bits control to fit both flags and bufcounter */
+ *flags = *flags | (bufcount & CTRL_BC_MASK);
+
+ if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH))
+ {
+ W_SM (&ddring[outidx].addr, BUS_SWAP32 (pa + di->dataoffsetlow));
+ W_SM (&ddring[outidx].ctrl, BUS_SWAP32 (*flags));
+ }
+ else
+ {
+ /* address extension */
+ uint32 ae;
+ ASSERT (di->addrext);
+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ pa &= ~PCI32ADDR_HIGH;
+
+ *flags |= (ae << CTRL_AE_SHIFT);
+ W_SM (&ddring[outidx].addr, BUS_SWAP32 (pa + di->dataoffsetlow));
+ W_SM (&ddring[outidx].ctrl, BUS_SWAP32 (*flags));
+ }
}
static INLINE void
-dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags,
- uint32 bufcount)
-{
- uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
-
- /* PCI bus with big(>1G) physical address, use address extension */
- if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
- W_SM(&ddring[outidx].addrlow, BUS_SWAP32(pa + di->dataoffsetlow));
- W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(0 + di->dataoffsethigh));
- W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
- W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
- } else {
- /* address extension */
- uint32 ae;
- ASSERT(di->addrext);
-
- ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
- pa &= ~PCI32ADDR_HIGH;
-
- ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
- W_SM(&ddring[outidx].addrlow, BUS_SWAP32(pa + di->dataoffsetlow));
- W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(0 + di->dataoffsethigh));
- W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
- W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
- }
+dma64_dd_upd (dma_info_t * di, dma64dd_t * ddring, ulong pa, uint outidx,
+ uint32 * flags, uint32 bufcount)
+{
+ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
+
+ /* PCI bus with big(>1G) physical address, use address extension */
+ if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH))
+ {
+ W_SM (&ddring[outidx].addrlow, BUS_SWAP32 (pa + di->dataoffsetlow));
+ W_SM (&ddring[outidx].addrhigh, BUS_SWAP32 (0 + di->dataoffsethigh));
+ W_SM (&ddring[outidx].ctrl1, BUS_SWAP32 (*flags));
+ W_SM (&ddring[outidx].ctrl2, BUS_SWAP32 (ctrl2));
+ }
+ else
+ {
+ /* address extension */
+ uint32 ae;
+ ASSERT (di->addrext);
+
+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ pa &= ~PCI32ADDR_HIGH;
+
+ ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
+ W_SM (&ddring[outidx].addrlow, BUS_SWAP32 (pa + di->dataoffsetlow));
+ W_SM (&ddring[outidx].addrhigh, BUS_SWAP32 (0 + di->dataoffsethigh));
+ W_SM (&ddring[outidx].ctrl1, BUS_SWAP32 (*flags));
+ W_SM (&ddring[outidx].ctrl2, BUS_SWAP32 (ctrl2));
+ }
}
static bool
-_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs)
+_dma32_addrext (osl_t * osh, dma32regs_t * dma32regs)
{
- uint32 w;
+ uint32 w;
- OR_REG(osh, &dma32regs->control, XC_AE);
- w = R_REG(osh, &dma32regs->control);
- AND_REG(osh, &dma32regs->control, ~XC_AE);
- return ((w & XC_AE) == XC_AE);
+ OR_REG (osh, &dma32regs->control, XC_AE);
+ w = R_REG (osh, &dma32regs->control);
+ AND_REG (osh, &dma32regs->control, ~XC_AE);
+ return ((w & XC_AE) == XC_AE);
}
static bool
-_dma_alloc(dma_info_t *di, uint direction)
+_dma_alloc (dma_info_t * di, uint direction)
{
- if (DMA64_ENAB(di)) {
- return dma64_alloc(di, direction);
- } else {
- return dma32_alloc(di, direction);
- }
+ if (DMA64_ENAB (di))
+ {
+ return dma64_alloc (di, direction);
+ }
+ else
+ {
+ return dma32_alloc (di, direction);
+ }
}
/* !! may be called with core in reset */
static void
-_dma_detach(dma_info_t *di)
-{
- if (di == NULL)
- return;
-
- DMA_TRACE(("%s: dma_detach\n", di->name));
-
- /* shouldn't be here if descriptors are unreclaimed */
- ASSERT(di->txin == di->txout);
- ASSERT(di->rxin == di->rxout);
-
- /* free dma descriptor rings */
- if (DMA64_ENAB(di)) {
- if (di->txd64)
- DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->txd64 - di->txdalign),
- di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah);
- if (di->rxd64)
- DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->rxd64 - di->rxdalign),
- di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah);
- } else {
- if (di->txd32)
- DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->txd32 - di->txdalign),
- di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah);
- if (di->rxd32)
- DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->rxd32 - di->rxdalign),
- di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah);
- }
-
- /* free packet pointer vectors */
- if (di->txp)
- MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *)));
- if (di->rxp)
- MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *)));
-
- /* free tx packet DMA handles */
- if (di->txp_dmah)
- MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(osldma_t **));
-
- /* free rx packet DMA handles */
- if (di->rxp_dmah)
- MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(osldma_t **));
-
- /* free our private info structure */
- MFREE(di->osh, (void *)di, sizeof(dma_info_t));
+_dma_detach (dma_info_t * di)
+{
+ if (di == NULL)
+ return;
+
+ DMA_TRACE (("%s: dma_detach\n", di->name));
+
+ /* shouldn't be here if descriptors are unreclaimed */
+ ASSERT (di->txin == di->txout);
+ ASSERT (di->rxin == di->rxout);
+
+ /* free dma descriptor rings */
+ if (DMA64_ENAB (di))
+ {
+ if (di->txd64)
+ DMA_FREE_CONSISTENT (di->osh,
+ ((int8 *) (uintptr) di->txd64 - di->txdalign),
+ di->txdalloc, (di->txdpa - di->txdalign),
+ &di->tx_dmah);
+ if (di->rxd64)
+ DMA_FREE_CONSISTENT (di->osh,
+ ((int8 *) (uintptr) di->rxd64 - di->rxdalign),
+ di->rxdalloc, (di->rxdpa - di->rxdalign),
+ &di->rx_dmah);
+ }
+ else
+ {
+ if (di->txd32)
+ DMA_FREE_CONSISTENT (di->osh,
+ ((int8 *) (uintptr) di->txd32 - di->txdalign),
+ di->txdalloc, (di->txdpa - di->txdalign),
+ &di->tx_dmah);
+ if (di->rxd32)
+ DMA_FREE_CONSISTENT (di->osh,
+ ((int8 *) (uintptr) di->rxd32 - di->rxdalign),
+ di->rxdalloc, (di->rxdpa - di->rxdalign),
+ &di->rx_dmah);
+ }
+
+ /* free packet pointer vectors */
+ if (di->txp)
+ MFREE (di->osh, (void *) di->txp, (di->ntxd * sizeof (void *)));
+ if (di->rxp)
+ MFREE (di->osh, (void *) di->rxp, (di->nrxd * sizeof (void *)));
+
+ /* free tx packet DMA handles */
+ if (di->txp_dmah)
+ MFREE (di->osh, (void *) di->txp_dmah, di->ntxd * sizeof (osldma_t **));
+
+ /* free rx packet DMA handles */
+ if (di->rxp_dmah)
+ MFREE (di->osh, (void *) di->rxp_dmah, di->nrxd * sizeof (osldma_t **));
+
+ /* free our private info structure */
+ MFREE (di->osh, (void *) di, sizeof (dma_info_t));
}
/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */
static bool
-_dma_isaddrext(dma_info_t *di)
-{
- if (DMA64_ENAB(di)) {
- /* DMA64 supports full 32 bits or 64 bits. AE is always valid */
-
- /* not all tx or rx channel are available */
- if (di->d64txregs != NULL) {
- if (!_dma64_addrext(di->osh, di->d64txregs)) {
- DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n",
- di->name));
- ASSERT(0);
- }
- return TRUE;
- } else if (di->d64rxregs != NULL) {
- if (!_dma64_addrext(di->osh, di->d64rxregs)) {
- DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n",
- di->name));
- ASSERT(0);
- }
- return TRUE;
- }
- return FALSE;
- } else if (di->d32txregs)
- return (_dma32_addrext(di->osh, di->d32txregs));
- else if (di->d32rxregs)
- return (_dma32_addrext(di->osh, di->d32rxregs));
- return FALSE;
+_dma_isaddrext (dma_info_t * di)
+{
+ if (DMA64_ENAB (di))
+ {
+ /* DMA64 supports full 32 bits or 64 bits. AE is always valid */
+
+ /* not all tx or rx channel are available */
+ if (di->d64txregs != NULL)
+ {
+ if (!_dma64_addrext (di->osh, di->d64txregs))
+ {
+ DMA_ERROR (("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", di->name));
+ ASSERT (0);
+ }
+ return TRUE;
+ }
+ else if (di->d64rxregs != NULL)
+ {
+ if (!_dma64_addrext (di->osh, di->d64rxregs))
+ {
+ DMA_ERROR (("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", di->name));
+ ASSERT (0);
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+ else if (di->d32txregs)
+ return (_dma32_addrext (di->osh, di->d32txregs));
+ else if (di->d32rxregs)
+ return (_dma32_addrext (di->osh, di->d32rxregs));
+ return FALSE;
}
/* initialize descriptor table base address */
static void
-_dma_ddtable_init(dma_info_t *di, uint direction, ulong pa)
-{
- if (DMA64_ENAB(di)) {
-
- if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
- if (direction == DMA_TX) {
- W_REG(di->osh, &di->d64txregs->addrlow, (pa + di->ddoffsetlow));
- W_REG(di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh);
- } else {
- W_REG(di->osh, &di->d64rxregs->addrlow, (pa + di->ddoffsetlow));
- W_REG(di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh);
- }
- } else {
- /* DMA64 32bits address extension */
- uint32 ae;
- ASSERT(di->addrext);
-
- /* shift the high bit(s) from pa to ae */
- ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
- pa &= ~PCI32ADDR_HIGH;
-
- if (direction == DMA_TX) {
- W_REG(di->osh, &di->d64txregs->addrlow, (pa + di->ddoffsetlow));
- W_REG(di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh);
- SET_REG(di->osh, &di->d64txregs->control, D64_XC_AE,
- (ae << D64_XC_AE_SHIFT));
- } else {
- W_REG(di->osh, &di->d64rxregs->addrlow, (pa + di->ddoffsetlow));
- W_REG(di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh);
- SET_REG(di->osh, &di->d64rxregs->control, D64_RC_AE,
- (ae << D64_RC_AE_SHIFT));
- }
- }
-
- } else {
- if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
- if (direction == DMA_TX)
- W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow));
- else
- W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow));
- } else {
- /* dma32 address extension */
- uint32 ae;
- ASSERT(di->addrext);
-
- /* shift the high bit(s) from pa to ae */
- ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
- pa &= ~PCI32ADDR_HIGH;
-
- if (direction == DMA_TX) {
- W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow));
- SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <<XC_AE_SHIFT);
- } else {
- W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow));
- SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <<RC_AE_SHIFT);
- }
- }
+_dma_ddtable_init (dma_info_t * di, uint direction, ulong pa)
+{
+ if (DMA64_ENAB (di))
+ {
+
+ if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH))
+ {
+ if (direction == DMA_TX)
+ {
+ W_REG (di->osh, &di->d64txregs->addrlow,
+ (pa + di->ddoffsetlow));
+ W_REG (di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh);
+ }
+ else
+ {
+ W_REG (di->osh, &di->d64rxregs->addrlow,
+ (pa + di->ddoffsetlow));
+ W_REG (di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh);
+ }
+ }
+ else
+ {
+ /* DMA64 32bits address extension */
+ uint32 ae;
+ ASSERT (di->addrext);
+
+ /* shift the high bit(s) from pa to ae */
+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ pa &= ~PCI32ADDR_HIGH;
+
+ if (direction == DMA_TX)
+ {
+ W_REG (di->osh, &di->d64txregs->addrlow,
+ (pa + di->ddoffsetlow));
+ W_REG (di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh);
+ SET_REG (di->osh, &di->d64txregs->control, D64_XC_AE,
+ (ae << D64_XC_AE_SHIFT));
+ }
+ else
+ {
+ W_REG (di->osh, &di->d64rxregs->addrlow,
+ (pa + di->ddoffsetlow));
+ W_REG (di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh);
+ SET_REG (di->osh, &di->d64rxregs->control, D64_RC_AE,
+ (ae << D64_RC_AE_SHIFT));
+ }
+ }
+
+ }
+ else
+ {
+ if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH))
+ {
+ if (direction == DMA_TX)
+ W_REG (di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow));
+ else
+ W_REG (di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow));
}
+ else
+ {
+ /* dma32 address extension */
+ uint32 ae;
+ ASSERT (di->addrext);
+
+ /* shift the high bit(s) from pa to ae */
+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ pa &= ~PCI32ADDR_HIGH;
+
+ if (direction == DMA_TX)
+ {
+ W_REG (di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow));
+ SET_REG (di->osh, &di->d32txregs->control, XC_AE,
+ ae << XC_AE_SHIFT);
+ }
+ else
+ {
+ W_REG (di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow));
+ SET_REG (di->osh, &di->d32rxregs->control, RC_AE,
+ ae << RC_AE_SHIFT);
+ }
+ }
+ }
}
static void
-_dma_fifoloopbackenable(dma_info_t *di)
+_dma_fifoloopbackenable (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
- if (DMA64_ENAB(di))
- OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE);
- else
- OR_REG(di->osh, &di->d32txregs->control, XC_LE);
+ DMA_TRACE (("%s: dma_fifoloopbackenable\n", di->name));
+ if (DMA64_ENAB (di))
+ OR_REG (di->osh, &di->d64txregs->control, D64_XC_LE);
+ else
+ OR_REG (di->osh, &di->d32txregs->control, XC_LE);
}
static void
-_dma_rxinit(dma_info_t *di)
+_dma_rxinit (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_rxinit\n", di->name));
+ DMA_TRACE (("%s: dma_rxinit\n", di->name));
- if (di->nrxd == 0)
- return;
+ if (di->nrxd == 0)
+ return;
- di->rxin = di->rxout = 0;
+ di->rxin = di->rxout = 0;
- /* clear rx descriptor ring */
- if (DMA64_ENAB(di)) {
- BZERO_SM((void *)(uintptr)di->rxd64, (di->nrxd * sizeof(dma64dd_t)));
- _dma_rxenable(di);
- _dma_ddtable_init(di, DMA_RX, di->rxdpa);
- } else {
- BZERO_SM((void *)(uintptr)di->rxd32, (di->nrxd * sizeof(dma32dd_t)));
- _dma_rxenable(di);
- _dma_ddtable_init(di, DMA_RX, di->rxdpa);
- }
+ /* clear rx descriptor ring */
+ if (DMA64_ENAB (di))
+ BZERO_SM ((void *) (uintptr) di->rxd64, (di->nrxd * sizeof (dma64dd_t)));
+ else
+ BZERO_SM ((void *) (uintptr) di->rxd32, (di->nrxd * sizeof (dma32dd_t)));
+
+ _dma_rxenable (di);
+ _dma_ddtable_init (di, DMA_RX, di->rxdpa);
}
static void
-_dma_rxenable(dma_info_t *di)
+_dma_rxenable (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_rxenable\n", di->name));
-
- if (DMA64_ENAB(di))
- W_REG(di->osh, &di->d64rxregs->control,
- ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE));
- else
- W_REG(di->osh, &di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
+ DMA_TRACE (("%s: dma_rxenable\n", di->name));
+
+ if (DMA64_ENAB (di))
+ W_REG (di->osh, &di->d64rxregs->control,
+ ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE));
+ else
+ W_REG (di->osh, &di->d32rxregs->control,
+ ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
}
/* !! rx entry routine, returns a pointer to the next frame received,
* or NULL if there are no more
*/
static void *
-_dma_rx(dma_info_t *di)
-{
- void *p;
- uint len;
- int skiplen = 0;
-
- while ((p = _dma_getnextrxp(di, FALSE))) {
- /* skip giant packets which span multiple rx descriptors */
- if (skiplen > 0) {
- skiplen -= di->rxbufsize;
- if (skiplen < 0)
- skiplen = 0;
- PKTFREE(di->osh, p, FALSE);
- continue;
- }
-
- len = ltoh16(*(uint16*)(PKTDATA(di->osh, p)));
- DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
-
- /* bad frame length check */
- if (len > (di->rxbufsize - di->rxoffset)) {
- DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len));
- if (len > 0)
- skiplen = len - (di->rxbufsize - di->rxoffset);
- PKTFREE(di->osh, p, FALSE);
- di->hnddma.rxgiants++;
- continue;
- }
-
- /* set actual length */
- PKTSETLEN(di->osh, p, (di->rxoffset + len));
-
- break;
+_dma_rx (dma_info_t * di)
+{
+ void *p;
+ uint len;
+ int skiplen = 0;
+
+ while ((p = _dma_getnextrxp (di, FALSE)))
+ {
+ /* skip giant packets which span multiple rx descriptors */
+ if (skiplen > 0)
+ {
+ skiplen -= di->rxbufsize;
+ if (skiplen < 0)
+ skiplen = 0;
+ PKTFREE (di->osh, p, FALSE);
+ continue;
+ }
+
+ len = ltoh16 (*(uint16 *) (PKTDATA (di->osh, p)));
+ DMA_TRACE (("%s: dma_rx len %d\n", di->name, len));
+
+ /* bad frame length check */
+ if (len > (di->rxbufsize - di->rxoffset))
+ {
+ DMA_ERROR (("%s: dma_rx: bad frame length (%d)\n", di->name, len));
+ if (len > 0)
+ skiplen = len - (di->rxbufsize - di->rxoffset);
+ PKTFREE (di->osh, p, FALSE);
+ di->hnddma.rxgiants++;
+ continue;
}
- return (p);
+ /* set actual length */
+ PKTSETLEN (di->osh, p, (di->rxoffset + len));
+
+ break;
+ }
+
+ return (p);
}
/* post receive buffers */
static void
-_dma_rxfill(dma_info_t *di)
-{
- void *p;
- uint rxin, rxout;
- uint32 flags = 0;
- uint n;
- uint i;
- uint32 pa;
- uint extra_offset = 0;
-
- /*
- * Determine how many receive buffers we're lacking
- * from the full complement, allocate, initialize,
- * and post them, then update the chip rx lastdscr.
- */
-
- rxin = di->rxin;
- rxout = di->rxout;
-
- n = di->nrxpost - NRXDACTIVE(rxin, rxout);
-
- DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
-
- if (di->rxbufsize > BCMEXTRAHDROOM)
- extra_offset = BCMEXTRAHDROOM;
-
- for (i = 0; i < n; i++) {
- /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
- size to be allocated
- */
- if ((p = PKTGET(di->osh, di->rxbufsize + extra_offset,
- FALSE)) == NULL) {
- DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
- di->hnddma.rxnobuf++;
- break;
- }
- /* reserve an extra headroom, if applicable */
- if (extra_offset)
- PKTPULL(di->osh, p, extra_offset);
-
- /* Do a cached write instead of uncached write since DMA_MAP
- * will flush the cache.
- */
- *(uint32*)(PKTDATA(di->osh, p)) = 0;
-
- pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p),
- di->rxbufsize, DMA_RX, p);
-
- ASSERT(ISALIGNED(pa, 4));
-
- /* save the free packet pointer */
- ASSERT(di->rxp[rxout] == NULL);
- di->rxp[rxout] = p;
-
- /* reset flags for each descriptor */
- flags = 0;
- if (DMA64_ENAB(di)) {
- if (rxout == (di->nrxd - 1))
- flags = D64_CTRL1_EOT;
-
- dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, di->rxbufsize);
- } else {
- if (rxout == (di->nrxd - 1))
- flags = CTRL_EOT;
-
- dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize);
- }
- rxout = NEXTRXD(rxout);
+_dma_rxfill (dma_info_t * di)
+{
+ void *p;
+ uint rxin, rxout;
+ uint32 flags = 0;
+ uint n;
+ uint i;
+ uint32 pa;
+ uint extra_offset = 0;
+
+ /*
+ * Determine how many receive buffers we're lacking
+ * from the full complement, allocate, initialize,
+ * and post them, then update the chip rx lastdscr.
+ */
+
+ rxin = di->rxin;
+ rxout = di->rxout;
+
+ n = di->nrxpost - NRXDACTIVE (rxin, rxout);
+
+ DMA_TRACE (("%s: dma_rxfill: post %d\n", di->name, n));
+
+ if (di->rxbufsize > BCMEXTRAHDROOM)
+ extra_offset = BCMEXTRAHDROOM;
+
+ for (i = 0; i < n; i++)
+ {
+ /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
+ size to be allocated
+ */
+ if ((p = PKTGET (di->osh, di->rxbufsize + extra_offset, FALSE)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_rxfill: out of rxbufs\n", di->name));
+ di->hnddma.rxnobuf++;
+ break;
}
+ /* reserve an extra headroom, if applicable */
+ if (extra_offset)
+ PKTPULL (di->osh, p, extra_offset);
- di->rxout = rxout;
+ /* Do a cached write instead of uncached write since DMA_MAP
+ * will flush the cache.
+ */
+ *(uint32 *) (PKTDATA (di->osh, p)) = 0;
- /* update the chip lastdscr pointer */
- if (DMA64_ENAB(di)) {
- W_REG(di->osh, &di->d64rxregs->ptr, I2B(rxout, dma64dd_t));
- } else {
- W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t));
- }
-}
+ pa = (uint32) DMA_MAP (di->osh, PKTDATA (di->osh, p),
+ di->rxbufsize, DMA_RX, p, &di->rxp_dmah[rxout]);
-/* like getnexttxp but no reclaim */
-static void *
-_dma_peeknexttxp(dma_info_t *di)
-{
- uint end, i;
+ ASSERT (ISALIGNED (pa, 4));
+
+ /* save the free packet pointer */
+ ASSERT (di->rxp[rxout] == NULL);
+ di->rxp[rxout] = p;
- if (di->ntxd == 0)
- return (NULL);
+ /* reset flags for each descriptor */
+ flags = 0;
+ if (DMA64_ENAB (di))
+ {
+ if (rxout == (di->nrxd - 1))
+ flags = D64_CTRL1_EOT;
- if (DMA64_ENAB(di)) {
- end = B2I(R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
- } else {
- end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
+ dma64_dd_upd (di, di->rxd64, pa, rxout, &flags, di->rxbufsize);
}
+ else
+ {
+ if (rxout == (di->nrxd - 1))
+ flags = CTRL_EOT;
- for (i = di->txin; i != end; i = NEXTTXD(i))
- if (di->txp[i])
- return (di->txp[i]);
+ dma32_dd_upd (di, di->rxd32, pa, rxout, &flags, di->rxbufsize);
+ }
+ rxout = NEXTRXD (rxout);
+ }
+
+ di->rxout = rxout;
+
+ /* update the chip lastdscr pointer */
+ if (DMA64_ENAB (di))
+ {
+ W_REG (di->osh, &di->d64rxregs->ptr, I2B (rxout, dma64dd_t));
+ }
+ else
+ {
+ W_REG (di->osh, &di->d32rxregs->ptr, I2B (rxout, dma32dd_t));
+ }
+}
- return (NULL);
+/* like getnexttxp but no reclaim */
+static void *
+_dma_peeknexttxp (dma_info_t * di)
+{
+ uint end, i;
+
+ if (di->ntxd == 0)
+ return (NULL);
+
+ if (DMA64_ENAB (di))
+ {
+ end =
+ B2I (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK,
+ dma64dd_t);
+ }
+ else
+ {
+ end =
+ B2I (R_REG (di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
+ }
+
+ for (i = di->txin; i != end; i = NEXTTXD (i))
+ if (di->txp[i])
+ return (di->txp[i]);
+
+ return (NULL);
}
static void
-_dma_rxreclaim(dma_info_t *di)
+_dma_rxreclaim (dma_info_t * di)
{
- void *p;
+ void *p;
- /* "unused local" warning suppression for OSLs that
- * define PKTFREE() without using the di->osh arg
- */
- di = di;
+ /* "unused local" warning suppression for OSLs that
+ * define PKTFREE() without using the di->osh arg
+ */
+ di = di;
- DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
+ DMA_TRACE (("%s: dma_rxreclaim\n", di->name));
- while ((p = _dma_getnextrxp(di, TRUE)))
- PKTFREE(di->osh, p, FALSE);
+ while ((p = _dma_getnextrxp (di, TRUE)))
+ PKTFREE (di->osh, p, FALSE);
}
static void *
-_dma_getnextrxp(dma_info_t *di, bool forceall)
+_dma_getnextrxp (dma_info_t * di, bool forceall)
{
- if (di->nrxd == 0)
- return (NULL);
-
- if (DMA64_ENAB(di)) {
- return dma64_getnextrxp(di, forceall);
- } else {
- return dma32_getnextrxp(di, forceall);
- }
+ if (di->nrxd == 0)
+ return (NULL);
+
+ if (DMA64_ENAB (di))
+ {
+ return dma64_getnextrxp (di, forceall);
+ }
+ else
+ {
+ return dma32_getnextrxp (di, forceall);
+ }
}
static void
-_dma_txblock(dma_info_t *di)
+_dma_txblock (dma_info_t * di)
{
- di->hnddma.txavail = 0;
+ di->hnddma.txavail = 0;
}
static void
-_dma_txunblock(dma_info_t *di)
+_dma_txunblock (dma_info_t * di)
{
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
}
static uint
-_dma_txactive(dma_info_t *di)
+_dma_txactive (dma_info_t * di)
{
- return (NTXDACTIVE(di->txin, di->txout));
+ return (NTXDACTIVE (di->txin, di->txout));
}
static void
-_dma_counterreset(dma_info_t *di)
+_dma_counterreset (dma_info_t * di)
{
- /* reset all software counter */
- di->hnddma.rxgiants = 0;
- di->hnddma.rxnobuf = 0;
- di->hnddma.txnobuf = 0;
+ /* reset all software counter */
+ di->hnddma.rxgiants = 0;
+ di->hnddma.rxnobuf = 0;
+ di->hnddma.txnobuf = 0;
}
/* get the address of the var in order to change later */
static uintptr
-_dma_getvar(dma_info_t *di, const char *name)
+_dma_getvar (dma_info_t * di, const char *name)
{
- if (!strcmp(name, "&txavail"))
- return ((uintptr) &(di->hnddma.txavail));
- else {
- ASSERT(0);
- }
- return (0);
+ if (!strcmp (name, "&txavail"))
+ return ((uintptr) & (di->hnddma.txavail));
+ else
+ {
+ ASSERT (0);
+ }
+ return (0);
}
void
-dma_txpioloopback(osl_t *osh, dma32regs_t *regs)
+dma_txpioloopback (osl_t * osh, dma32regs_t * regs)
{
- OR_REG(osh, ®s->control, XC_LE);
+ OR_REG (osh, ®s->control, XC_LE);
}
+#ifdef BCMDBG
+static void
+dma32_dumpring (dma_info_t * di, struct bcmstrbuf *b, dma32dd_t * ring,
+ uint start, uint end, uint max_num)
+{
+ uint i;
+
+ for (i = start; i != end; i = XXD ((i + 1), max_num))
+ {
+ /* in the format of high->low 8 bytes */
+ bcm_bprintf (b, "ring index %d: 0x%x %x\n", i, ring[i].addr,
+ ring[i].ctrl);
+ }
+}
+
+static void
+dma32_dumptx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ if (di->ntxd == 0)
+ return;
+
+ bcm_bprintf (b, "DMA32: txd32 %p txdpa 0x%lx txp %p txin %d txout %d "
+ "txavail %d\n", di->txd32, di->txdpa, di->txp, di->txin,
+ di->txout, di->hnddma.txavail);
+
+ bcm_bprintf (b, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n",
+ R_REG (di->osh, &di->d32txregs->control),
+ R_REG (di->osh, &di->d32txregs->addr),
+ R_REG (di->osh, &di->d32txregs->ptr),
+ R_REG (di->osh, &di->d32txregs->status));
+
+ if (dumpring && di->txd32)
+ dma32_dumpring (di, b, di->txd32, di->txin, di->txout, di->ntxd);
+}
+
+static void
+dma32_dumprx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ if (di->nrxd == 0)
+ return;
+
+ bcm_bprintf (b, "DMA32: rxd32 %p rxdpa 0x%lx rxp %p rxin %d rxout %d\n",
+ di->rxd32, di->rxdpa, di->rxp, di->rxin, di->rxout);
+
+ bcm_bprintf (b, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n",
+ R_REG (di->osh, &di->d32rxregs->control),
+ R_REG (di->osh, &di->d32rxregs->addr),
+ R_REG (di->osh, &di->d32rxregs->ptr),
+ R_REG (di->osh, &di->d32rxregs->status));
+ if (di->rxd32 && dumpring)
+ dma32_dumpring (di, b, di->rxd32, di->rxin, di->rxout, di->nrxd);
+}
+
+static void
+dma32_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ dma32_dumptx (di, b, dumpring);
+ dma32_dumprx (di, b, dumpring);
+}
+
+static void
+dma64_dumpring (dma_info_t * di, struct bcmstrbuf *b, dma64dd_t * ring,
+ uint start, uint end, uint max_num)
+{
+ uint i;
+
+ for (i = start; i != end; i = XXD ((i + 1), max_num))
+ {
+ /* in the format of high->low 16 bytes */
+ bcm_bprintf (b, "ring index %d: 0x%x %x %x %x\n",
+ i, ring[i].addrhigh, ring[i].addrlow, ring[i].ctrl2,
+ ring[i].ctrl1);
+ }
+}
+
+static void
+dma64_dumptx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ if (di->ntxd == 0)
+ return;
+
+ bcm_bprintf (b, "DMA64: txd64 %p txdpa 0x%lx txp %p txin %d txout %d "
+ "txavail %d\n", di->txd64, di->txdpa, di->txp, di->txin,
+ di->txout, di->hnddma.txavail);
+
+ bcm_bprintf (b, "xmtcontrol 0x%x xmtaddrlow 0x%x xmtaddrhigh 0x%x "
+ "xmtptr 0x%x xmtstatus0 0x%x xmtstatus1 0x%x\n",
+ R_REG (di->osh, &di->d64txregs->control),
+ R_REG (di->osh, &di->d64txregs->addrlow),
+ R_REG (di->osh, &di->d64txregs->addrhigh),
+ R_REG (di->osh, &di->d64txregs->ptr),
+ R_REG (di->osh, &di->d64txregs->status0),
+ R_REG (di->osh, &di->d64txregs->status1));
+
+ if (dumpring && di->txd64)
+ {
+ dma64_dumpring (di, b, di->txd64, di->txin, di->txout, di->ntxd);
+ }
+}
+
+static void
+dma64_dumprx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ if (di->nrxd == 0)
+ return;
+
+ bcm_bprintf (b, "DMA64: rxd64 %p rxdpa 0x%lx rxp %p rxin %d rxout %d\n",
+ di->rxd64, di->rxdpa, di->rxp, di->rxin, di->rxout);
+
+ bcm_bprintf (b, "rcvcontrol 0x%x rcvaddrlow 0x%x rcvaddrhigh 0x%x rcvptr "
+ "0x%x rcvstatus0 0x%x rcvstatus1 0x%x\n",
+ R_REG (di->osh, &di->d64rxregs->control),
+ R_REG (di->osh, &di->d64rxregs->addrlow),
+ R_REG (di->osh, &di->d64rxregs->addrhigh),
+ R_REG (di->osh, &di->d64rxregs->ptr),
+ R_REG (di->osh, &di->d64rxregs->status0),
+ R_REG (di->osh, &di->d64rxregs->status1));
+ if (di->rxd64 && dumpring)
+ {
+ dma64_dumpring (di, b, di->rxd64, di->rxin, di->rxout, di->nrxd);
+ }
+}
+
+static void
+dma64_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring)
+{
+ dma64_dumptx (di, b, dumpring);
+ dma64_dumprx (di, b, dumpring);
+}
+
+#endif /* BCMDBG */
/* 32 bits DMA functions */
static void
-dma32_txinit(dma_info_t *di)
+dma32_txinit (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txinit\n", di->name));
+ DMA_TRACE (("%s: dma_txinit\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- di->txin = di->txout = 0;
- di->hnddma.txavail = di->ntxd - 1;
+ di->txin = di->txout = 0;
+ di->hnddma.txavail = di->ntxd - 1;
- /* clear tx descriptor ring */
- BZERO_SM((void *)(uintptr)di->txd32, (di->ntxd * sizeof(dma32dd_t)));
- W_REG(di->osh, &di->d32txregs->control, XC_XE);
- _dma_ddtable_init(di, DMA_TX, di->txdpa);
+ /* clear tx descriptor ring */
+ BZERO_SM ((void *) (uintptr) di->txd32, (di->ntxd * sizeof (dma32dd_t)));
+ W_REG (di->osh, &di->d32txregs->control, XC_XE);
+ _dma_ddtable_init (di, DMA_TX, di->txdpa);
}
static bool
-dma32_txenabled(dma_info_t *di)
+dma32_txenabled (dma_info_t * di)
{
- uint32 xc;
+ uint32 xc;
- /* If the chip is dead, it is not enabled :-) */
- xc = R_REG(di->osh, &di->d32txregs->control);
- return ((xc != 0xffffffff) && (xc & XC_XE));
+ /* If the chip is dead, it is not enabled :-) */
+ xc = R_REG (di->osh, &di->d32txregs->control);
+ return ((xc != 0xffffffff) && (xc & XC_XE));
}
static void
-dma32_txsuspend(dma_info_t *di)
+dma32_txsuspend (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+ DMA_TRACE (("%s: dma_txsuspend\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- OR_REG(di->osh, &di->d32txregs->control, XC_SE);
+ OR_REG (di->osh, &di->d32txregs->control, XC_SE);
}
static void
-dma32_txresume(dma_info_t *di)
+dma32_txresume (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txresume\n", di->name));
+ DMA_TRACE (("%s: dma_txresume\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- AND_REG(di->osh, &di->d32txregs->control, ~XC_SE);
+ AND_REG (di->osh, &di->d32txregs->control, ~XC_SE);
}
static bool
-dma32_txsuspended(dma_info_t *di)
+dma32_txsuspended (dma_info_t * di)
{
- return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE);
+ return (di->ntxd == 0)
+ || ((R_REG (di->osh, &di->d32txregs->control) & XC_SE) == XC_SE);
}
static void
-dma32_txreclaim(dma_info_t *di, bool forceall)
+dma32_txreclaim (dma_info_t * di, bool forceall)
{
- void *p;
+ void *p;
- DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
+ DMA_TRACE (("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
- while ((p = dma32_getnexttxp(di, forceall)))
- PKTFREE(di->osh, p, TRUE);
+ while ((p = dma32_getnexttxp (di, forceall)))
+ PKTFREE (di->osh, p, TRUE);
}
static bool
-dma32_txstopped(dma_info_t *di)
+dma32_txstopped (dma_info_t * di)
{
- return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED);
+ return ((R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK) ==
+ XS_XS_STOPPED);
}
static bool
-dma32_rxstopped(dma_info_t *di)
+dma32_rxstopped (dma_info_t * di)
{
- return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED);
+ return ((R_REG (di->osh, &di->d32rxregs->status) & RS_RS_MASK) ==
+ RS_RS_STOPPED);
}
static bool
-dma32_alloc(dma_info_t *di, uint direction)
-{
- uint size;
- uint ddlen;
- void *va;
-
- ddlen = sizeof(dma32dd_t);
-
- size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
-
- if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN))
- size += D32RINGALIGN;
-
-
- if (direction == DMA_TX) {
- if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) {
- DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
- di->name));
- return FALSE;
- }
-
- di->txd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN);
- di->txdalign = (uint)((int8*)(uintptr)di->txd32 - (int8*)va);
- di->txdpa += di->txdalign;
- di->txdalloc = size;
- ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN));
- } else {
- if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) {
- DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
- di->name));
- return FALSE;
- }
- di->rxd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN);
- di->rxdalign = (uint)((int8*)(uintptr)di->rxd32 - (int8*)va);
- di->rxdpa += di->rxdalign;
- di->rxdalloc = size;
- ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN));
+dma32_alloc (dma_info_t * di, uint direction)
+{
+ uint size;
+ uint ddlen;
+ void *va;
+
+ ddlen = sizeof (dma32dd_t);
+
+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+
+ if (!ISALIGNED (DMA_CONSISTENT_ALIGN, D32RINGALIGN))
+ size += D32RINGALIGN;
+
+
+ if (direction == DMA_TX)
+ {
+ if ((va =
+ DMA_ALLOC_CONSISTENT (di->osh, size, &di->txdpa,
+ &di->tx_dmah)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
+ di->name));
+ return FALSE;
}
- return TRUE;
+ di->txd32 = (dma32dd_t *) ROUNDUP ((uintptr) va, D32RINGALIGN);
+ di->txdalign = (uint) ((int8 *) (uintptr) di->txd32 - (int8 *) va);
+ di->txdpa += di->txdalign;
+ di->txdalloc = size;
+ ASSERT (ISALIGNED ((uintptr) di->txd32, D32RINGALIGN));
+ }
+ else
+ {
+ if ((va =
+ DMA_ALLOC_CONSISTENT (di->osh, size, &di->rxdpa,
+ &di->rx_dmah)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
+ di->name));
+ return FALSE;
+ }
+ di->rxd32 = (dma32dd_t *) ROUNDUP ((uintptr) va, D32RINGALIGN);
+ di->rxdalign = (uint) ((int8 *) (uintptr) di->rxd32 - (int8 *) va);
+ di->rxdpa += di->rxdalign;
+ di->rxdalloc = size;
+ ASSERT (ISALIGNED ((uintptr) di->rxd32, D32RINGALIGN));
+ }
+
+ return TRUE;
}
static bool
-dma32_txreset(dma_info_t *di)
+dma32_txreset (dma_info_t * di)
{
- uint32 status;
+ uint32 status;
- if (di->ntxd == 0)
- return TRUE;
+ if (di->ntxd == 0)
+ return TRUE;
- /* suspend tx DMA first */
- W_REG(di->osh, &di->d32txregs->control, XC_SE);
- SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK))
- != XS_XS_DISABLED) &&
- (status != XS_XS_IDLE) &&
- (status != XS_XS_STOPPED),
- (10000));
+ /* suspend tx DMA first */
+ W_REG (di->osh, &di->d32txregs->control, XC_SE);
+ SPINWAIT (((status = (R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK))
+ != XS_XS_DISABLED) &&
+ (status != XS_XS_IDLE) && (status != XS_XS_STOPPED), (10000));
- W_REG(di->osh, &di->d32txregs->control, 0);
- SPINWAIT(((status = (R_REG(di->osh,
- &di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED),
- 10000);
+ W_REG (di->osh, &di->d32txregs->control, 0);
+ SPINWAIT (((status = (R_REG (di->osh,
+ &di->d32txregs->status) & XS_XS_MASK)) !=
+ XS_XS_DISABLED), 10000);
- /* wait for the last transaction to complete */
- OSL_DELAY(300);
+ /* wait for the last transaction to complete */
+ OSL_DELAY (300);
- return (status == XS_XS_DISABLED);
+ return (status == XS_XS_DISABLED);
}
static bool
-dma32_rxidle(dma_info_t *di)
+dma32_rxidle (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_rxidle\n", di->name));
+ DMA_TRACE (("%s: dma_rxidle\n", di->name));
- if (di->nrxd == 0)
- return TRUE;
+ if (di->nrxd == 0)
+ return TRUE;
- return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) ==
- R_REG(di->osh, &di->d32rxregs->ptr));
+ return ((R_REG (di->osh, &di->d32rxregs->status) & RS_CD_MASK) ==
+ R_REG (di->osh, &di->d32rxregs->ptr));
}
static bool
-dma32_rxreset(dma_info_t *di)
+dma32_rxreset (dma_info_t * di)
{
- uint32 status;
+ uint32 status;
- if (di->nrxd == 0)
- return TRUE;
+ if (di->nrxd == 0)
+ return TRUE;
- W_REG(di->osh, &di->d32rxregs->control, 0);
- SPINWAIT(((status = (R_REG(di->osh,
- &di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED),
- 10000);
+ W_REG (di->osh, &di->d32rxregs->control, 0);
+ SPINWAIT (((status = (R_REG (di->osh,
+ &di->d32rxregs->status) & RS_RS_MASK)) !=
+ RS_RS_DISABLED), 10000);
- return (status == RS_RS_DISABLED);
+ return (status == RS_RS_DISABLED);
}
static bool
-dma32_rxenabled(dma_info_t *di)
+dma32_rxenabled (dma_info_t * di)
{
- uint32 rc;
+ uint32 rc;
- rc = R_REG(di->osh, &di->d32rxregs->control);
- return ((rc != 0xffffffff) && (rc & RC_RE));
+ rc = R_REG (di->osh, &di->d32rxregs->control);
+ return ((rc != 0xffffffff) && (rc & RC_RE));
}
static bool
-dma32_txsuspendedidle(dma_info_t *di)
+dma32_txsuspendedidle (dma_info_t * di)
{
- if (di->ntxd == 0)
- return TRUE;
+ if (di->ntxd == 0)
+ return TRUE;
- if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE))
- return 0;
+ if (!(R_REG (di->osh, &di->d32txregs->control) & XC_SE))
+ return 0;
- if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
- return 0;
+ if ((R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
+ return 0;
- OSL_DELAY(2);
- return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE);
+ OSL_DELAY (2);
+ return ((R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK) ==
+ XS_XS_IDLE);
}
/* !! tx entry routine
* dma buffers can cross 4 Kbyte page boundaries.
*/
static int
-dma32_txfast(dma_info_t *di, void *p0, bool commit)
-{
- void *p, *next;
- uchar *data;
- uint len;
- uint txout;
- uint32 flags = 0;
- uint32 pa;
-
- DMA_TRACE(("%s: dma_txfast\n", di->name));
-
- txout = di->txout;
-
- /*
- * Walk the chain of packet buffers
- * allocating and initializing transmit descriptor entries.
- */
- for (p = p0; p; p = next) {
- data = PKTDATA(di->osh, p);
- len = PKTLEN(di->osh, p);
- next = PKTNEXT(di->osh, p);
-
- /* return nonzero if out of tx descriptors */
- if (NEXTTXD(txout) == di->txin)
- goto outoftxd;
-
- if (len == 0)
- continue;
-
- /* get physical address of buffer start */
- pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p);
-
- flags = 0;
- if (p == p0)
- flags |= CTRL_SOF;
- if (next == NULL)
- flags |= (CTRL_IOC | CTRL_EOF);
- if (txout == (di->ntxd - 1))
- flags |= CTRL_EOT;
-
- dma32_dd_upd(di, di->txd32, pa, txout, &flags, len);
- ASSERT(di->txp[txout] == NULL);
-
- txout = NEXTTXD(txout);
- }
+dma32_txfast (dma_info_t * di, void *p0, bool commit)
+{
+ void *p, *next;
+ uchar *data;
+ uint len;
+ uint txout;
+ uint32 flags = 0;
+ uint32 pa;
+
+ DMA_TRACE (("%s: dma_txfast\n", di->name));
+
+ txout = di->txout;
+
+ /*
+ * Walk the chain of packet buffers
+ * allocating and initializing transmit descriptor entries.
+ */
+ for (p = p0; p; p = next)
+ {
+ data = PKTDATA (di->osh, p);
+ len = PKTLEN (di->osh, p);
+ next = PKTNEXT (di->osh, p);
+
+ /* return nonzero if out of tx descriptors */
+ if (NEXTTXD (txout) == di->txin)
+ goto outoftxd;
+
+ if (len == 0)
+ continue;
+
+ /* get physical address of buffer start */
+ pa =
+ (uint32) DMA_MAP (di->osh, data, len, DMA_TX, p,
+ &di->txp_dmah[txout]);
+
+ flags = 0;
+ if (p == p0)
+ flags |= CTRL_SOF;
+ if (next == NULL)
+ flags |= (CTRL_IOC | CTRL_EOF);
+ if (txout == (di->ntxd - 1))
+ flags |= CTRL_EOT;
- /* if last txd eof not set, fix it */
- if (!(flags & CTRL_EOF))
- W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF));
+ dma32_dd_upd (di, di->txd32, pa, txout, &flags, len);
+ ASSERT (di->txp[txout] == NULL);
- /* save the packet */
- di->txp[PREVTXD(txout)] = p0;
+ txout = NEXTTXD (txout);
+ }
- /* bump the tx descriptor index */
- di->txout = txout;
+ /* if last txd eof not set, fix it */
+ if (!(flags & CTRL_EOF))
+ W_SM (&di->txd32[PREVTXD (txout)].ctrl,
+ BUS_SWAP32 (flags | CTRL_IOC | CTRL_EOF));
- /* kick the chip */
- if (commit)
- W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t));
+ /* save the packet */
+ di->txp[PREVTXD (txout)] = p0;
- /* tx flow control */
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ /* bump the tx descriptor index */
+ di->txout = txout;
- return (0);
+ /* kick the chip */
+ if (commit)
+ W_REG (di->osh, &di->d32txregs->ptr, I2B (txout, dma32dd_t));
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
+
+ return (0);
outoftxd:
- DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
- PKTFREE(di->osh, p0, TRUE);
- di->hnddma.txavail = 0;
- di->hnddma.txnobuf++;
- return (-1);
+ DMA_ERROR (("%s: dma_txfast: out of txds\n", di->name));
+ PKTFREE (di->osh, p0, TRUE);
+ di->hnddma.txavail = 0;
+ di->hnddma.txnobuf++;
+ return (-1);
}
/*
* regardless of the value of the hardware "curr" pointer.
*/
static void *
-dma32_getnexttxp(dma_info_t *di, bool forceall)
+dma32_getnexttxp (dma_info_t * di, bool forceall)
{
- uint start, end, i;
- void *txp;
+ uint start, end, i;
+ void *txp;
- DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
+ DMA_TRACE (("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
- if (di->ntxd == 0)
- return (NULL);
+ if (di->ntxd == 0)
+ return (NULL);
- txp = NULL;
+ txp = NULL;
- start = di->txin;
- if (forceall)
- end = di->txout;
- else
- end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
+ start = di->txin;
+ if (forceall)
+ end = di->txout;
+ else
+ end =
+ B2I (R_REG (di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
- if ((start == 0) && (end > di->txout))
- goto bogus;
+ if ((start == 0) && (end > di->txout))
+ goto bogus;
- for (i = start; i != end && !txp; i = NEXTTXD(i)) {
- DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow),
- (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK),
- DMA_TX, di->txp[i]);
+ for (i = start; i != end && !txp; i = NEXTTXD (i))
+ {
+ DMA_UNMAP (di->osh,
+ (BUS_SWAP32 (R_SM (&di->txd32[i].addr)) - di->dataoffsetlow),
+ (BUS_SWAP32 (R_SM (&di->txd32[i].ctrl)) & CTRL_BC_MASK),
+ DMA_TX, di->txp[i], &di->txp_dmah[i]);
- W_SM(&di->txd32[i].addr, 0xdeadbeef);
- txp = di->txp[i];
- di->txp[i] = NULL;
- }
+ W_SM (&di->txd32[i].addr, 0xdeadbeef);
+ txp = di->txp[i];
+ di->txp[i] = NULL;
+ }
- di->txin = i;
+ di->txin = i;
- /* tx flow control */
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
- return (txp);
+ return (txp);
bogus:
/*
DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
start, end, di->txout, forceall));
*/
- return (NULL);
+ return (NULL);
}
static void *
-dma32_getnextrxp(dma_info_t *di, bool forceall)
+dma32_getnextrxp (dma_info_t * di, bool forceall)
{
- uint i;
- void *rxp;
+ uint i;
+ void *rxp;
- /* if forcing, dma engine must be disabled */
- ASSERT(!forceall || !dma32_rxenabled(di));
+ /* if forcing, dma engine must be disabled */
+ ASSERT (!forceall || !dma32_rxenabled (di));
- i = di->rxin;
+ i = di->rxin;
- /* return if no packets posted */
- if (i == di->rxout)
- return (NULL);
+ /* return if no packets posted */
+ if (i == di->rxout)
+ return (NULL);
- /* ignore curr if forceall */
- if (!forceall && (i == B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t)))
- return (NULL);
+ /* ignore curr if forceall */
+ if (!forceall
+ && (i ==
+ B2I (R_REG (di->osh, &di->d32rxregs->status) & RS_CD_MASK,
+ dma32dd_t)))
+ return (NULL);
- /* get the packet pointer that corresponds to the rx descriptor */
- rxp = di->rxp[i];
- ASSERT(rxp);
- di->rxp[i] = NULL;
+ /* get the packet pointer that corresponds to the rx descriptor */
+ rxp = di->rxp[i];
+ ASSERT (rxp);
+ di->rxp[i] = NULL;
- /* clear this packet from the descriptor ring */
- DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow),
- di->rxbufsize, DMA_RX, rxp);
+ /* clear this packet from the descriptor ring */
+ DMA_UNMAP (di->osh,
+ (BUS_SWAP32 (R_SM (&di->rxd32[i].addr)) - di->dataoffsetlow),
+ di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]);
- W_SM(&di->rxd32[i].addr, 0xdeadbeef);
+ W_SM (&di->rxd32[i].addr, 0xdeadbeef);
- di->rxin = NEXTRXD(i);
+ di->rxin = NEXTRXD (i);
- return (rxp);
+ return (rxp);
}
/*
* Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
*/
static void
-dma32_txrotate(dma_info_t *di)
+dma32_txrotate (dma_info_t * di)
{
- uint ad;
- uint nactive;
- uint rot;
- uint old, new;
- uint32 w;
- uint first, last;
-
- ASSERT(dma32_txsuspendedidle(di));
-
- nactive = _dma_txactive(di);
- ad = B2I(((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t);
- rot = TXD(ad - di->txin);
-
- ASSERT(rot < di->ntxd);
-
- /* full-ring case is a lot harder - don't worry about this */
- if (rot >= (di->ntxd - nactive)) {
- DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
- return;
- }
-
- first = di->txin;
- last = PREVTXD(di->txout);
-
- /* move entries starting at last and moving backwards to first */
- for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
- new = TXD(old + rot);
-
- /*
- * Move the tx dma descriptor.
- * EOT is set only in the last entry in the ring.
- */
- w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT;
- if (new == (di->ntxd - 1))
- w |= CTRL_EOT;
- W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w));
- W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr));
-
- /* zap the old tx dma descriptor address field */
- W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef));
-
- /* move the corresponding txp[] entry */
- ASSERT(di->txp[new] == NULL);
- di->txp[new] = di->txp[old];
- di->txp[old] = NULL;
- }
-
- /* update txin and txout */
- di->txin = ad;
- di->txout = TXD(di->txout + rot);
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-
- /* kick the chip */
- W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t));
+ uint ad;
+ uint nactive;
+ uint rot;
+ uint old, new;
+ uint32 w;
+ uint first, last;
+
+ ASSERT (dma32_txsuspendedidle (di));
+
+ nactive = _dma_txactive (di);
+ ad =
+ B2I (((R_REG (di->osh, &di->d32txregs->status) & XS_AD_MASK) >>
+ XS_AD_SHIFT), dma32dd_t);
+ rot = TXD (ad - di->txin);
+
+ ASSERT (rot < di->ntxd);
+
+ /* full-ring case is a lot harder - don't worry about this */
+ if (rot >= (di->ntxd - nactive))
+ {
+ DMA_ERROR (("%s: dma_txrotate: ring full - punt\n", di->name));
+ return;
+ }
+
+ first = di->txin;
+ last = PREVTXD (di->txout);
+
+ /* move entries starting at last and moving backwards to first */
+ for (old = last; old != PREVTXD (first); old = PREVTXD (old))
+ {
+ new = TXD (old + rot);
+
+ /*
+ * Move the tx dma descriptor.
+ * EOT is set only in the last entry in the ring.
+ */
+ w = BUS_SWAP32 (R_SM (&di->txd32[old].ctrl)) & ~CTRL_EOT;
+ if (new == (di->ntxd - 1))
+ w |= CTRL_EOT;
+ W_SM (&di->txd32[new].ctrl, BUS_SWAP32 (w));
+ W_SM (&di->txd32[new].addr, R_SM (&di->txd32[old].addr));
+
+ /* zap the old tx dma descriptor address field */
+ W_SM (&di->txd32[old].addr, BUS_SWAP32 (0xdeadbeef));
+
+ /* move the corresponding txp[] entry */
+ ASSERT (di->txp[new] == NULL);
+ di->txp[new] = di->txp[old];
+ di->txp[old] = NULL;
+ }
+
+ /* update txin and txout */
+ di->txin = ad;
+ di->txout = TXD (di->txout + rot);
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
+
+ /* kick the chip */
+ W_REG (di->osh, &di->d32txregs->ptr, I2B (di->txout, dma32dd_t));
}
/* 64 bits DMA functions */
#ifdef BCMDMA64
static void
-dma64_txinit(dma_info_t *di)
+dma64_txinit (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txinit\n", di->name));
+ DMA_TRACE (("%s: dma_txinit\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- di->txin = di->txout = 0;
- di->hnddma.txavail = di->ntxd - 1;
+ di->txin = di->txout = 0;
+ di->hnddma.txavail = di->ntxd - 1;
- /* clear tx descriptor ring */
- BZERO_SM((void *)(uintptr)di->txd64, (di->ntxd * sizeof(dma64dd_t)));
- W_REG(di->osh, &di->d64txregs->control, D64_XC_XE);
- _dma_ddtable_init(di, DMA_TX, di->txdpa);
+ /* clear tx descriptor ring */
+ BZERO_SM ((void *) (uintptr) di->txd64, (di->ntxd * sizeof (dma64dd_t)));
+ W_REG (di->osh, &di->d64txregs->control, D64_XC_XE);
+ _dma_ddtable_init (di, DMA_TX, di->txdpa);
}
static bool
-dma64_txenabled(dma_info_t *di)
+dma64_txenabled (dma_info_t * di)
{
- uint32 xc;
+ uint32 xc;
- /* If the chip is dead, it is not enabled :-) */
- xc = R_REG(di->osh, &di->d64txregs->control);
- return ((xc != 0xffffffff) && (xc & D64_XC_XE));
+ /* If the chip is dead, it is not enabled :-) */
+ xc = R_REG (di->osh, &di->d64txregs->control);
+ return ((xc != 0xffffffff) && (xc & D64_XC_XE));
}
static void
-dma64_txsuspend(dma_info_t *di)
+dma64_txsuspend (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+ DMA_TRACE (("%s: dma_txsuspend\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE);
+ OR_REG (di->osh, &di->d64txregs->control, D64_XC_SE);
}
static void
-dma64_txresume(dma_info_t *di)
+dma64_txresume (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_txresume\n", di->name));
+ DMA_TRACE (("%s: dma_txresume\n", di->name));
- if (di->ntxd == 0)
- return;
+ if (di->ntxd == 0)
+ return;
- AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_SE);
+ AND_REG (di->osh, &di->d64txregs->control, ~D64_XC_SE);
}
static bool
-dma64_txsuspended(dma_info_t *di)
+dma64_txsuspended (dma_info_t * di)
{
- return (di->ntxd == 0) || ((R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE)
- == D64_XC_SE);
+ return (di->ntxd == 0)
+ || ((R_REG (di->osh, &di->d64txregs->control) & D64_XC_SE) == D64_XC_SE);
}
static void
-dma64_txreclaim(dma_info_t *di, bool forceall)
+dma64_txreclaim (dma_info_t * di, bool forceall)
{
- void *p;
+ void *p;
- DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
+ DMA_TRACE (("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
- while ((p = dma64_getnexttxp(di, forceall)))
- PKTFREE(di->osh, p, TRUE);
+ while ((p = dma64_getnexttxp (di, forceall)))
+ PKTFREE (di->osh, p, TRUE);
}
static bool
-dma64_txstopped(dma_info_t *di)
+dma64_txstopped (dma_info_t * di)
{
- return ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED);
+ return ((R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+ D64_XS0_XS_STOPPED);
}
static bool
-dma64_rxstopped(dma_info_t *di)
+dma64_rxstopped (dma_info_t * di)
{
- return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED);
+ return ((R_REG (di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
+ D64_RS0_RS_STOPPED);
}
static bool
-dma64_alloc(dma_info_t *di, uint direction)
-{
- uint size;
- uint ddlen;
- uint32 alignbytes;
- void *va;
-
- ddlen = sizeof(dma64dd_t);
-
- size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
-
- alignbytes = di->dma64align;
-
- if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes))
- size += alignbytes;
-
- if (direction == DMA_TX) {
- if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) {
- DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
- di->name));
- return FALSE;
- }
-
- di->txd64 = (dma64dd_t *) ROUNDUP((uintptr)va, alignbytes);
- di->txdalign = (uint)((int8*)(uintptr)di->txd64 - (int8*)va);
- di->txdpa += di->txdalign;
- di->txdalloc = size;
- ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes));
- } else {
- if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) {
- DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
- di->name));
- return FALSE;
- }
- di->rxd64 = (dma64dd_t *) ROUNDUP((uintptr)va, alignbytes);
- di->rxdalign = (uint)((int8*)(uintptr)di->rxd64 - (int8*)va);
- di->rxdpa += di->rxdalign;
- di->rxdalloc = size;
- ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes));
+dma64_alloc (dma_info_t * di, uint direction)
+{
+ uint size;
+ uint ddlen;
+ uint32 alignbytes;
+ void *va;
+
+ ddlen = sizeof (dma64dd_t);
+
+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+
+ alignbytes = di->dma64align;
+
+ if (!ISALIGNED (DMA_CONSISTENT_ALIGN, alignbytes))
+ size += alignbytes;
+
+ if (direction == DMA_TX)
+ {
+ if ((va =
+ DMA_ALLOC_CONSISTENT (di->osh, size, &di->txdpa,
+ &di->tx_dmah)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
+ di->name));
+ return FALSE;
}
- return TRUE;
+ di->txd64 = (dma64dd_t *) ROUNDUP ((uintptr) va, alignbytes);
+ di->txdalign = (uint) ((int8 *) (uintptr) di->txd64 - (int8 *) va);
+ di->txdpa += di->txdalign;
+ di->txdalloc = size;
+ ASSERT (ISALIGNED ((uintptr) di->txd64, alignbytes));
+ }
+ else
+ {
+ if ((va =
+ DMA_ALLOC_CONSISTENT (di->osh, size, &di->rxdpa,
+ &di->rx_dmah)) == NULL)
+ {
+ DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
+ di->name));
+ return FALSE;
+ }
+ di->rxd64 = (dma64dd_t *) ROUNDUP ((uintptr) va, alignbytes);
+ di->rxdalign = (uint) ((int8 *) (uintptr) di->rxd64 - (int8 *) va);
+ di->rxdpa += di->rxdalign;
+ di->rxdalloc = size;
+ ASSERT (ISALIGNED ((uintptr) di->rxd64, alignbytes));
+ }
+
+ return TRUE;
}
static bool
-dma64_txreset(dma_info_t *di)
+dma64_txreset (dma_info_t * di)
{
- uint32 status;
+ uint32 status;
- if (di->ntxd == 0)
- return TRUE;
+ if (di->ntxd == 0)
+ return TRUE;
- /* suspend tx DMA first */
- W_REG(di->osh, &di->d64txregs->control, D64_XC_SE);
- SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) !=
- D64_XS0_XS_DISABLED) &&
- (status != D64_XS0_XS_IDLE) &&
- (status != D64_XS0_XS_STOPPED),
- 10000);
+ /* suspend tx DMA first */
+ W_REG (di->osh, &di->d64txregs->control, D64_XC_SE);
+ SPINWAIT (((status =
+ (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) !=
+ D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
+ && (status != D64_XS0_XS_STOPPED), 10000);
- W_REG(di->osh, &di->d64txregs->control, 0);
- SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) !=
- D64_XS0_XS_DISABLED),
- 10000);
+ W_REG (di->osh, &di->d64txregs->control, 0);
+ SPINWAIT (((status =
+ (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) !=
+ D64_XS0_XS_DISABLED), 10000);
- /* wait for the last transaction to complete */
- OSL_DELAY(300);
+ /* wait for the last transaction to complete */
+ OSL_DELAY (300);
- return (status == D64_XS0_XS_DISABLED);
+ return (status == D64_XS0_XS_DISABLED);
}
static bool
-dma64_rxidle(dma_info_t *di)
+dma64_rxidle (dma_info_t * di)
{
- DMA_TRACE(("%s: dma_rxidle\n", di->name));
+ DMA_TRACE (("%s: dma_rxidle\n", di->name));
- if (di->nrxd == 0)
- return TRUE;
+ if (di->nrxd == 0)
+ return TRUE;
- return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
- R_REG(di->osh, &di->d64rxregs->ptr));
+ return ((R_REG (di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
+ R_REG (di->osh, &di->d64rxregs->ptr));
}
static bool
-dma64_rxreset(dma_info_t *di)
+dma64_rxreset (dma_info_t * di)
{
- uint32 status;
+ uint32 status;
- if (di->nrxd == 0)
- return TRUE;
+ if (di->nrxd == 0)
+ return TRUE;
- W_REG(di->osh, &di->d64rxregs->control, 0);
- SPINWAIT(((status = (R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK)) !=
- D64_RS0_RS_DISABLED),
- 10000);
+ W_REG (di->osh, &di->d64rxregs->control, 0);
+ SPINWAIT (((status =
+ (R_REG (di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK)) !=
+ D64_RS0_RS_DISABLED), 10000);
- return (status == D64_RS0_RS_DISABLED);
+ return (status == D64_RS0_RS_DISABLED);
}
static bool
-dma64_rxenabled(dma_info_t *di)
+dma64_rxenabled (dma_info_t * di)
{
- uint32 rc;
+ uint32 rc;
- rc = R_REG(di->osh, &di->d64rxregs->control);
- return ((rc != 0xffffffff) && (rc & D64_RC_RE));
+ rc = R_REG (di->osh, &di->d64rxregs->control);
+ return ((rc != 0xffffffff) && (rc & D64_RC_RE));
}
static bool
-dma64_txsuspendedidle(dma_info_t *di)
+dma64_txsuspendedidle (dma_info_t * di)
{
- if (di->ntxd == 0)
- return TRUE;
+ if (di->ntxd == 0)
+ return TRUE;
- if (!(R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE))
- return 0;
+ if (!(R_REG (di->osh, &di->d64txregs->control) & D64_XC_SE))
+ return 0;
- if ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE)
- return 1;
+ if ((R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+ D64_XS0_XS_IDLE)
+ return 1;
- return 0;
+ return 0;
}
/* !! tx entry routine */
static int
-dma64_txfast(dma_info_t *di, void *p0, bool commit)
-{
- void *p, *next;
- uchar *data;
- uint len;
- uint txout;
- uint32 flags = 0;
- uint32 pa;
-
- DMA_TRACE(("%s: dma_txfast\n", di->name));
-
- txout = di->txout;
-
- /*
- * Walk the chain of packet buffers
- * allocating and initializing transmit descriptor entries.
- */
- for (p = p0; p; p = next) {
- data = PKTDATA(di->osh, p);
- len = PKTLEN(di->osh, p);
- next = PKTNEXT(di->osh, p);
-
- /* return nonzero if out of tx descriptors */
- if (NEXTTXD(txout) == di->txin)
- goto outoftxd;
-
- if (len == 0)
- continue;
-
- /* get physical address of buffer start */
- pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p);
-
- flags = 0;
- if (p == p0)
- flags |= D64_CTRL1_SOF;
- if (next == NULL)
- flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
- if (txout == (di->ntxd - 1))
- flags |= D64_CTRL1_EOT;
-
- dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
- ASSERT(di->txp[txout] == NULL);
-
- txout = NEXTTXD(txout);
- }
+dma64_txfast (dma_info_t * di, void *p0, bool commit)
+{
+ void *p, *next;
+ uchar *data;
+ uint len;
+ uint txout;
+ uint32 flags = 0;
+ uint32 pa;
- /* if last txd eof not set, fix it */
- if (!(flags & D64_CTRL1_EOF))
- W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
- BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
+ DMA_TRACE (("%s: dma_txfast\n", di->name));
- /* save the packet */
- di->txp[PREVTXD(txout)] = p0;
+ txout = di->txout;
- /* bump the tx descriptor index */
- di->txout = txout;
+ /*
+ * Walk the chain of packet buffers
+ * allocating and initializing transmit descriptor entries.
+ */
+ for (p = p0; p; p = next)
+ {
+ data = PKTDATA (di->osh, p);
+ len = PKTLEN (di->osh, p);
+ next = PKTNEXT (di->osh, p);
- /* kick the chip */
- if (commit)
- W_REG(di->osh, &di->d64txregs->ptr, I2B(txout, dma64dd_t));
+ /* return nonzero if out of tx descriptors */
+ if (NEXTTXD (txout) == di->txin)
+ goto outoftxd;
- /* tx flow control */
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ if (len == 0)
+ continue;
- return (0);
+ /* get physical address of buffer start */
+ pa =
+ (uint32) DMA_MAP (di->osh, data, len, DMA_TX, p,
+ &di->txp_dmah[txout]);
+
+ flags = 0;
+ if (p == p0)
+ flags |= D64_CTRL1_SOF;
+ if (next == NULL)
+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
+ if (txout == (di->ntxd - 1))
+ flags |= D64_CTRL1_EOT;
+
+ dma64_dd_upd (di, di->txd64, pa, txout, &flags, len);
+ ASSERT (di->txp[txout] == NULL);
+
+ txout = NEXTTXD (txout);
+ }
+
+ /* if last txd eof not set, fix it */
+ if (!(flags & D64_CTRL1_EOF))
+ W_SM (&di->txd64[PREVTXD (txout)].ctrl1,
+ BUS_SWAP32 (flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
+
+ /* save the packet */
+ di->txp[PREVTXD (txout)] = p0;
+
+ /* bump the tx descriptor index */
+ di->txout = txout;
+
+ /* kick the chip */
+ if (commit)
+ W_REG (di->osh, &di->d64txregs->ptr, I2B (txout, dma64dd_t));
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
+
+ return (0);
outoftxd:
- DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
- PKTFREE(di->osh, p0, TRUE);
- di->hnddma.txavail = 0;
- di->hnddma.txnobuf++;
- return (-1);
+ DMA_ERROR (("%s: dma_txfast: out of txds\n", di->name));
+ PKTFREE (di->osh, p0, TRUE);
+ di->hnddma.txavail = 0;
+ di->hnddma.txnobuf++;
+ return (-1);
}
/*
* regardless of the value of the hardware "curr" pointer.
*/
static void *
-dma64_getnexttxp(dma_info_t *di, bool forceall)
+dma64_getnexttxp (dma_info_t * di, bool forceall)
{
- uint start, end, i;
- void *txp;
+ uint start, end, i;
+ void *txp;
- DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
+ DMA_TRACE (("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
- if (di->ntxd == 0)
- return (NULL);
+ if (di->ntxd == 0)
+ return (NULL);
- txp = NULL;
+ txp = NULL;
- start = di->txin;
- if (forceall)
- end = di->txout;
- else
- end = B2I(R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
+ start = di->txin;
+ if (forceall)
+ end = di->txout;
+ else
+ end =
+ B2I (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK,
+ dma64dd_t);
- if ((start == 0) && (end > di->txout))
- goto bogus;
+ if ((start == 0) && (end > di->txout))
+ goto bogus;
- for (i = start; i != end && !txp; i = NEXTTXD(i)) {
- DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow),
- (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK),
- DMA_TX, di->txp[i]);
+ for (i = start; i != end && !txp; i = NEXTTXD (i))
+ {
+ DMA_UNMAP (di->osh,
+ (BUS_SWAP32 (R_SM (&di->txd64[i].addrlow)) -
+ di->dataoffsetlow),
+ (BUS_SWAP32 (R_SM (&di->txd64[i].ctrl2)) &
+ D64_CTRL2_BC_MASK), DMA_TX, di->txp[i], &di->txp_dmah[i]);
- W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
- W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
+ W_SM (&di->txd64[i].addrlow, 0xdeadbeef);
+ W_SM (&di->txd64[i].addrhigh, 0xdeadbeef);
- txp = di->txp[i];
- di->txp[i] = NULL;
- }
+ txp = di->txp[i];
+ di->txp[i] = NULL;
+ }
- di->txin = i;
+ di->txin = i;
- /* tx flow control */
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
- return (txp);
+ return (txp);
bogus:
/*
DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
start, end, di->txout, forceall));
*/
- return (NULL);
+ return (NULL);
}
static void *
-dma64_getnextrxp(dma_info_t *di, bool forceall)
+dma64_getnextrxp (dma_info_t * di, bool forceall)
{
- uint i;
- void *rxp;
+ uint i;
+ void *rxp;
- /* if forcing, dma engine must be disabled */
- ASSERT(!forceall || !dma64_rxenabled(di));
+ /* if forcing, dma engine must be disabled */
+ ASSERT (!forceall || !dma64_rxenabled (di));
- i = di->rxin;
+ i = di->rxin;
- /* return if no packets posted */
- if (i == di->rxout)
- return (NULL);
+ /* return if no packets posted */
+ if (i == di->rxout)
+ return (NULL);
- /* ignore curr if forceall */
- if (!forceall &&
- (i == B2I(R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t)))
- return (NULL);
+ /* ignore curr if forceall */
+ if (!forceall &&
+ (i ==
+ B2I (R_REG (di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK,
+ dma64dd_t)))
+ return (NULL);
- /* get the packet pointer that corresponds to the rx descriptor */
- rxp = di->rxp[i];
- ASSERT(rxp);
- di->rxp[i] = NULL;
+ /* get the packet pointer that corresponds to the rx descriptor */
+ rxp = di->rxp[i];
+ ASSERT (rxp);
+ di->rxp[i] = NULL;
- /* clear this packet from the descriptor ring */
- DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow),
- di->rxbufsize, DMA_RX, rxp);
+ /* clear this packet from the descriptor ring */
+ DMA_UNMAP (di->osh,
+ (BUS_SWAP32 (R_SM (&di->rxd64[i].addrlow)) - di->dataoffsetlow),
+ di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]);
- W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
- W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
+ W_SM (&di->rxd64[i].addrlow, 0xdeadbeef);
+ W_SM (&di->rxd64[i].addrhigh, 0xdeadbeef);
- di->rxin = NEXTRXD(i);
+ di->rxin = NEXTRXD (i);
- return (rxp);
+ return (rxp);
}
static bool
-_dma64_addrext(osl_t *osh, dma64regs_t *dma64regs)
+_dma64_addrext (osl_t * osh, dma64regs_t * dma64regs)
{
- uint32 w;
- OR_REG(osh, &dma64regs->control, D64_XC_AE);
- w = R_REG(osh, &dma64regs->control);
- AND_REG(osh, &dma64regs->control, ~D64_XC_AE);
- return ((w & D64_XC_AE) == D64_XC_AE);
+ uint32 w;
+ OR_REG (osh, &dma64regs->control, D64_XC_AE);
+ w = R_REG (osh, &dma64regs->control);
+ AND_REG (osh, &dma64regs->control, ~D64_XC_AE);
+ return ((w & D64_XC_AE) == D64_XC_AE);
}
/*
* Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
*/
static void
-dma64_txrotate(dma_info_t *di)
+dma64_txrotate (dma_info_t * di)
{
- uint ad;
- uint nactive;
- uint rot;
- uint old, new;
- uint32 w;
- uint first, last;
-
- ASSERT(dma64_txsuspendedidle(di));
-
- nactive = _dma_txactive(di);
- ad = B2I((R_REG(di->osh, &di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t);
- rot = TXD(ad - di->txin);
-
- ASSERT(rot < di->ntxd);
-
- /* full-ring case is a lot harder - don't worry about this */
- if (rot >= (di->ntxd - nactive)) {
- DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
- return;
- }
-
- first = di->txin;
- last = PREVTXD(di->txout);
-
- /* move entries starting at last and moving backwards to first */
- for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
- new = TXD(old + rot);
-
- /*
- * Move the tx dma descriptor.
- * EOT is set only in the last entry in the ring.
- */
- w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
- if (new == (di->ntxd - 1))
- w |= D64_CTRL1_EOT;
- W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
-
- w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
- W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
-
- W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
- W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
-
- /* zap the old tx dma descriptor address field */
- W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
- W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
-
- /* move the corresponding txp[] entry */
- ASSERT(di->txp[new] == NULL);
- di->txp[new] = di->txp[old];
- di->txp[old] = NULL;
- }
-
- /* update txin and txout */
- di->txin = ad;
- di->txout = TXD(di->txout + rot);
- di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-
- /* kick the chip */
- W_REG(di->osh, &di->d64txregs->ptr, I2B(di->txout, dma64dd_t));
+ uint ad;
+ uint nactive;
+ uint rot;
+ uint old, new;
+ uint32 w;
+ uint first, last;
+
+ ASSERT (dma64_txsuspendedidle (di));
+
+ nactive = _dma_txactive (di);
+ ad =
+ B2I ((R_REG (di->osh, &di->d64txregs->status1) & D64_XS1_AD_MASK),
+ dma64dd_t);
+ rot = TXD (ad - di->txin);
+
+ ASSERT (rot < di->ntxd);
+
+ /* full-ring case is a lot harder - don't worry about this */
+ if (rot >= (di->ntxd - nactive))
+ {
+ DMA_ERROR (("%s: dma_txrotate: ring full - punt\n", di->name));
+ return;
+ }
+
+ first = di->txin;
+ last = PREVTXD (di->txout);
+
+ /* move entries starting at last and moving backwards to first */
+ for (old = last; old != PREVTXD (first); old = PREVTXD (old))
+ {
+ new = TXD (old + rot);
+
+ /*
+ * Move the tx dma descriptor.
+ * EOT is set only in the last entry in the ring.
+ */
+ w = BUS_SWAP32 (R_SM (&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
+ if (new == (di->ntxd - 1))
+ w |= D64_CTRL1_EOT;
+ W_SM (&di->txd64[new].ctrl1, BUS_SWAP32 (w));
+
+ w = BUS_SWAP32 (R_SM (&di->txd64[old].ctrl2));
+ W_SM (&di->txd64[new].ctrl2, BUS_SWAP32 (w));
+
+ W_SM (&di->txd64[new].addrlow, R_SM (&di->txd64[old].addrlow));
+ W_SM (&di->txd64[new].addrhigh, R_SM (&di->txd64[old].addrhigh));
+
+ /* zap the old tx dma descriptor address field */
+ W_SM (&di->txd64[old].addrlow, BUS_SWAP32 (0xdeadbeef));
+ W_SM (&di->txd64[old].addrhigh, BUS_SWAP32 (0xdeadbeef));
+
+ /* move the corresponding txp[] entry */
+ ASSERT (di->txp[new] == NULL);
+ di->txp[new] = di->txp[old];
+ di->txp[old] = NULL;
+ }
+
+ /* update txin and txout */
+ di->txin = ad;
+ di->txout = TXD (di->txout + rot);
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1;
+
+ /* kick the chip */
+ W_REG (di->osh, &di->d64txregs->ptr, I2B (di->txout, dma64dd_t));
}
-#endif /* BCMDMA64 */
+#endif /* BCMDMA64 */
uint
-dma_addrwidth(sb_t *sbh, void *dmaregs)
-{
- dma32regs_t *dma32regs;
- osl_t *osh;
-
- osh = sb_osh(sbh);
-
- if (DMA64_CAP) {
- /* DMA engine is 64-bit capable */
- if (((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64)) {
- /* backplane are 64 bits capable */
-#if 0
- if (sb_backplane64(sbh))
- /* If bus is System Backplane or PCIE then we can access 64-bits */
- if ((BUSTYPE(sbh->bustype) == SB_BUS) ||
- ((BUSTYPE(sbh->bustype) == PCI_BUS) &&
- sbh->buscoretype == SB_PCIE))
- return (DMADDRWIDTH_64);
-#endif
-
- /* DMA64 is always 32 bits capable, AE is always TRUE */
+dma_addrwidth (sb_t * sbh, void *dmaregs)
+{
+ dma32regs_t *dma32regs;
+ osl_t *osh;
+
+ osh = sb_osh (sbh);
+
+ if (DMA64_CAP)
+ {
+ /* DMA engine is 64-bit capable */
+ if (((sb_coreflagshi (sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64))
+ {
+ /* backplane are 64 bits capable */
+ if (sb_backplane64 (sbh))
+ /* If bus is System Backplane or PCIE then we can access 64-bits */
+ if ((BUSTYPE (sbh->bustype) == SB_BUS) ||
+ ((BUSTYPE (sbh->bustype) == PCI_BUS) &&
+ sbh->buscoretype == SB_PCIE))
+ return (DMADDRWIDTH_64);
+
+ /* DMA64 is always 32 bits capable, AE is always TRUE */
#ifdef BCMDMA64
- ASSERT(_dma64_addrext(osh, (dma64regs_t *)dmaregs));
+ ASSERT (_dma64_addrext (osh, (dma64regs_t *) dmaregs));
#endif
- return (DMADDRWIDTH_32);
- }
+ return (DMADDRWIDTH_32);
}
+ }
- /* Start checking for 32-bit / 30-bit addressing */
- dma32regs = (dma32regs_t *)dmaregs;
+ /* Start checking for 32-bit / 30-bit addressing */
+ dma32regs = (dma32regs_t *) dmaregs;
- /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */
- if ((BUSTYPE(sbh->bustype) == SB_BUS) ||
- ((BUSTYPE(sbh->bustype) == PCI_BUS) && sbh->buscoretype == SB_PCIE) ||
- (_dma32_addrext(osh, dma32regs)))
- return (DMADDRWIDTH_32);
+ /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */
+ if ((BUSTYPE (sbh->bustype) == SB_BUS) ||
+ ((BUSTYPE (sbh->bustype) == PCI_BUS) && sbh->buscoretype == SB_PCIE) ||
+ (_dma32_addrext (osh, dma32regs)))
+ return (DMADDRWIDTH_32);
- /* Fallthru */
- return (DMADDRWIDTH_30);
+ /* Fallthru */
+ return (DMADDRWIDTH_30);
}