/*
 * Network device driver for the MACE ethernet controller on
 * Apple Powermacs.  Assumes it's under a DBDMA controller.
 *
 * Copyright (C) 1996 Paul Mackerras.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/crc32.h>
#include <linux/spinlock.h>
#include <linux/bitrev.h>
#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/macio.h>

#include "mace.h"

static int port_aaui = -1;

#define N_RX_RING	8
#define N_TX_RING	6
#define MAX_TX_ACTIVE	1
#define NCMDS_TX	1	/* dma commands per element in tx ring */
#define RX_BUFLEN	(ETH_FRAME_LEN + 8)
#define TX_TIMEOUT	HZ	/* 1 second */

/* Chip rev needs workaround on HW & multicast addr change */
#define BROKEN_ADDRCHG_REV	0x0941

/* Bits in transmit DMA status */
#define TX_DMA_ERR	0x80

struct mace_data {
    volatile struct mace __iomem *mace;
    volatile struct dbdma_regs __iomem *tx_dma;
    int tx_dma_intr;
    volatile struct dbdma_regs __iomem *rx_dma;
    int rx_dma_intr;
    volatile struct dbdma_cmd *tx_cmds;	/* xmit dma command list */
    volatile struct dbdma_cmd *rx_cmds;	/* recv dma command list */
    struct sk_buff *rx_bufs[N_RX_RING];
    int rx_fill;
    int rx_empty;
    struct sk_buff *tx_bufs[N_TX_RING];
    int tx_fill;
    int tx_empty;
    unsigned char maccc;
    unsigned char tx_fullup;
    unsigned char tx_active;
    unsigned char tx_bad_runt;
    struct timer_list tx_timeout;
    int timeout_active;
    int port_aaui;
    int chipid;
    struct macio_dev *mdev;
    spinlock_t lock;
};

/*
 * Number of bytes of private data per MACE: allow enough for
 * the rx and tx dma commands plus a branch dma command each,
 * and another 16 bytes to allow us to align the dma command
 * buffers on a 16 byte boundary.
 */
#define PRIV_BYTES	(sizeof(struct mace_data) \
	+ (N_RX_RING + NCMDS_TX * N_TX_RING + 3) * sizeof(struct dbdma_cmd))

static int mace_open(struct net_device *dev);
static int mace_close(struct net_device *dev);
static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
static void mace_set_multicast(struct net_device *dev);
static void mace_reset(struct net_device *dev);
static int mace_set_address(struct net_device *dev, void *addr);
static irqreturn_t mace_interrupt(int irq, void *dev_id);
static irqreturn_t mace_txdma_intr(int irq, void *dev_id);
static irqreturn_t mace_rxdma_intr(int irq, void *dev_id);
static void mace_set_timeout(struct net_device *dev);
static void mace_tx_timeout(struct timer_list *t);
static inline void dbdma_reset(volatile struct dbdma_regs __iomem *dma);
static inline void mace_clean_rings(struct mace_data *mp);
static void __mace_set_address(struct net_device *dev, void *addr);

/*
 * If we can't get a skbuff when we need it, we use this area for DMA.
 */
static unsigned char *dummy_buf;

static const struct net_device_ops mace_netdev_ops = {
	.ndo_open		= mace_open,
	.ndo_stop		= mace_close,
	.ndo_start_xmit		= mace_xmit_start,
	.ndo_set_rx_mode	= mace_set_multicast,
	.ndo_set_mac_address	= mace_set_address,
	.ndo_validate_addr	= eth_validate_addr,
};

