Skip to content

Commit

Permalink
brcm80211: smac: use bcma function for register access in dma.c
Browse files Browse the repository at this point in the history
The dma.c source file now uses the register access functions
provided by bcma.

Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Arend van Spriel authored and John W. Linville committed Dec 13, 2011
1 parent 2e81b9b commit e81da65
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 91 deletions.
174 changes: 97 additions & 77 deletions drivers/net/wireless/brcm80211/brcmsmac/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
#include "dma.h"
#include "soc.h"

/*
* dma register field offset calculation
*/
#define DMA64REGOFFS(field) offsetof(struct dma64regs, field)
#define DMA64TXREGOFFS(di, field) (di->d64txregbase + DMA64REGOFFS(field))
#define DMA64RXREGOFFS(di, field) (di->d64rxregbase + DMA64REGOFFS(field))

/*
* DMA hardware requires each descriptor ring to be 8kB aligned, and fit within
* a contiguous 8kB physical address.
Expand Down Expand Up @@ -227,9 +234,9 @@ struct dma_info {
bool addrext; /* this dma engine supports DmaExtendedAddrChanges */

/* 64-bit dma tx engine registers */
struct dma64regs __iomem *d64txregs;
uint d64txregbase;
/* 64-bit dma rx engine registers */
struct dma64regs __iomem *d64rxregs;
uint d64rxregbase;
/* pointer to dma64 tx descriptor ring */
struct dma64desc *txd64;
/* pointer to dma64 rx descriptor ring */
Expand Down Expand Up @@ -376,15 +383,16 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
if (dmactrlflags & DMA_CTRL_PEN) {
u32 control;

control = R_REG(&di->d64txregs->control);
W_REG(&di->d64txregs->control,
control = bcma_read32(di->d11core, DMA64TXREGOFFS(di, control));
bcma_write32(di->d11core, DMA64TXREGOFFS(di, control),
control | D64_XC_PD);
if (R_REG(&di->d64txregs->control) & D64_XC_PD)
if (bcma_read32(di->d11core, DMA64TXREGOFFS(di, control)) &
D64_XC_PD)
/* We *can* disable it so it is supported,
* restore control register
*/
W_REG(&di->d64txregs->control,
control);
bcma_write32(di->d11core, DMA64TXREGOFFS(di, control),
control);
else
/* Not supported, don't allow it to be enabled */
dmactrlflags &= ~DMA_CTRL_PEN;
Expand All @@ -395,12 +403,12 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
return dmactrlflags;
}

static bool _dma64_addrext(struct dma64regs __iomem *dma64regs)
static bool _dma64_addrext(struct dma_info *di, uint ctrl_offset)
{
u32 w;
OR_REG(&dma64regs->control, D64_XC_AE);
w = R_REG(&dma64regs->control);
AND_REG(&dma64regs->control, ~D64_XC_AE);
bcma_set32(di->d11core, ctrl_offset, D64_XC_AE);
w = bcma_read32(di->d11core, ctrl_offset);
bcma_mask32(di->d11core, ctrl_offset, ~D64_XC_AE);
return (w & D64_XC_AE) == D64_XC_AE;
}

Expand All @@ -413,13 +421,13 @@ static bool _dma_isaddrext(struct dma_info *di)
/* DMA64 supports full 32- or 64-bit operation. AE is always valid */

/* not all tx or rx channel are available */
if (di->d64txregs != NULL) {
if (!_dma64_addrext(di->d64txregs))
if (di->d64txregbase != 0) {
if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control)))
DMA_ERROR("%s: DMA64 tx doesn't have AE set\n",
di->name);
return true;
} else if (di->d64rxregs != NULL) {
if (!_dma64_addrext(di->d64rxregs))
} else if (di->d64rxregbase != 0) {
if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control)))
DMA_ERROR("%s: DMA64 rx doesn't have AE set\n",
di->name);
return true;
Expand All @@ -433,14 +441,14 @@ static bool _dma_descriptor_align(struct dma_info *di)
u32 addrl;

