9
0
Fork 0

gianfar: descriptors access with I/O accessors

As in U-Boot git-9c9141f, make read/write access to the TX/RX
descriptors CPU agnostic.

Signed-off-by: Renaud Barbier <renaud.barbier@ge.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Renaud Barbier 2014-07-22 15:16:18 +01:00 committed by Sascha Hauer
parent b3265685f7
commit 752b9f4bf4
2 changed files with 43 additions and 43 deletions

View File

@ -199,19 +199,19 @@ static int gfar_open(struct eth_device *edev)
/* Initialize the Rx Buffer descriptors */
for (ix = 0; ix < RX_BUF_CNT; ix++) {
priv->rxbd[ix].status = RXBD_EMPTY;
priv->rxbd[ix].length = 0;
priv->rxbd[ix].bufPtr = (uint) NetRxPackets[ix];
out_be16(&priv->rxbd[ix].status, RXBD_EMPTY);
out_be16(&priv->rxbd[ix].length, 0);
out_be32(&priv->rxbd[ix].bufPtr, (uint) NetRxPackets[ix]);
}
priv->rxbd[RX_BUF_CNT - 1].status |= RXBD_WRAP;
out_be16(&priv->rxbd[RX_BUF_CNT - 1].status, RXBD_EMPTY | RXBD_WRAP);
/* Initialize the TX Buffer Descriptors */
for (ix = 0; ix < TX_BUF_CNT; ix++) {
priv->txbd[ix].status = 0;
priv->txbd[ix].length = 0;
priv->txbd[ix].bufPtr = 0;
out_be16(&priv->txbd[ix].status, 0);
out_be16(&priv->txbd[ix].length, 0);
out_be32(&priv->txbd[ix].bufPtr, 0);
}
priv->txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP;
out_be16(&priv->txbd[TX_BUF_CNT - 1].status, TXBD_WRAP);
/* Enable Transmit and Receive */
setbits_be32(regs + GFAR_MACCFG1_OFFSET, GFAR_MACCFG1_RX_EN |
@ -366,30 +366,32 @@ static int gfar_send(struct eth_device *edev, void *packet, int length)
struct device_d *dev = edev->parent;
uint64_t start;
uint tidx;
uint16_t status;
tidx = priv->txidx;
priv->txbd[tidx].bufPtr = (uint) packet;
priv->txbd[tidx].length = length;
priv->txbd[tidx].status |= (TXBD_READY | TXBD_LAST |
TXBD_CRC | TXBD_INTERRUPT);
out_be32(&priv->txbd[tidx].bufPtr, (u32) packet);
out_be16(&priv->txbd[tidx].length, length);
out_be16(&priv->txbd[tidx].status,
in_be16(&priv->txbd[tidx].status) |
(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT));
/* Tell the DMA to go */
out_be32(regs + GFAR_TSTAT_OFFSET, GFAR_TSTAT_CLEAR_THALT);
/* Wait for buffer to be transmitted */
start = get_time_ns();
while (priv->txbd[tidx].status & TXBD_READY) {
while (in_be16(&priv->txbd[tidx].status) & TXBD_READY) {
if (is_timeout(start, 5 * MSECOND)) {
break;
}
}
if (priv->txbd[tidx].status & TXBD_READY) {
dev_err(dev, "tx timeout: 0x%x\n", priv->txbd[tidx].status);
status = in_be16(&priv->txbd[tidx].status);
if (status & TXBD_READY) {
dev_err(dev, "tx timeout: 0x%x\n", status);
return -EBUSY;
}
else if (priv->txbd[tidx].status & TXBD_STATS) {
dev_err(dev, "TX error: 0x%x\n", priv->txbd[tidx].status);
} else if (status & TXBD_STATS) {
dev_err(dev, "TX error: 0x%x\n", status);
return -EIO;
}
@ -403,31 +405,28 @@ static int gfar_recv(struct eth_device *edev)
struct gfar_private *priv = edev->priv;
struct device_d *dev = edev->parent;
void __iomem *regs = priv->regs;
int length;
uint16_t status, length;
if (priv->rxbd[priv->rxidx].status & RXBD_EMPTY) {
return 0; /* no data */
}
if (in_be16(&priv->rxbd[priv->rxidx].status) & RXBD_EMPTY)
return 0;
length = priv->rxbd[priv->rxidx].length;
length = in_be16(&priv->rxbd[priv->rxidx].length);
/* Send the packet up if there were no errors */
if (!(priv->rxbd[priv->rxidx].status & RXBD_STATS)) {
status = in_be16(&priv->rxbd[priv->rxidx].status);
if (!(status & RXBD_STATS))
net_receive(edev, NetRxPackets[priv->rxidx], length - 4);
} else {
dev_err(dev, "Got error %x\n",
(priv->rxbd[priv->rxidx].status & RXBD_STATS));
}
else
dev_err(dev, "Got error %x\n", status & RXBD_STATS);
priv->rxbd[priv->rxidx].length = 0;
out_be16(&priv->rxbd[priv->rxidx].length, 0);
status = RXBD_EMPTY;
/* Set the wrap bit if this is the last element in the list */
if ((priv->rxidx + 1) == RX_BUF_CNT)
priv->rxbd[priv->rxidx].status = RXBD_WRAP;
else
priv->rxbd[priv->rxidx].status = 0;
status |= RXBD_WRAP;
priv->rxbd[priv->rxidx].status |= RXBD_EMPTY;
out_be16(&priv->rxbd[priv->rxidx].status, status);
priv->rxidx = (priv->rxidx + 1) % RX_BUF_CNT;
if (in_be32(regs + GFAR_IEVENT_OFFSET) & GFAR_IEVENT_BSY) {
@ -517,8 +516,9 @@ static int gfar_probe(struct device_d *dev)
size = ((TX_BUF_CNT * sizeof(struct txbd8)) +
(RX_BUF_CNT * sizeof(struct rxbd8))) + BUF_ALIGN;
p = (char *)xmemalign(BUF_ALIGN, size);
priv->txbd = (struct txbd8 *)p;
priv->rxbd = (struct rxbd8 *)(p + (TX_BUF_CNT * sizeof(struct txbd8)));
priv->txbd = (struct txbd8 __iomem *)p;
priv->rxbd = (struct rxbd8 __iomem *)(p +
(TX_BUF_CNT * sizeof(struct txbd8)));
edev->priv = priv;
edev->init = gfar_init;

View File

@ -188,15 +188,15 @@
#define RXBD_STATS 0x003f
struct txbd8 {
ushort status; /* Status Fields */
ushort length; /* Buffer length */
uint bufPtr; /* Buffer Pointer */
uint16_t status; /* Status Fields */
uint16_t length; /* Buffer length */
uint32_t bufPtr; /* Buffer Pointer */
};
struct rxbd8 {
ushort status; /* Status Fields */
ushort length; /* Buffer Length */
uint bufPtr; /* Buffer Pointer */
uint16_t status; /* Status Fields */
uint16_t length; /* Buffer Length */
uint32_t bufPtr; /* Buffer Pointer */
};
/* eTSEC general control and status registers */
@ -275,8 +275,8 @@ struct gfar_private {
struct gfar_phy *gfar_mdio;
struct gfar_phy *gfar_tbi;
struct phy_info *phyinfo;
volatile struct txbd8 *txbd;
volatile struct rxbd8 *rxbd;
struct txbd8 __iomem *txbd;
struct rxbd8 __iomem *rxbd;
uint txidx;
uint rxidx;
uint phyaddr;