summaryrefslogtreecommitdiffstats
path: root/drivers/net/mace.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mace.c')
-rw-r--r--drivers/net/mace.c70
1 files changed, 39 insertions, 31 deletions
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index cf1e9e903..ea836aaa0 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -13,6 +13,7 @@
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.h>
+#include <asm/pgtable.h>
#include "mace.h"
#define N_RX_RING 8
@@ -117,21 +118,22 @@ mace_probe(struct device *dev)
mp = (struct mace_data *) dev->priv;
dev->base_addr = maces->addrs[0].address;
- mp->mace = (volatile struct mace *) maces->addrs[0].address;
- dev->irq = maces->intrs[0];
+ mp->mace = (volatile struct mace *)
+ ioremap(maces->addrs[0].address, 0x1000);
+ dev->irq = maces->intrs[0].line;
if (request_irq(dev->irq, mace_interrupt, 0, "MACE", dev)) {
printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);
return -EAGAIN;
}
- if (request_irq(maces->intrs[1], mace_txdma_intr, 0, "MACE-txdma",
+ if (request_irq(maces->intrs[1].line, mace_txdma_intr, 0, "MACE-txdma",
dev)) {
- printk(KERN_ERR "MACE: can't get irq %d\n", maces->intrs[1]);
+ printk(KERN_ERR "MACE: can't get irq %d\n", maces->intrs[1].line);
return -EAGAIN;
}
- if (request_irq(maces->intrs[2], mace_rxdma_intr, 0, "MACE-rxdma",
+ if (request_irq(maces->intrs[2].line, mace_rxdma_intr, 0, "MACE-rxdma",
dev)) {
- printk(KERN_ERR "MACE: can't get irq %d\n", maces->intrs[2]);
+ printk(KERN_ERR "MACE: can't get irq %d\n", maces->intrs[2].line);
return -EAGAIN;
}
@@ -155,10 +157,12 @@ mace_probe(struct device *dev)
mp = (struct mace_data *) dev->priv;
mp->maccc = ENXMT | ENRCV;
- mp->tx_dma = (volatile struct dbdma_regs *) maces->addrs[1].address;
- mp->tx_dma_intr = maces->intrs[1];
- mp->rx_dma = (volatile struct dbdma_regs *) maces->addrs[2].address;
- mp->rx_dma_intr = maces->intrs[2];
+ mp->tx_dma = (volatile struct dbdma_regs *)
+ ioremap(maces->addrs[1].address, 0x1000);
+ mp->tx_dma_intr = maces->intrs[1].line;
+ mp->rx_dma = (volatile struct dbdma_regs *)
+ ioremap(maces->addrs[2].address, 0x1000);
+ mp->rx_dma_intr = maces->intrs[2].line;
mp->tx_cmds = (volatile struct dbdma_cmd *) DBDMA_ALIGN(mp + 1);
mp->rx_cmds = mp->tx_cmds + NCMDS_TX * N_TX_RING + 1;
@@ -169,8 +173,6 @@ mace_probe(struct device *dev)
init_timer(&mp->tx_timeout);
mp->timeout_active = 0;
- mace_reset(dev);
-
dev->open = mace_open;
dev->stop = mace_close;
dev->hard_start_xmit = mace_xmit_start;
@@ -260,6 +262,9 @@ static int mace_open(struct device *dev)
struct sk_buff *skb;
unsigned char *data;
+ /* reset the chip */
+ mace_reset(dev);
+
/* initialize list of sk_buffs for receiving and set up recv dma */
memset((char *)mp->rx_cmds, 0, N_RX_RING * sizeof(struct dbdma_cmd));
cp = mp->rx_cmds;
@@ -410,6 +415,10 @@ static int mace_xmit_start(struct sk_buff *skb, struct device *dev)
++mp->tx_active;
mace_set_timeout(dev);
}
+ if (++next >= N_TX_RING)
+ next = 0;
+ if (next == mp->tx_empty)
+ dev->tbusy = 1;
restore_flags(flags);
return 0;
@@ -520,6 +529,8 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
i = mp->tx_empty;
while (mb->pr & XMTSV) {
+ del_timer(&mp->tx_timeout);
+ mp->timeout_active = 0;
/*
* Clear any interrupt indication associated with this status
* word. This appears to unlatch any error indication from
@@ -533,8 +544,6 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
eieio();
mp->tx_bad_runt = 0;
mb->xmtfc = AUTO_PAD_XMIT;
- del_timer(&mp->tx_timeout);
- mp->timeout_active = 0;
continue;
}
dstat = ld_le32(&td->status);
@@ -562,7 +571,8 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
fs = mb->xmtfs;
if ((fs & XMTSV) == 0) {
- printk(KERN_ERR "mace: xmtfs not valid! (fs=%x xc=%d ds=%x)\n", fs, xcount, dstat);
+ printk(KERN_ERR "mace: xmtfs not valid! (fs=%x xc=%d ds=%x)\n",
+ fs, xcount, dstat);
}
cp = mp->tx_cmds + NCMDS_TX * i;
stat = ld_le16(&cp->xfer_status);
@@ -571,6 +581,7 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* Check whether there were in fact 2 bytes written to
* the transmit FIFO.
*/
+ udelay(1);
x = (mb->fifofc >> XMTFC_SH) & XMTFC_MASK;
if (x != 0) {
/* there were two bytes with an end-of-packet indication */
@@ -579,17 +590,21 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} else {
/*
* Either there weren't the two bytes buffered up, or they
- * didn't have an end-of-packet indication. Maybe we ought
- * to flush the transmit FIFO just in case (by setting the
+ * didn't have an end-of-packet indication.
+ * We flush the transmit FIFO just in case (by setting the
* XMTFWU bit with the transmitter disabled).
*/
- mb->xmtfc = AUTO_PAD_XMIT;
- eieio();
+ out_8(&mb->maccc, mb->maccc & ~ENXMT);
+ out_8(&mb->fifocc, mb->fifocc | XMTFWU);
+ udelay(1);
+ out_8(&mb->maccc, mb->maccc | ENXMT);
+ out_8(&mb->xmtfc, AUTO_PAD_XMIT);
}
}
/* dma should have finished */
if (i == mp->tx_fill) {
- printk(KERN_DEBUG "mace: tx ring ran out? (fs=%x xc=%d ds=%x)\n", fs, xcount, dstat);
+ printk(KERN_DEBUG "mace: tx ring ran out? (fs=%x xc=%d ds=%x)\n",
+ fs, xcount, dstat);
continue;
}
/* Update stats */
@@ -607,11 +622,9 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
i = 0;
mace_last_fs = fs;
mace_last_xcount = xcount;
- del_timer(&mp->tx_timeout);
- mp->timeout_active = 0;
}
- if (i != mp->tx_empty && mp->tx_fullup) {
+ if (i != mp->tx_empty) {
mp->tx_fullup = 0;
dev->tbusy = 0;
mark_bh(NET_BH);
@@ -656,9 +669,6 @@ static void mace_tx_timeout(unsigned long data)
mace_handle_misc_intrs(mp, mb->ir);
cp = mp->tx_cmds + NCMDS_TX * mp->tx_empty;
- printk(KERN_DEBUG "mace: tx dmastat=%x %x bad_runt=%d pr=%x fs=%x fc=%x\n",
- ld_le32(&td->status), ld_le16(&cp->xfer_status), mp->tx_bad_runt,
- mb->pr, mb->xmtfs, mb->fifofc);
/* turn off both tx and rx and reset the chip */
mb->maccc = 0;
@@ -685,11 +695,9 @@ static void mace_tx_timeout(unsigned long data)
i = 0;
mp->tx_empty = i;
}
- if (mp->tx_fullup) {
- mp->tx_fullup = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
+ mp->tx_fullup = 0;
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
if (i != mp->tx_fill) {
cp = mp->tx_cmds + NCMDS_TX * i;
out_le16(&cp->xfer_status, 0);