/* Check to see if the descriptors need to be aligned on 4K/8K or not */
if (di->d64txregs != NULL) {
W_REG(&di->d64txregs->addrlow, 0xff0);
addrl = R_REG(&di->d64txregs->addrlow);
if (di->d64txregbase != 0) {
bcma_write32(di->d11core, DMA64TXREGOFFS(di, addrlow), 0xff0);
addrl = bcma_read32(di->d11core, DMA64TXREGOFFS(di, addrlow));
if (addrl != 0)
return false;
} else if (di->d64rxregs != NULL) {
W_REG(&di->d64rxregs->addrlow, 0xff0);
addrl = R_REG(&di->d64rxregs->addrlow);
} else if (di->d64rxregbase != 0) {
bcma_write32(di->d11core, DMA64RXREGOFFS(di, addrlow), 0xff0);
addrl = bcma_read32(di->d11core, DMA64RXREGOFFS(di, addrlow));
if (addrl != 0)
return false;
}
Expand Down Expand Up @@ -558,8 +566,7 @@ static bool _dma_alloc(struct dma_info *di, uint direction)

struct dma_pub *dma_attach(char *name, struct si_pub *sih,
struct bcma_device *d11core,
void __iomem *dmaregstx, void __iomem *dmaregsrx,
uint ntxd, uint nrxd,
uint txregbase, uint rxregbase, uint ntxd, uint nrxd,
uint rxbufsize, int rxextheadroom,
uint nrxpost, uint rxoffset, uint *msg_level)
{
Expand All @@ -576,10 +583,10 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,

di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);

/* init dma reg pointer */
/* init dma reg info */
di->d11core = d11core;
di->d64txregs = (struct dma64regs __iomem *) dmaregstx;
di->d64rxregs = (struct dma64regs __iomem *) dmaregsrx;
di->d64txregbase = txregbase;
di->d64rxregbase = rxregbase;

/*
* Default flags (which can be changed by the driver calling
Expand All @@ -588,10 +595,11 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
*/
_dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0);

DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d dmaregstx %p dmaregsrx %p\n",
name, "DMA64",
DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d "
"rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
"txregbase %u rxregbase %u\n", name, "DMA64",
di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx);
rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase);

/* make a private copy of our callers name */
strncpy(di->name, name, MAXNAMEL);
Expand Down Expand Up @@ -783,11 +791,15 @@ _dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa)
if ((di->ddoffsetlow == 0)
|| !(pa & PCI32ADDR_HIGH)) {
if (direction == DMA_TX) {
W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
bcma_write32(di->d11core, DMA64TXREGOFFS(di, addrlow),
pa + di->ddoffsetlow);
bcma_write32(di->d11core, DMA64TXREGOFFS(di, addrhigh),
di->ddoffsethigh);
} else {
W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
bcma_write32(di->d11core, DMA64RXREGOFFS(di, addrlow),
pa + di->ddoffsetlow);
bcma_write32(di->d11core, DMA64RXREGOFFS(di, addrhigh),
di->ddoffsethigh);
}
} else {
/* DMA64 32bits address extension */
Expand All @@ -798,15 +810,19 @@ _dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa)
pa &= ~PCI32ADDR_HIGH;

