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