static int mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
	struct device_node *mace = macio_get_of_node(mdev);
	struct net_device *dev;
	struct mace_data *mp;
	const unsigned char *addr;
	int j, rev, rc = -EBUSY;

	if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) {
		printk(KERN_ERR "can't use MACE %pOF: need 3 addrs and 3 irqs\n",
		       mace);
		return -ENODEV;
	}

	addr = of_get_property(mace, "mac-address", NULL);
	if (addr == NULL) {
		addr = of_get_property(mace, "local-mac-address", NULL);
		if (addr == NULL) {
			printk(KERN_ERR "Can't get mac-address for MACE %pOF\n",
			       mace);
			return -ENODEV;
		}
	}

	/*
	 * lazy allocate the driver-wide dummy buffer. (Note that we
	 * never have more than one MACE in the system anyway)
	 */
	if (dummy_buf == NULL) {
		dummy_buf = kmalloc(RX_BUFLEN+2, GFP_KERNEL);
		if (dummy_buf == NULL)
			return -ENOMEM;
	}

	if (macio_request_resources(mdev, "mace")) {
		printk(KERN_ERR "MACE: can't request IO resources !\n");
		return -EBUSY;
	}

	dev = alloc_etherdev(PRIV_BYTES);
	if (!dev) {
		rc = -ENOMEM;
		goto err_release;
	}
	SET_NETDEV_DEV(dev, &mdev->ofdev.dev);

	mp = netdev_priv(dev);
	mp->mdev = mdev;
	macio_set_drvdata(mdev, dev);

	dev->base_addr = macio_resource_start(mdev, 0);
	mp->mace = ioremap(dev->base_addr, 0x1000);
	if (mp->mace == NULL) {
		printk(KERN_ERR "MACE: can't map IO resources !\n");
		rc = -ENOMEM;
		goto err_free;
	}
	dev->irq = macio_irq(mdev, 0);

	rev = addr[0] == 0 && addr[1] == 0xA0;
	for (j = 0; j < 6; ++j) {
		dev->dev_addr[j] = rev ? bitrev8(addr[j]): addr[j];
	}
	mp->chipid = (in_8(&mp->mace->chipid_hi) << 8) |
			in_8(&mp->mace->chipid_lo);


	mp = netdev_priv(dev);
	mp->maccc = ENXMT | ENRCV;

	mp->tx_dma = ioremap(macio_resource_start(mdev, 1), 0x1000);
	if (mp->tx_dma == NULL) {
		printk(KERN_ERR "MACE: can't map TX DMA resources !\n");
		rc = -ENOMEM;
		goto err_unmap_io;
	}
	mp->tx_dma_intr = macio_irq(mdev, 1);

	mp->rx_dma = ioremap(macio_resource_start(mdev, 2), 0x1000);
	if (mp->rx_dma == NULL) {
		printk(KERN_ERR "MACE: can't map RX DMA resources !\n");
		rc = -ENOMEM;
		goto err_unmap_tx_dma;
	}
	mp->rx_dma_intr = macio_irq(mdev, 2);

	mp->tx_cmds = (volatile struct dbdma_cmd *) DBDMA_ALIGN(mp + 1);
	mp->rx_cmds = mp->tx_cmds + NCMDS_TX * N_TX_RING + 1;

	memset((char *) mp->tx_cmds, 0,
	       (NCMDS_TX*N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd));
	timer_setup(&mp->tx_timeout, mace_tx_timeout, 0);
	spin_lock_init(&mp->lock);
	mp->timeout_active = 0;

	if (port_aaui >= 0)
		mp->port_aaui = port_aaui;
	else {
		/* Apple Network Server uses the AAUI port */
		if (of_machine_is_compatible("AAPL,ShinerESB"))
			mp->port_aaui = 1;
		else {
#ifdef CONFIG_MACE_AAUI_PORT
			mp->port_aaui = 1;
#else
			mp->port_aaui = 0;
#endif
		}
	}

	dev->netdev_ops = &mace_netdev_ops;

	/*
	 * Most of what is below could be moved to mace_open()
	 */
	mace_reset(dev);

	rc = request_irq(dev->irq, mace_interrupt, 0, "MACE", dev);
	if (rc) {
		printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);
		goto err_unmap_rx_dma;
	}
	rc = request_irq(mp->tx_dma_intr, mace_txdma_intr, 0, "MACE-txdma", dev);
	if (rc) {
		printk(KERN_ERR "MACE: can't get irq %d\n", mp->tx_dma_intr);
		goto err_free_irq;
	}
	rc = request_irq(mp->rx_dma_intr, mace_rxdma_intr, 0, "MACE-rxdma", dev);
	if (rc) {
		printk(KERN_ERR "MACE: can't get irq %d\n", mp->rx_dma_intr);
		goto err_free_tx_irq;
	}

	rc = register_netdev(dev);
	if (rc) {
		printk(KERN_ERR "MACE: Cannot register net device, aborting.\n");
		goto err_free_rx_irq;
	}

	printk(KERN_INFO "%s: MACE at %pM, chip revision %d.%d\n",
	       dev->name, dev->dev_addr,
	       mp->chipid >> 8, mp->chipid & 0xff);

	return 0;

 err_free_rx_irq:
	free_irq(macio_irq(mdev, 2), dev);
 err_free_tx_irq:
	free_irq(macio_irq(mdev, 1), dev);
 err_free_irq:
	free_irq(macio_irq(mdev, 0), dev);
 err_unmap_rx_dma:
	iounmap(mp->rx_dma);
 err_unmap_tx_dma:
	iounmap(mp->tx_dma);
 err_unmap_io:
	iounmap(mp->mace);
 err_free:
	free_netdev(dev);
 err_release:
	macio_release_resources(mdev);

	return rc;
}