if (direction == DMA_TX) {
W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
SET_REG(&di->d64txregs->control,
D64_XC_AE, (ae << D64_XC_AE_SHIFT));
bcma_write32(di->d11core, DMA64TXREGOFFS(di, addrlow),
pa + di->ddoffsetlow);
bcma_write32(di->d11core, DMA64TXREGOFFS(di, addrhigh),
di->ddoffsethigh);
bcma_maskset32(di->d11core, DMA64TXREGOFFS(di, control),
D64_XC_AE, (ae << D64_XC_AE_SHIFT));
} else {
W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
SET_REG(&di->d64rxregs->control,
D64_RC_AE, (ae << D64_RC_AE_SHIFT));
bcma_write32(di->d11core, DMA64RXREGOFFS(di, addrlow),
pa + di->ddoffsetlow);
bcma_write32(di->d11core, DMA64RXREGOFFS(di, addrhigh),
di->ddoffsethigh);
bcma_maskset32(di->d11core, DMA64RXREGOFFS(di, control),
D64_RC_AE, (ae << D64_RC_AE_SHIFT));
}
}
}
Expand All @@ -818,17 +834,17 @@ static void _dma_rxenable(struct dma_info *di)

DMA_TRACE("%s:\n", di->name);

control =
(R_REG(&di->d64rxregs->control) & D64_RC_AE) |
D64_RC_RE;
control = D64_RC_RE | (bcma_read32(di->d11core,
DMA64RXREGOFFS(di, control)) &
D64_RC_AE);

if ((dmactrlflags & DMA_CTRL_PEN) == 0)
control |= D64_RC_PD;

if (dmactrlflags & DMA_CTRL_ROC)
control |= D64_RC_OC;

W_REG(&di->d64rxregs->control,
bcma_write32(di->d11core, DMA64RXREGOFFS(di, control),
((di->rxoffset << D64_RC_RO_SHIFT) | control));
}

Expand Down Expand Up @@ -871,7 +887,8 @@ static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall)
return NULL;

