// SPDX-License-Identifier: GPL-2.0-only
/*
 * 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 <linux/pgtable.h>
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.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);