static int mace_remove(struct macio_dev *mdev)
{
	struct net_device *dev = macio_get_drvdata(mdev);
	struct mace_data *mp;

	BUG_ON(dev == NULL);

	macio_set_drvdata(mdev, NULL);

	mp = netdev_priv(dev);

	unregister_netdev(dev);

	free_irq(dev->irq, dev);
	free_irq(mp->tx_dma_intr, dev);
	free_irq(mp->rx_dma_intr, dev);

	iounmap(mp->rx_dma);
	iounmap(mp->tx_dma);
	iounmap(mp->mace);

	free_netdev(dev);

	macio_release_resources(mdev);

	return 0;
}

static void dbdma_reset(volatile struct dbdma_regs __iomem *dma)
{
    int i;

    out_le32(&dma->control, (WAKE|FLUSH|PAUSE|RUN) << 16);

    /*
     * Yes this looks peculiar, but apparently it needs to be this
     * way on some machines.
     */
    for (i = 200; i > 0; --i)
	if (le32_to_cpu(dma->control) & RUN)
	    udelay(1);
}

static void mace_reset(struct net_device *dev)
{
    struct mace_data *mp = netdev_priv(dev);
    volatile struct mace __iomem *mb = mp->mace;
    int i;

    /* soft-reset the chip */
    i = 200;
    while (--i) {
	out_8(&mb->biucc, SWRST);
	if (in_8(&mb->biucc) & SWRST) {
	    udelay(10);
	    continue;
	}
	break;
    }
    if (!i) {
	printk(KERN_ERR "mace: cannot reset chip!\n");
	return;
    }

    out_8(&mb->imr, 0xff);	/* disable all intrs for now */
    i = in_8(&mb->ir);
    out_8(&mb->maccc, 0);	/* turn off tx, rx */

    out_8(&mb->biucc, XMTSP_64);
    out_8(&mb->utr, RTRD);
    out_8(&mb->fifocc, RCVFW_32 | XMTFW_16 | XMTFWU | RCVFWU | XMTBRST);
    out_8(&mb->xmtfc, AUTO_PAD_XMIT); /* auto-pad short frames */
    out_8(&mb->rcvfc, 0);

    /* load up the hardware address */
    __mace_set_address(dev, dev->dev_addr);

    /* clear the multicast filter */
    if (mp->chipid == BROKEN_ADDRCHG_REV)
	out_8(&mb->iac, LOGADDR);
    else {
	out_8(&mb->iac, ADDRCHG | LOGADDR);
	while ((in_8(&mb->iac) & ADDRCHG) != 0)
		;
    }
    for (i = 0; i < 8; ++i)
	out_8(&mb->ladrf, 0);

    /* done changing address */
    if (mp->chipid != BROKEN_ADDRCHG_REV)
	out_8(&mb->iac, 0);

    if (mp->port_aaui)
    	out_8(&mb->plscc, PORTSEL_AUI + ENPLSIO);
    else
    	out_8(&mb->plscc, PORTSEL_GPSI + ENPLSIO);
}

static void __mace_set_address(struct net_device *dev, void *addr)
{
    struct mace_data *mp = netdev_priv(dev);
    volatile struct mace __iomem *mb = mp->mace;
    unsigned char *p = addr;
    int i;

    /* load up the hardware address */
    if (mp->chipid == BROKEN_ADDRCHG_REV)
    	out_8(&mb->iac, PHYADDR);
    else {
    	out_8(&mb->iac, ADDRCHG | PHYADDR);
	while ((in_8(&mb->iac) & ADDRCHG) != 0)
	    ;
    }
    for (i = 0; i < 6; ++i)
	out_8(&mb->padr, dev->dev_addr[i] = p[i]);
    if (mp->chipid != BROKEN_ADDRCHG_REV)
        out_8(&mb->iac, 0);
}

static int mace_set_address(struct net_device *dev, void *addr)
{
    struct mace_data *mp = netdev_priv(dev);
    volatile struct mace __iomem *mb = mp->mace;
    unsigned long flags;

    spin_lock_irqsave(&mp->lock, flags);

    __mace_set_address(dev, addr);

    /* note: setting ADDRCHG clears ENRCV */
    out_8(&mb->maccc, mp->maccc);

    spin_unlock_irqrestore(&mp->lock, flags);
    return 0;
}