curr =
B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
B2I(((bcma_read32(di->d11core,
DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) -
di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc);

/* ignore curr if forceall */
Expand Down Expand Up @@ -953,12 +970,12 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
if (resid > 0) {
uint cur;
cur =
B2I(((R_REG(&di->d64rxregs->status0) &
D64_RS0_CD_MASK) -
di->rcvptrbase) & D64_RS0_CD_MASK,
struct dma64desc);
B2I(((bcma_read32(di->d11core,
DMA64RXREGOFFS(di, status0)) &
D64_RS0_CD_MASK) - di->rcvptrbase) &
D64_RS0_CD_MASK, struct dma64desc);
DMA_ERROR("rxin %d rxout %d, hw_curr %d\n",
di->rxin, di->rxout, cur);
di->rxin, di->rxout, cur);
}
#endif /* BCMDBG */

Expand Down Expand Up @@ -986,8 +1003,10 @@ static bool dma64_rxidle(struct dma_info *di)
if (di->nrxd == 0)
return true;

return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
(R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
return ((bcma_read32(di->d11core,
DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) ==
(bcma_read32(di->d11core, DMA64RXREGOFFS(di, ptr)) &
D64_RS0_CD_MASK));
}

/*
Expand Down Expand Up @@ -1070,7 +1089,7 @@ bool dma_rxfill(struct dma_pub *pub)
di->rxout = rxout;

/* update the chip lastdscr pointer */
W_REG(&di->d64rxregs->ptr,
bcma_write32(di->d11core, DMA64RXREGOFFS(di, ptr),
di->rcvptrbase + I2B(rxout, struct dma64desc));

return ring_empty;
Expand Down Expand Up @@ -1131,7 +1150,7 @@ void dma_txinit(struct dma_pub *pub)

if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0)
control |= D64_XC_PD;
OR_REG(&di->d64txregs->control, control);
bcma_set32(di->d11core, DMA64TXREGOFFS(di, control), control);

/* DMA engine with alignment requirement requires table to be inited
* before enabling the engine
Expand All @@ -1149,7 +1168,7 @@ void dma_txsuspend(struct dma_pub *pub)
if (di->ntxd == 0)
return;

OR_REG(&di->d64txregs->control, D64_XC_SE);
bcma_set32(di->d11core, DMA64TXREGOFFS(di, control), D64_XC_SE);
}

void dma_txresume(struct dma_pub *pub)
Expand All @@ -1161,16 +1180,17 @@ void dma_txresume(struct dma_pub *pub)
if (di->ntxd == 0)
return;

AND_REG(&di->d64txregs->control, ~D64_XC_SE);
bcma_mask32(di->d11core, DMA64TXREGOFFS(di, control), ~D64_XC_SE);
}

bool dma_txsuspended(struct dma_pub *pub)
{
struct dma_info *di = (struct dma_info *)pub;

return (di->ntxd == 0) ||
((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
D64_XC_SE);
((bcma_read32(di->d11core,
DMA64TXREGOFFS(di, control)) & D64_XC_SE) ==
D64_XC_SE);
}

void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
Expand Down Expand Up @@ -1203,16 +1223,17 @@ bool dma_txreset(struct dma_pub *pub)
return true;

/* suspend tx DMA first */
W_REG(&di->d64txregs->control, D64_XC_SE);
bcma_write32(di->d11core, DMA64TXREGOFFS(di, control), D64_XC_SE);
SPINWAIT(((status =
(R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
!= D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
&& (status != D64_XS0_XS_STOPPED), 10000);
(bcma_read32(di->d11core, DMA64TXREGOFFS(di, status0)) &
D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED) &&
(status != D64_XS0_XS_IDLE) && (status != D64_XS0_XS_STOPPED),
10000);

W_REG(&di->d64txregs->control, 0);
bcma_write32(di->d11core, DMA64TXREGOFFS(di, control), 0);
SPINWAIT(((status =
(R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
!= D64_XS0_XS_DISABLED), 10000);
(bcma_read32(di->d11core, DMA64TXREGOFFS(di, status0)) &
D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED), 10000);

/* wait for the last transaction to complete */
udelay(300);
Expand All @@ -1228,10 +1249,10 @@ bool dma_rxreset(struct dma_pub *pub)
if (di->nrxd == 0)
return true;

W_REG(&di->d64rxregs->control, 0);
bcma_write32(di->d11core, DMA64RXREGOFFS(di, control), 0);
SPINWAIT(((status =
(R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
!= D64_RS0_RS_DISABLED), 10000);
(bcma_read32(di->d11core, DMA64RXREGOFFS(di, status0)) &
D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED), 10000);

return status == D64_RS0_RS_DISABLED;
}
Expand Down Expand Up @@ -1293,7 +1314,7 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)

/* kick the chip */
if (commit)
W_REG(&di->d64txregs->ptr,
bcma_write32(di->d11core, DMA64TXREGOFFS(di, ptr),
di->xmtptrbase + I2B(txout, struct dma64desc));

/* tx flow control */
Expand Down Expand Up @@ -1341,16 +1362,15 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
if (range == DMA_RANGE_ALL)
end = di->txout;
else {
struct dma64regs __iomem *dregs = di->d64txregs;

end = (u16) (B2I(((R_REG(&dregs->status0) &
D64_XS0_CD_MASK) -
di->xmtptrbase) & D64_XS0_CD_MASK,
struct dma64desc));
end = (u16) (B2I(((bcma_read32(di->d11core,
DMA64TXREGOFFS(di, status0)) &
D64_XS0_CD_MASK) - di->xmtptrbase) &
D64_XS0_CD_MASK, struct dma64desc));

if (range == DMA_RANGE_TRANSFERED) {
active_desc =
(u16) (R_REG(&dregs->status1) &
(u16)(bcma_read32(di->d11core,
DMA64TXREGOFFS(di, status1)) &
D64_XS1_AD_MASK);
active_desc =
(active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/brcm80211/brcmsmac/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ struct dma_pub {

extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
struct bcma_device *d11core,
void __iomem *dmaregstx,
void __iomem *dmaregsrx,
uint txregbase, uint rxregbase,
uint ntxd, uint nrxd,
uint rxbufsize, int rxextheadroom,
uint nrxpost, uint rxoffset, uint *msg_level);
Expand Down
Loading

0 comments on commit e81da65

Please sign in to comment.