static inline void mace_clean_rings(struct mace_data *mp)
{
    int i;

    /* free some skb's */
    for (i = 0; i < N_RX_RING; ++i) {
	if (mp->rx_bufs[i] != NULL) {
	    dev_kfree_skb(mp->rx_bufs[i]);
	    mp->rx_bufs[i] = NULL;
	}
    }
    for (i = mp->tx_empty; i != mp->tx_fill; ) {
	dev_kfree_skb(mp->tx_bufs[i]);
	if (++i >= N_TX_RING)
	    i = 0;
    }
}

static int mace_open(struct net_device *dev)
{
    struct mace_data *mp = netdev_priv(dev);
    volatile struct mace __iomem *mb = mp->mace;
    volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
    volatile struct dbdma_cmd *cp;
    int i;
    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 */
    mace_clean_rings(mp);
    memset((char *)mp->rx_cmds, 0, N_RX_RING * sizeof(struct dbdma_cmd));
    cp = mp->rx_cmds;
    for (i = 0; i < N_RX_RING - 1; ++i) {
	skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
	if (!skb) {
	    data = dummy_buf;
	} else {
	    skb_reserve(skb, 2);	/* so IP header lands on 4-byte bdry */
	    data = skb->data;
	}
	mp->rx_bufs[i] = skb;
	cp->req_count = cpu_to_le16(RX_BUFLEN);
	cp->command = cpu_to_le16(INPUT_LAST + INTR_ALWAYS);
	cp->phy_addr = cpu_to_le32(virt_to_bus(data));
	cp->xfer_status = 0;
	++cp;
    }
    mp->rx_bufs[i] = NULL;
    cp->command = cpu_to_le16(DBDMA_STOP);
    mp->rx_fill = i;
    mp->rx_empty = 0;

    /* Put a branch back to the beginning of the receive command list */
    ++cp;
    cp->command = cpu_to_le16(DBDMA_NOP + BR_ALWAYS);
    cp->cmd_dep = cpu_to_le32(virt_to_bus(mp->rx_cmds));

    /* start rx dma */
    out_le32(&rd->control, (RUN|PAUSE|FLUSH|WAKE) << 16); /* clear run bit */
    out_le32(&rd->cmdptr, virt_to_bus(mp->rx_cmds));
    out_le32(&rd->control, (RUN << 16) | RUN);

    /* put a branch at the end of the tx command list */
    cp = mp->tx_cmds + NCMDS_TX * N_TX_RING;
    cp->command = cpu_to_le16(DBDMA_NOP + BR_ALWAYS);
    cp->cmd_dep = cpu_to_le32(virt_to_bus(mp->tx_cmds));

    /* reset tx dma */
    out_le32(&td->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
    out_le32(&td->cmdptr, virt_to_bus(mp->tx_cmds));
    mp->tx_fill = 0;
    mp->tx_empty = 0;
    mp->tx_fullup = 0;
    mp->tx_active = 0;
    mp->tx_bad_runt = 0;

    /* turn it on! */
    out_8(&mb->maccc, mp->maccc);
    /* enable all interrupts except receive interrupts */
    out_8(&mb->imr, RCVINT);

    return 0;
}

static int mace_close(struct net_device *dev)
{
    struct mace_data *mp = netdev_priv(dev);
    volatile struct mace __iomem *mb = mp->mace;
    volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
    volatile struct dbdma_regs __iomem *td = mp->tx_dma;

    /* disable rx and tx */
    out_8(&mb->maccc, 0);
    out_8(&mb->imr, 0xff);		/* disable all intrs */

    /* disable rx and tx dma */
    rd->control = cpu_to_le32((RUN|PAUSE|FLUSH|WAKE) << 16); /* clear run bit */
    td->control = cpu_to_le32((RUN|PAUSE|FLUSH|WAKE) << 16); /* clear run bit */

    mace_clean_rings(mp);

    return 0;
}

static inline void mace_set_timeout(struct net_device *dev)
{
    struct mace_data *mp = netdev_priv(dev);

    if (mp->timeout_active)
	del_timer(&mp->tx_timeout);
    mp->tx_timeout.expires = jiffies + TX_TIMEOUT;
    add_timer(&mp->tx_timeout);
    mp->timeout_active = 1;
}

static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
{
    struct mace_data *mp = netdev_priv(dev);
    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
    volatile struct dbdma_cmd *cp, *np;
    unsigned long flags;
    int fill, next, len;

    /* see if there's a free slot in the tx ring */
    spin_lock_irqsave(&mp->lock, flags);
    fill = mp->tx_fill;
    next = fill + 1;
    if (next >= N_TX_RING)
	next = 0;
    if (next == mp->tx_empty) {
	netif_stop_queue(dev);
	mp->tx_fullup = 1;
	spin_unlock_irqrestore(&mp->lock, flags);
	return NETDEV_TX_BUSY;		/* can't take it at the moment */
    }
    spin_unlock_irqrestore(&mp->lock, flags);

    /* partially fill in the dma command block */
    len = skb->len;
    if (len > ETH_FRAME_LEN) {
	printk(KERN_DEBUG "mace: xmit frame too long (%d)\n", len);
	len = ETH_FRAME_LEN;
    }
    mp->tx_bufs[fill] = skb;
    cp = mp->tx_cmds + NCMDS_TX * fill;
    cp->req_count = cpu_to_le16(len);
    cp->phy_addr = cpu_to_le32(virt_to_bus(skb->data));

    np = mp->tx_cmds + NCMDS_TX * next;
    out_le16(&np->command, DBDMA_STOP);

    /* poke the tx dma channel */
    spin_lock_irqsave(&mp->lock, flags);
    mp->tx_fill = next;
    if (!mp->tx_bad_runt && mp->tx_active < MAX_TX_ACTIVE) {
	out_le16(&cp->xfer_status, 0);
	out_le16(&cp->command, OUTPUT_LAST);
	out_le32(&td->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
	++mp->tx_active;
	mace_set_timeout(dev);
    }
    if (++next >= N_TX_RING)
	next = 0;
    if (next == mp->tx_empty)
	netif_stop_queue(dev);
    spin_unlock_irqrestore(&mp->lock, flags);

    return NETDEV_TX_OK;
}

static void mace_set_multicast(struct net_device *dev)
{
    struct mace_data *mp = netdev_priv(dev);
    volatile struct mace __iomem *mb = mp->mace;
    int i;
    u32 crc;
    unsigned long flags;

    spin_lock_irqsave(&mp->lock, flags);
    mp->maccc &= ~PROM;
    if (dev->flags & IFF_PROMISC) {
	mp->maccc |= PROM;
    } else {
	unsigned char multicast_filter[8];
	struct netdev_hw_addr *ha;

	if (dev->flags & IFF_ALLMULTI) {
	    for (i = 0; i < 8; i++)
		multicast_filter[i] = 0xff;
	} else {
	    for (i = 0; i < 8; i++)
		multicast_filter[i] = 0;
	    netdev_for_each_mc_addr(ha, dev) {
	        crc = ether_crc_le(6, ha->addr);
		i = crc >> 26;	/* bit number in multicast_filter */
		multicast_filter[i >> 3] |= 1 << (i & 7);
	    }
	}
#if 0
	printk("Multicast filter :");
	for (i = 0; i < 8; i++)
	    printk("%02x ", multicast_filter[i]);
	printk("\n");
#endif

	if (mp->chipid == BROKEN_ADDRCHG_REV)
	    out_8(&mb->iac, LOGADDR);
	else {
	    out_8(&mb->iac, ADDRCHG | LOGADDR);
	    while ((in_8(&mb->iac) & ADDRCHG) != 0)
		;
	}
	for (i = 0; i < 8; ++i)
	    out_8(&mb->ladrf, multicast_filter[i]);
	if (mp->chipid != BROKEN_ADDRCHG_REV)
	    out_8(&mb->iac, 0);
    }
    /* reset maccc */
    out_8(&mb->maccc, mp->maccc);
    spin_unlock_irqrestore(&mp->lock, flags);
}

static void mace_handle_misc_intrs(struct mace_data *mp, int intr, struct net_device *dev)
{
    volatile struct mace __iomem *mb = mp->mace;
    static int mace_babbles, mace_jabbers;

    if (intr & MPCO)
	dev->stats.rx_missed_errors += 256;
    dev->stats.rx_missed_errors += in_8(&mb->mpc);   /* reading clears it */
    if (intr & RNTPCO)
	dev->stats.rx_length_errors += 256;
    dev->stats.rx_length_errors += in_8(&mb->rntpc); /* reading clears it */
    if (intr & CERR)
	++dev->stats.tx_heartbeat_errors;
    if (intr & BABBLE)
	if (mace_babbles++ < 4)
	    printk(KERN_DEBUG "mace: babbling transmitter\n");
    if (intr & JABBER)
	if (mace_jabbers++ < 4)
	    printk(KERN_DEBUG "mace: jabbering transceiver\n");
}

static irqreturn_t mace_interrupt(int irq, void *dev_id)
{
    struct net_device *dev = (struct net_device *) dev_id;
    struct mace_data *mp = netdev_priv(dev);
    volatile struct mace __iomem *mb = mp->mace;
    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
    volatile struct dbdma_cmd *cp;
    int intr, fs, i, stat, x;
    int xcount, dstat;
    unsigned long flags;
    /* static int mace_last_fs, mace_last_xcount; */

    spin_lock_irqsave(&mp->lock, flags);
    intr = in_8(&mb->ir);		/* read interrupt register */
    in_8(&mb->xmtrc);			/* get retries */
    mace_handle_misc_intrs(mp, intr, dev);

    i = mp->tx_empty;
    while (in_8(&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
	 * the DMA controller.
	 */
	intr = in_8(&mb->ir);
	if (intr != 0)
	    mace_handle_misc_intrs(mp, intr, dev);
	if (mp->tx_bad_runt) {
	    fs = in_8(&mb->xmtfs);
	    mp->tx_bad_runt = 0;
	    out_8(&mb->xmtfc, AUTO_PAD_XMIT);
	    continue;
	}
	dstat = le32_to_cpu(td->status);
	/* stop DMA controller */
	out_le32(&td->control, RUN << 16);
	/*
	 * xcount is the number of complete frames which have been
	 * written to the fifo but for which status has not been read.
	 */
	xcount = (in_8(&mb->fifofc) >> XMTFC_SH) & XMTFC_MASK;
	if (xcount == 0 || (dstat & DEAD)) {
	    /*
	     * If a packet was aborted before the DMA controller has
	     * finished transferring it, it seems that there are 2 bytes
	     * which are stuck in some buffer somewhere.  These will get
	     * transmitted as soon as we read the frame status (which
	     * reenables the transmit data transfer request).  Turning
	     * off the DMA controller and/or resetting the MACE doesn't
	     * help.  So we disable auto-padding and FCS transmission
	     * so the two bytes will only be a runt packet which should
	     * be ignored by other stations.
	     */
	    out_8(&mb->xmtfc, DXMTFCS);
	}
	fs = in_8(&mb->xmtfs);
	if ((fs & XMTSV) == 0) {
	    printk(KERN_ERR "mace: xmtfs not valid! (fs=%x xc=%d ds=%x)\n",
		   fs, xcount, dstat);
	    mace_reset(dev);
		/*
		 * XXX mace likes to hang the machine after a xmtfs error.
		 * This is hard to reproduce, resetting *may* help
		 */
	}
	cp = mp->tx_cmds + NCMDS_TX * i;
	stat = le16_to_cpu(cp->xfer_status);
	if ((fs & (UFLO|LCOL|LCAR|RTRY)) || (dstat & DEAD) || xcount == 0) {
	    /*
	     * Check whether there were in fact 2 bytes written to
	     * the transmit FIFO.
	     */
	    udelay(1);
	    x = (in_8(&mb->fifofc) >> XMTFC_SH) & XMTFC_MASK;
	    if (x != 0) {
		/* there were two bytes with an end-of-packet indication */
		mp->tx_bad_runt = 1;
		mace_set_timeout(dev);
	    } else {
		/*
		 * Either there weren't the two bytes buffered up, or they
		 * 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).
		 */
		out_8(&mb->maccc, in_8(&mb->maccc) & ~ENXMT);
		out_8(&mb->fifocc, in_8(&mb->fifocc) | XMTFWU);
		udelay(1);
		out_8(&mb->maccc, in_8(&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);
	    continue;
	}
	/* Update stats */
	if (fs & (UFLO|LCOL|LCAR|RTRY)) {
	    ++dev->stats.tx_errors;
	    if (fs & LCAR)
		++dev->stats.tx_carrier_errors;
	    if (fs & (UFLO|LCOL|RTRY))
		++dev->stats.tx_aborted_errors;
	} else {
	    dev->stats.tx_bytes += mp->tx_bufs[i]->len;
	    ++dev->stats.tx_packets;
	}
	dev_consume_skb_irq(mp->tx_bufs[i]);
	--mp->tx_active;
	if (++i >= N_TX_RING)
	    i = 0;
#if 0
	mace_last_fs = fs;
	mace_last_xcount = xcount;
#endif
    }

    if (i != mp->tx_empty) {
	mp->tx_fullup = 0;
	netif_wake_queue(dev);
    }
    mp->tx_empty = i;
    i += mp->tx_active;
    if (i >= N_TX_RING)
	i -= N_TX_RING;
    if (!mp->tx_bad_runt && i != mp->tx_fill && mp->tx_active < MAX_TX_ACTIVE) {
	do {
	    /* set up the next one */
	    cp = mp->tx_cmds + NCMDS_TX * i;
	    out_le16(&cp->xfer_status, 0);
	    out_le16(&cp->command, OUTPUT_LAST);
	    ++mp->tx_active;
	    if (++i >= N_TX_RING)
		i = 0;
	} while (i != mp->tx_fill && mp->tx_active < MAX_TX_ACTIVE);
	out_le32(&td->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
	mace_set_timeout(dev);
    }
    spin_unlock_irqrestore(&mp->lock, flags);
    return IRQ_HANDLED;
}

static void mace_tx_timeout(struct timer_list *t)
{
    struct mace_data *mp = from_timer(mp, t, tx_timeout);
    struct net_device *dev = macio_get_drvdata(mp->mdev);
    volatile struct mace __iomem *mb = mp->mace;
    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
    volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
    volatile struct dbdma_cmd *cp;
    unsigned long flags;
    int i;

    spin_lock_irqsave(&mp->lock, flags);
    mp->timeout_active = 0;
    if (mp->tx_active == 0 && !mp->tx_bad_runt)
	goto out;

    /* update various counters */
    mace_handle_misc_intrs(mp, in_8(&mb->ir), dev);

    cp = mp->tx_cmds + NCMDS_TX * mp->tx_empty;

    /* turn off both tx and rx and reset the chip */
    out_8(&mb->maccc, 0);
    printk(KERN_ERR "mace: transmit timeout - resetting\n");
    dbdma_reset(td);
    mace_reset(dev);

    /* restart rx dma */
    cp = bus_to_virt(le32_to_cpu(rd->cmdptr));
    dbdma_reset(rd);
    out_le16(&cp->xfer_status, 0);
    out_le32(&rd->cmdptr, virt_to_bus(cp));
    out_le32(&rd->control, (RUN << 16) | RUN);

    /* fix up the transmit side */
    i = mp->tx_empty;
    mp->tx_active = 0;
    ++dev->stats.tx_errors;
    if (mp->tx_bad_runt) {
	mp->tx_bad_runt = 0;
    } else if (i != mp->tx_fill) {
	dev_kfree_skb(mp->tx_bufs[i]);
	if (++i >= N_TX_RING)
	    i = 0;
	mp->tx_empty = i;
    }
    mp->tx_fullup = 0;
    netif_wake_queue(dev);
    if (i != mp->tx_fill) {
	cp = mp->tx_cmds + NCMDS_TX * i;
	out_le16(&cp->xfer_status, 0);
	out_le16(&cp->command, OUTPUT_LAST);
	out_le32(&td->cmdptr, virt_to_bus(cp));
	out_le32(&td->control, (RUN << 16) | RUN);
	++mp->tx_active;
	mace_set_timeout(dev);
    }

    /* turn it back on */
    out_8(&mb->imr, RCVINT);
    out_8(&mb->maccc, mp->maccc);

out:
    spin_unlock_irqrestore(&mp->lock, flags);
}

static irqreturn_t mace_txdma_intr(int irq, void *dev_id)
{
	return IRQ_HANDLED;
}

static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
{
    struct net_device *dev = (struct net_device *) dev_id;
    struct mace_data *mp = netdev_priv(dev);
    volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
    volatile struct dbdma_cmd *cp, *np;
    int i, nb, stat, next;
    struct sk_buff *skb;
    unsigned frame_status;
    static int mace_lost_status;
    unsigned char *data;
    unsigned long flags;

    spin_lock_irqsave(&mp->lock, flags);
    for (i = mp->rx_empty; i != mp->rx_fill; ) {
	cp = mp->rx_cmds + i;
	stat = le16_to_cpu(cp->xfer_status);
	if ((stat & ACTIVE) == 0) {
	    next = i + 1;
	    if (next >= N_RX_RING)
		next = 0;
	    np = mp->rx_cmds + next;
	    if (next != mp->rx_fill &&
		(le16_to_cpu(np->xfer_status) & ACTIVE) != 0) {
		printk(KERN_DEBUG "mace: lost a status word\n");
		++mace_lost_status;
	    } else
		break;
	}
	nb = le16_to_cpu(cp->req_count) - le16_to_cpu(cp->res_count);
	out_le16(&cp->command, DBDMA_STOP);
	/* got a packet, have a look at it */
	skb = mp->rx_bufs[i];
	if (!skb) {
	    ++dev->stats.rx_dropped;
	} else if (nb > 8) {
	    data = skb->data;
	    frame_status = (data[nb-3] << 8) + data[nb-4];
	    if (frame_status & (RS_OFLO|RS_CLSN|RS_FRAMERR|RS_FCSERR)) {
		++dev->stats.rx_errors;
		if (frame_status & RS_OFLO)
		    ++dev->stats.rx_over_errors;
		if (frame_status & RS_FRAMERR)
		    ++dev->stats.rx_frame_errors;
		if (frame_status & RS_FCSERR)
		    ++dev->stats.rx_crc_errors;
	    } else {
		/* Mace feature AUTO_STRIP_RCV is on by default, dropping the
		 * FCS on frames with 802.3 headers. This means that Ethernet
		 * frames have 8 extra octets at the end, while 802.3 frames
		 * have only 4. We need to correctly account for this. */
		if (*(unsigned short *)(data+12) < 1536) /* 802.3 header */
		    nb -= 4;
		else	/* Ethernet header; mace includes FCS */
		    nb -= 8;
		skb_put(skb, nb);
		skb->protocol = eth_type_trans(skb, dev);
		dev->stats.rx_bytes += skb->len;
		netif_rx(skb);
		mp->rx_bufs[i] = NULL;
		++dev->stats.rx_packets;
	    }
	} else {
	    ++dev->stats.rx_errors;
	    ++dev->stats.rx_length_errors;
	}

	/* advance to next */
	if (++i >= N_RX_RING)
	    i = 0;
    }
    mp->rx_empty = i;

    i = mp->rx_fill;
    for (;;) {
	next = i + 1;
	if (next >= N_RX_RING)
	    next = 0;
	if (next == mp->rx_empty)
	    break;
	cp = mp->rx_cmds + i;
	skb = mp->rx_bufs[i];
	if (!skb) {
	    skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
	    if (skb) {
		skb_reserve(skb, 2);
		mp->rx_bufs[i] = skb;
	    }
	}
	cp->req_count = cpu_to_le16(RX_BUFLEN);
	data = skb? skb->data: dummy_buf;
	cp->phy_addr = cpu_to_le32(virt_to_bus(data));
	out_le16(&cp->xfer_status, 0);
	out_le16(&cp->command, INPUT_LAST + INTR_ALWAYS);
#if 0
	if ((le32_to_cpu(rd->status) & ACTIVE) != 0) {
	    out_le32(&rd->control, (PAUSE << 16) | PAUSE);
	    while ((in_le32(&rd->status) & ACTIVE) != 0)
		;
	}
#endif
	i = next;
    }
    if (i != mp->rx_fill) {
	out_le32(&rd->control, ((RUN|WAKE) << 16) | (RUN|WAKE));
	mp->rx_fill = i;
    }
    spin_unlock_irqrestore(&mp->lock, flags);
    return IRQ_HANDLED;
}

static const struct of_device_id mace_match[] =
{
	{
	.name 		= "mace",
	},
	{},
};
MODULE_DEVICE_TABLE (of, mace_match);

static struct macio_driver mace_driver =
{
	.driver = {
		.name 		= "mace",
		.owner		= THIS_MODULE,
		.of_match_table	= mace_match,
	},
	.probe		= mace_probe,
	.remove		= mace_remove,
};


static int __init mace_init(void)
{
	return macio_register_driver(&mace_driver);
}

static void __exit mace_cleanup(void)
{
	macio_unregister_driver(&mace_driver);

	kfree(dummy_buf);
	dummy_buf = NULL;
}

MODULE_AUTHOR("Paul Mackerras");
MODULE_DESCRIPTION("PowerMac MACE driver.");
module_param(port_aaui, int, 0);
MODULE_PARM_DESC(port_aaui, "MACE uses AAUI port (0-1)");
MODULE_LICENSE("GPL");

module_init(mace_init);
module_exit(mace_cleanup);
