// SPDX-License-Identifier: GPL-2.0-or-later
/*	(c) Copyright 1998 Alan Cox <alan@lxorguk.ukuu.org.uk>
 *	(c) Copyright 2000, 2001 Red Hat Inc
 *
 *	Development of this driver was funded by Equiinet Ltd
 *			http://www.equiinet.com
 *
 *	ChangeLog:
 *
 *	Asynchronous mode dropped for 2.2. For 2.5 we will attempt the
 *	unification of all the Z85x30 asynchronous drivers for real.
 *
 *	DMA now uses get_free_page as kmalloc buffers may span a 64K
 *	boundary.
 *
 *	Modified for SMP safety and SMP locking by Alan Cox
 *					<alan@lxorguk.ukuu.org.uk>
 *
 *	Performance
 *
 *	Z85230:
 *	Non DMA you want a 486DX50 or better to do 64Kbits. 9600 baud
 *	X.25 is not unrealistic on all machines. DMA mode can in theory
 *	handle T1/E1 quite nicely. In practice the limit seems to be about
 *	512Kbit->1Mbit depending on motherboard.
 *
 *	Z85C30:
 *	64K will take DMA, 9600 baud X.25 should be ok.
 *
 *	Z8530:
 *	Synchronous mode without DMA is unlikely to pass about 2400 baud.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/delay.h>
#include <linux/hdlc.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/gfp.h>
#include <asm/dma.h>
#include <asm/io.h>
#define RT_LOCK
#define RT_UNLOCK
#include <linux/spinlock.h>

#include "z85230.h"

/**
 *	z8530_read_port - Architecture specific interface function
 *	@p: port to read
 *
 *	Provided port access methods. The Comtrol SV11 requires no delays
 *	between accesses and uses PC I/O. Some drivers may need a 5uS delay
 *
 *	In the longer term this should become an architecture specific
 *	section so that this can become a generic driver interface for all
 *	platforms. For now we only handle PC I/O ports with or without the
 *	dread 5uS sanity delay.
 *
 *	The caller must hold sufficient locks to avoid violating the horrible
 *	5uS delay rule.
 */

static inline int z8530_read_port(unsigned long p)
{
	u8 r = inb(Z8530_PORT_OF(p));

	if (p & Z8530_PORT_SLEEP) /* gcc should figure this out efficiently ! */
		udelay(5);
	return r;
}

/**
 *	z8530_write_port - Architecture specific interface function
 *	@p: port to write
 *	@d: value to write
 *
 *	Write a value to a port with delays if need be. Note that the
 *	caller must hold locks to avoid read/writes from other contexts
 *	violating the 5uS rule
 *
 *	In the longer term this should become an architecture specific
 *	section so that this can become a generic driver interface for all
 *	platforms. For now we only handle PC I/O ports with or without the
 *	dread 5uS sanity delay.
 */

static inline void z8530_write_port(unsigned long p, u8 d)
{
	outb(d, Z8530_PORT_OF(p));
	if (p & Z8530_PORT_SLEEP)
		udelay(5);
}

static void z8530_rx_done(struct z8530_channel *c);
static void z8530_tx_done(struct z8530_channel *c);

/**
 *	read_zsreg - Read a register from a Z85230
 *	@c: Z8530 channel to read from (2 per chip)
 *	@reg: Register to read
 *	FIXME: Use a spinlock.
 *
 *	Most of the Z8530 registers are indexed off the control registers.
 *	A read is done by writing to the control register and reading the
 *	register back.  The caller must hold the lock
 */

static inline u8 read_zsreg(struct z8530_channel *c, u8 reg)
{
	if (reg)
		z8530_write_port(c->ctrlio, reg);
	return z8530_read_port(c->ctrlio);
}

/**
 *	read_zsdata - Read the data port of a Z8530 channel
 *	@c: The Z8530 channel to read the data port from
 *
 *	The data port provides fast access to some things. We still
 *	have all the 5uS delays to worry about.
 */

static inline u8 read_zsdata(struct z8530_channel *c)
{
	u8 r;

	r = z8530_read_port(c->dataio);
	return r;
}

/**
 *	write_zsreg - Write to a Z8530 channel register
 *	@c: The Z8530 channel
 *	@reg: Register number
 *	@val: Value to write
 *
 *	Write a value to an indexed register. The caller must hold the lock
 *	to honour the irritating delay rules. We know about register 0
 *	being fast to access.
 *
 *      Assumes c->lock is held.
 */
static inline void write_zsreg(struct z8530_channel *c, u8 reg, u8 val)
{
	if (reg)
		z8530_write_port(c->ctrlio, reg);
	z8530_write_port(c->ctrlio, val);
}

/**
 *	write_zsctrl - Write to a Z8530 control register
 *	@c: The Z8530 channel
 *	@val: Value to write
 *
 *	Write directly to the control register on the Z8530
 */

static inline void write_zsctrl(struct z8530_channel *c, u8 val)
{
	z8530_write_port(c->ctrlio, val);
}

/**
 *	write_zsdata - Write to a Z8530 control register
 *	@c: The Z8530 channel
 *	@val: Value to write
 *
 *	Write directly to the data register on the Z8530
 */
static inline void write_zsdata(struct z8530_channel *c, u8 val)
{
	z8530_write_port(c->dataio, val);
}

/*	Register loading parameters for a dead port
 */

u8 z8530_dead_port[] = {
	255
};
EXPORT_SYMBOL(z8530_dead_port);

/*	Register loading parameters for currently supported circuit types
 */

/*	Data clocked by telco end. This is the correct data for the UK
 *	"kilostream" service, and most other similar services.
 */

u8 z8530_hdlc_kilostream[] = {
	4,	SYNC_ENAB | SDLC | X1CLK,
	2,	0,	/* No vector */
	1,	0,
	3,	ENT_HM | RxCRC_ENAB | Rx8,
	5,	TxCRC_ENAB | RTS | TxENAB | Tx8 | DTR,
	9,	0,		/* Disable interrupts */
	6,	0xFF,
	7,	FLAG,
	10,	ABUNDER | NRZ | CRCPS,/*MARKIDLE ??*/
	11,	TCTRxCP,
	14,	DISDPLL,
	15,	DCDIE | SYNCIE | CTSIE | TxUIE | BRKIE,
	1,	EXT_INT_ENAB | TxINT_ENAB | INT_ALL_Rx,
	9,	NV | MIE | NORESET,
	255
};
EXPORT_SYMBOL(z8530_hdlc_kilostream);

/*	As above but for enhanced chips.
 */

u8 z8530_hdlc_kilostream_85230[] = {
	4,	SYNC_ENAB | SDLC | X1CLK,
	2,	0,	/* No vector */
	1,	0,
	3,	ENT_HM | RxCRC_ENAB | Rx8,
	5,	TxCRC_ENAB | RTS | TxENAB | Tx8 | DTR,
	9,	0,		/* Disable interrupts */
	6,	0xFF,
	7,	FLAG,
	10,	ABUNDER | NRZ | CRCPS,	/* MARKIDLE?? */
	11,	TCTRxCP,
	14,	DISDPLL,
	15,	DCDIE | SYNCIE | CTSIE | TxUIE | BRKIE,
	1,	EXT_INT_ENAB | TxINT_ENAB | INT_ALL_Rx,
	9,	NV | MIE | NORESET,
	23,	3,		/* Extended mode AUTO TX and EOM*/

	255
};
EXPORT_SYMBOL(z8530_hdlc_kilostream_85230);

/**
 *	z8530_flush_fifo - Flush on chip RX FIFO
 *	@c: Channel to flush
 *
 *	Flush the receive FIFO. There is no specific option for this, we
 *	blindly read bytes and discard them. Reading when there is no data
 *	is harmless. The 8530 has a 4 byte FIFO, the 85230 has 8 bytes.
 *
 *	All locking is handled for the caller. On return data may still be
 *	present if it arrived during the flush.
 */

static void z8530_flush_fifo(struct z8530_channel *c)
{
	read_zsreg(c, R1);
	read_zsreg(c, R1);
	read_zsreg(c, R1);
	read_zsreg(c, R1);
	if (c->dev->type == Z85230) {
		read_zsreg(c, R1);
		read_zsreg(c, R1);
		read_zsreg(c, R1);
		read_zsreg(c, R1);
	}
}

/**
 *	z8530_rtsdtr - Control the outgoing DTS/RTS line
 *	@c: The Z8530 channel to control;
 *	@set: 1 to set, 0 to clear
 *
 *	Sets or clears DTR/RTS on the requested line. All locking is handled
 *	by the caller. For now we assume all boards use the actual RTS/DTR
 *	on the chip. Apparently one or two don't. We'll scream about them
 *	later.
 */

static void z8530_rtsdtr(struct z8530_channel *c, int set)
{
	if (set)
		c->regs[5] |= (RTS | DTR);
	else
		c->regs[5] &= ~(RTS | DTR);
	write_zsreg(c, R5, c->regs[5]);
}

/**
 *	z8530_rx - Handle a PIO receive event
 *	@c: Z8530 channel to process
 *
 *	Receive handler for receiving in PIO mode. This is much like the
 *	async one but not quite the same or as complex
 *
 *	Note: Its intended that this handler can easily be separated from
 *	the main code to run realtime. That'll be needed for some machines
 *	(eg to ever clock 64kbits on a sparc ;)).
 *
 *	The RT_LOCK macros don't do anything now. Keep the code covered
 *	by them as short as possible in all circumstances - clocks cost
 *	baud. The interrupt handler is assumed to be atomic w.r.t. to
 *	other code - this is true in the RT case too.
 *
 *	We only cover the sync cases for this. If you want 2Mbit async
 *	do it yourself but consider medical assistance first. This non DMA
 *	synchronous mode is portable code. The DMA mode assumes PCI like
 *	ISA DMA
 *
 *	Called with the device lock held
 */

static void z8530_rx(struct z8530_channel *c)
{
	u8 ch, stat;

	while (1) {
		/* FIFO empty ? */
		if (!(read_zsreg(c, R0) & 1))
			break;
		ch = read_zsdata(c);
		stat = read_zsreg(c, R1);

		/*	Overrun ?
		 */
		if (c->count < c->max) {
			*c->dptr++ = ch;
			c->count++;
		}

		if (stat & END_FR) {
			/*	Error ?
			 */
			if (stat & (Rx_OVR | CRC_ERR)) {
				/* Rewind the buffer and return */
				if (c->skb)
					c->dptr = c->skb->data;
				c->count = 0;
				if (stat & Rx_OVR) {
					pr_warn("%s: overrun\n", c->dev->name);
					c->rx_overrun++;
				}
				if (stat & CRC_ERR) {
					c->rx_crc_err++;
					/* printk("crc error\n"); */
				}
				/* Shove the frame upstream */
			} else {
				/*	Drop the lock for RX processing, or
				 *	there are deadlocks
				 */
				z8530_rx_done(c);
				write_zsctrl(c, RES_Rx_CRC);
			}
		}
	}
	/*	Clear irq
	 */
	write_zsctrl(c, ERR_RES);
	write_zsctrl(c, RES_H_IUS);
}

/**
 *	z8530_tx - Handle a PIO transmit event
 *	@c: Z8530 channel to process
 *
 *	Z8530 transmit interrupt handler for the PIO mode. The basic
 *	idea is to attempt to keep the FIFO fed. We fill as many bytes
 *	in as possible, its quite possible that we won't keep up with the
 *	data rate otherwise.
 */

static void z8530_tx(struct z8530_channel *c)
{
	while (c->txcount) {
		/* FIFO full ? */
		if (!(read_zsreg(c, R0) & 4))
			return;
		c->txcount--;
		/*	Shovel out the byte
		 */
		write_zsreg(c, R8, *c->tx_ptr++);
		write_zsctrl(c, RES_H_IUS);
		/* We are about to underflow */
		if (c->txcount == 0) {
			write_zsctrl(c, RES_EOM_L);
			write_zsreg(c, R10, c->regs[10] & ~ABUNDER);
		}
	}

	/*	End of frame TX - fire another one
	 */

	write_zsctrl(c, RES_Tx_P);

	z8530_tx_done(c);
	write_zsctrl(c, RES_H_IUS);
}

/**
 *	z8530_status - Handle a PIO status exception
 *	@chan: Z8530 channel to process
 *
 *	A status event occurred in PIO synchronous mode. There are several
 *	reasons the chip will bother us here. A transmit underrun means we
 *	failed to feed the chip fast enough and just broke a packet. A DCD
 *	change is a line up or down.
 */

static void z8530_status(struct z8530_channel *chan)
{
	u8 status, altered;

	status = read_zsreg(chan, R0);
	altered = chan->status ^ status;

	chan->status = status;

	if (status & TxEOM) {
/*		printk("%s: Tx underrun.\n", chan->dev->name); */
		chan->netdevice->stats.tx_fifo_errors++;
		write_zsctrl(chan, ERR_RES);
		z8530_tx_done(chan);
	}

	if (altered & chan->dcdcheck) {
		if (status & chan->dcdcheck) {
			pr_info("%s: DCD raised\n", chan->dev->name);
			write_zsreg(chan, R3, chan->regs[3] | RxENABLE);
			if (chan->netdevice)
				netif_carrier_on(chan->netdevice);
		} else {
			pr_info("%s: DCD lost\n", chan->dev->name);
			write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE);
			z8530_flush_fifo(chan);
			if (chan->netdevice)
				netif_carrier_off(chan->netdevice);
		}
	}
	write_zsctrl(chan, RES_EXT_INT);
	write_zsctrl(chan, RES_H_IUS);
}

struct z8530_irqhandler z8530_sync = {
	.rx = z8530_rx,
	.tx = z8530_tx,
	.status = z8530_status,
};
EXPORT_SYMBOL(z8530_sync);

/**
 *	z8530_dma_rx - Handle a DMA RX event
 *	@chan: Channel to handle
 *
 *	Non bus mastering DMA interfaces for the Z8x30 devices. This
 *	is really pretty PC specific. The DMA mode means that most receive
 *	events are handled by the DMA hardware. We get a kick here only if
 *	a frame ended.
 */

static void z8530_dma_rx(struct z8530_channel *chan)
{
	if (chan->rxdma_on) {
		/* Special condition check only */
		u8 status;

		read_zsreg(chan, R7);
		read_zsreg(chan, R6);

		status = read_zsreg(chan, R1);

		if (status & END_FR)
			z8530_rx_done(chan);	/* Fire up the next one */

		write_zsctrl(chan, ERR_RES);
		write_zsctrl(chan, RES_H_IUS);
	} else {
		/* DMA is off right now, drain the slow way */
		z8530_rx(chan);
	}
}

/**
 *	z8530_dma_tx - Handle a DMA TX event
 *	@chan:	The Z8530 channel to handle
 *
 *	We have received an interrupt while doing DMA transmissions. It
 *	shouldn't happen. Scream loudly if it does.
 */
static void z8530_dma_tx(struct z8530_channel *chan)
{
	if (!chan->dma_tx) {
		pr_warn("Hey who turned the DMA off?\n");
		z8530_tx(chan);
		return;
	}
	/* This shouldn't occur in DMA mode */
	pr_err("DMA tx - bogus event!\n");
	z8530_tx(chan);
}

/**
 *	z8530_dma_status - Handle a DMA status exception
 *	@chan: Z8530 channel to process
 *
 *	A status event occurred on the Z8530. We receive these for two reasons
 *	when in DMA mode. Firstly if we finished a packet transfer we get one
 *	and kick the next packet out. Secondly we may see a DCD change.
 *
 */
static void z8530_dma_status(struct z8530_channel *chan)
{
	u8 status, altered;

	status = read_zsreg(chan, R0);
	altered = chan->status ^ status;

	chan->status = status;

	if (chan->dma_tx) {
		if (status & TxEOM) {
			unsigned long flags;

			flags = claim_dma_lock();
			disable_dma(chan->txdma);
			clear_dma_ff(chan->txdma);
			chan->txdma_on = 0;
			release_dma_lock(flags);
			z8530_tx_done(chan);
		}
	}

	if (altered & chan->dcdcheck) {
		if (status & chan->dcdcheck) {
			pr_info("%s: DCD raised\n", chan->dev->name);
			write_zsreg(chan, R3, chan->regs[3] | RxENABLE);
			if (chan->netdevice)
				netif_carrier_on(chan->netdevice);
		} else {
			pr_info("%s: DCD lost\n", chan->dev->name);
			write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE);
			z8530_flush_fifo(chan);
			if (chan->netdevice)
				netif_carrier_off(chan->netdevice);
		}
	}

	write_zsctrl(chan, RES_EXT_INT);
	write_zsctrl(chan, RES_H_IUS);
}

static struct z8530_irqhandler z8530_dma_sync = {
	.rx = z8530_dma_rx,
	.tx = z8530_dma_tx,
	.status = z8530_dma_status,
};

static struct z8530_irqhandler z8530_txdma_sync = {
	.rx = z8530_rx,
	.tx = z8530_dma_tx,
	.status = z8530_dma_status,
};

/**
 *	z8530_rx_clear - Handle RX events from a stopped chip
 *	@c: Z8530 channel to shut up
 *
 *	Receive interrupt vectors for a Z8530 that is in 'parked' mode.
 *	For machines with PCI Z85x30 cards, or level triggered interrupts
 *	(eg the MacII) we must clear the interrupt cause or die.
 */

static void z8530_rx_clear(struct z8530_channel *c)
{
	/*	Data and status bytes
	 */
	u8 stat;

	read_zsdata(c);
	stat = read_zsreg(c, R1);

	if (stat & END_FR)
		write_zsctrl(c, RES_Rx_CRC);
	/*	Clear irq
	 */
	write_zsctrl(c, ERR_RES);
	write_zsctrl(c, RES_H_IUS);
}

/**
 *	z8530_tx_clear - Handle TX events from a stopped chip
 *	@c: Z8530 channel to shut up
 *
 *	Transmit interrupt vectors for a Z8530 that is in 'parked' mode.
 *	For machines with PCI Z85x30 cards, or level triggered interrupts
 *	(eg the MacII) we must clear the interrupt cause or die.
 */

static void z8530_tx_clear(struct z8530_channel *c)
{
	write_zsctrl(c, RES_Tx_P);
	write_zsctrl(c, RES_H_IUS);
}

/**
 *	z8530_status_clear - Handle status events from a stopped chip
 *	@chan: Z8530 channel to shut up
 *
 *	Status interrupt vectors for a Z8530 that is in 'parked' mode.
 *	For machines with PCI Z85x30 cards, or level triggered interrupts
 *	(eg the MacII) we must clear the interrupt cause or die.
 */

static void z8530_status_clear(struct z8530_channel *chan)
{
	u8 status = read_zsreg(chan, R0);

	if (status & TxEOM)
		write_zsctrl(chan, ERR_RES);
	write_zsctrl(chan, RES_EXT_INT);
	write_zsctrl(chan, RES_H_IUS);
}

struct z8530_irqhandler z8530_nop = {
	.rx = z8530_rx_clear,
	.tx = z8530_tx_clear,
	.status = z8530_status_clear,
};
EXPORT_SYMBOL(z8530_nop);

/**
 *	z8530_interrupt - Handle an interrupt from a Z8530
 *	@irq: Interrupt number
 *	@dev_id: The Z8530 device that is interrupting.
 *
 *	A Z85[2]30 device has stuck its hand in the air for attention.
 *	We scan both the channels on the chip for events and then call
 *	the channel specific call backs for each channel that has events.
 *	We have to use callback functions because the two channels can be
 *	in different modes.
 *
 *	Locking is done for the handlers. Note that locking is done
 *	at the chip level (the 5uS delay issue is per chip not per
 *	channel). c->lock for both channels points to dev->lock
 */

irqreturn_t z8530_interrupt(int irq, void *dev_id)
{
	struct z8530_dev *dev = dev_id;
	u8 intr;
	static volatile int locker=0;
	int work = 0;
	struct z8530_irqhandler *irqs;

	if (locker) {
		pr_err("IRQ re-enter\n");
		return IRQ_NONE;
	}
	locker = 1;

	spin_lock(&dev->lock);

	while (++work < 5000) {
		intr = read_zsreg(&dev->chanA, R3);
		if (!(intr &
		   (CHARxIP | CHATxIP | CHAEXT | CHBRxIP | CHBTxIP | CHBEXT)))
			break;

		/* This holds the IRQ status. On the 8530 you must read it
		 * from chan A even though it applies to the whole chip
		 */

		/* Now walk the chip and see what it is wanting - it may be
		 * an IRQ for someone else remember
		 */

		irqs = dev->chanA.irqs;

		if (intr & (CHARxIP | CHATxIP | CHAEXT)) {
			if (intr & CHARxIP)
				irqs->rx(&dev->chanA);
			if (intr & CHATxIP)
				irqs->tx(&dev->chanA);
			if (intr & CHAEXT)
				irqs->status(&dev->chanA);
		}

		irqs = dev->chanB.irqs;

		if (intr & (CHBRxIP | CHBTxIP | CHBEXT)) {
			if (intr & CHBRxIP)
				irqs->rx(&dev->chanB);
			if (intr & CHBTxIP)
				irqs->tx(&dev->chanB);
			if (intr & CHBEXT)
				irqs->status(&dev->chanB);
		}
	}
	spin_unlock(&dev->lock);
	if (work == 5000)
		pr_err("%s: interrupt jammed - abort(0x%X)!\n",
		       dev->name, intr);
	/* Ok all done */
	locker = 0;
	return IRQ_HANDLED;
}
EXPORT_SYMBOL(z8530_interrupt);

static const u8 reg_init[16] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0x55, 0, 0, 0
};

/**
 *	z8530_sync_open - Open a Z8530 channel for PIO
 *	@dev:	The network interface we are using
 *	@c:	The Z8530 channel to open in synchronous PIO mode
 *
 *	Switch a Z8530 into synchronous mode without DMA assist. We
 *	raise the RTS/DTR and commence network operation.
 */
int z8530_sync_open(struct net_device *dev, struct z8530_channel *c)
{
	unsigned long flags;

	spin_lock_irqsave(c->lock, flags);

	c->sync = 1;
	c->mtu = dev->mtu + 64;
	c->count = 0;
	c->skb = NULL;
	c->skb2 = NULL;
	c->irqs = &z8530_sync;

	/* This loads the double buffer up */
	z8530_rx_done(c);	/* Load the frame ring */
	z8530_rx_done(c);	/* Load the backup frame */
	z8530_rtsdtr(c, 1);
	c->dma_tx = 0;
	c->regs[R1] |= TxINT_ENAB;
	write_zsreg(c, R1, c->regs[R1]);
	write_zsreg(c, R3, c->regs[R3] | RxENABLE);

	spin_unlock_irqrestore(c->lock, flags);
	return 0;
}
EXPORT_SYMBOL(z8530_sync_open);

/**
 *	z8530_sync_close - Close a PIO Z8530 channel
 *	@dev: Network device to close
 *	@c: Z8530 channel to disassociate and move to idle
 *
 *	Close down a Z8530 interface and switch its interrupt handlers
 *	to discard future events.
 */
int z8530_sync_close(struct net_device *dev, struct z8530_channel *c)
{
	u8 chk;
	unsigned long flags;

	spin_lock_irqsave(c->lock, flags);
	c->irqs = &z8530_nop;
	c->max = 0;
	c->sync = 0;

	chk = read_zsreg(c, R0);
	write_zsreg(c, R3, c->regs[R3]);
	z8530_rtsdtr(c, 0);

	spin_unlock_irqrestore(c->lock, flags);
	return 0;
}
EXPORT_SYMBOL(z8530_sync_close);

/**
 *	z8530_sync_dma_open - Open a Z8530 for DMA I/O
 *	@dev: The network device to attach
 *	@c: The Z8530 channel to configure in sync DMA mode.
 *
 *	Set up a Z85x30 device for synchronous DMA in both directions. Two
 *	ISA DMA channels must be available for this to work. We assume ISA
 *	DMA driven I/O and PC limits on access.
 */
int z8530_sync_dma_open(struct net_device *dev, struct z8530_channel *c)
{
	unsigned long cflags, dflags;

	c->sync = 1;
	c->mtu = dev->mtu + 64;
	c->count = 0;
	c->skb = NULL;
	c->skb2 = NULL;

	/*	Load the DMA interfaces up
	 */
	c->rxdma_on = 0;
	c->txdma_on = 0;

	/*	Allocate the DMA flip buffers. Limit by page size.
	 *	Everyone runs 1500 mtu or less on wan links so this
	 *	should be fine.
	 */

	if (c->mtu  > PAGE_SIZE / 2)
		return -EMSGSIZE;

	c->rx_buf[0] = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!c->rx_buf[0])
		return -ENOBUFS;
	c->rx_buf[1] = c->rx_buf[0] + PAGE_SIZE / 2;

	c->tx_dma_buf[0] = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!c->tx_dma_buf[0]) {
		free_page((unsigned long)c->rx_buf[0]);
		c->rx_buf[0] = NULL;
		return -ENOBUFS;
	}
	c->tx_dma_buf[1] = c->tx_dma_buf[0] + PAGE_SIZE / 2;

	c->tx_dma_used = 0;
	c->dma_tx = 1;
	c->dma_num = 0;
	c->dma_ready = 1;

	/*	Enable DMA control mode
	 */

	spin_lock_irqsave(c->lock, cflags);

	/*	TX DMA via DIR/REQ
	 */

	c->regs[R14] |= DTRREQ;
	write_zsreg(c, R14, c->regs[R14]);

	c->regs[R1] &= ~TxINT_ENAB;
	write_zsreg(c, R1, c->regs[R1]);

	/*	RX DMA via W/Req
	 */

	c->regs[R1] |= WT_FN_RDYFN;
	c->regs[R1] |= WT_RDY_RT;
	c->regs[R1] |= INT_ERR_Rx;
	c->regs[R1] &= ~TxINT_ENAB;
	write_zsreg(c, R1, c->regs[R1]);
	c->regs[R1] |= WT_RDY_ENAB;
	write_zsreg(c, R1, c->regs[R1]);

	/*	DMA interrupts
	 */

	/*	Set up the DMA configuration
	 */

	dflags = claim_dma_lock();

	disable_dma(c->rxdma);
	clear_dma_ff(c->rxdma);
	set_dma_mode(c->rxdma, DMA_MODE_READ | 0x10);
	set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[0]));
	set_dma_count(c->rxdma, c->mtu);
	enable_dma(c->rxdma);

	disable_dma(c->txdma);
	clear_dma_ff(c->txdma);
	set_dma_mode(c->txdma, DMA_MODE_WRITE);
	disable_dma(c->txdma);

	release_dma_lock(dflags);

	/*	Select the DMA interrupt handlers
	 */

	c->rxdma_on = 1;
	c->txdma_on = 1;
	c->tx_dma_used = 1;

	c->irqs = &z8530_dma_sync;
	z8530_rtsdtr(c, 1);
	write_zsreg(c, R3, c->regs[R3] | RxENABLE);

	spin_unlock_irqrestore(c->lock, cflags);

	return 0;
}
EXPORT_SYMBOL(z8530_sync_dma_open);

/**
 *	z8530_sync_dma_close - Close down DMA I/O
 *	@dev: Network device to detach
 *	@c: Z8530 channel to move into discard mode
 *
 *	Shut down a DMA mode synchronous interface. Halt the DMA, and
 *	free the buffers.
 */
int z8530_sync_dma_close(struct net_device *dev, struct z8530_channel *c)
{
	u8 chk;
	unsigned long flags;

	c->irqs = &z8530_nop;
	c->max = 0;
	c->sync = 0;

	/*	Disable the PC DMA channels
	 */

	flags = claim_dma_lock();
	disable_dma(c->rxdma);
	clear_dma_ff(c->rxdma);

	c->rxdma_on = 0;

	disable_dma(c->txdma);
	clear_dma_ff(c->txdma);
	release_dma_lock(flags);

	c->txdma_on = 0;
	c->tx_dma_used = 0;

	spin_lock_irqsave(c->lock, flags);

	/*	Disable DMA control mode
	 */

	c->regs[R1] &= ~WT_RDY_ENAB;
	write_zsreg(c, R1, c->regs[R1]);
	c->regs[R1] &= ~(WT_RDY_RT | WT_FN_RDYFN | INT_ERR_Rx);
	c->regs[R1] |= INT_ALL_Rx;
	write_zsreg(c, R1, c->regs[R1]);
	c->regs[R14] &= ~DTRREQ;
	write_zsreg(c, R14, c->regs[R14]);

	if (c->rx_buf[0]) {
		free_page((unsigned long)c->rx_buf[0]);
		c->rx_buf[0] = NULL;
	}
	if (c->tx_dma_buf[0]) {
		free_page((unsigned  long)c->tx_dma_buf[0]);
		c->tx_dma_buf[0] = NULL;
	}
	chk = read_zsreg(c, R0);
	write_zsreg(c, R3, c->regs[R3]);
	z8530_rtsdtr(c, 0);

	spin_unlock_irqrestore(c->lock, flags);

	return 0;
}
EXPORT_SYMBOL(z8530_sync_dma_close);

/**
 *	z8530_sync_txdma_open - Open a Z8530 for TX driven DMA
 *	@dev: The network device to attach
 *	@c: The Z8530 channel to configure in sync DMA mode.
 *
 *	Set up a Z85x30 device for synchronous DMA transmission. One
 *	ISA DMA channel must be available for this to work. The receive
 *	side is run in PIO mode, but then it has the bigger FIFO.
 */

int z8530_sync_txdma_open(struct net_device *dev, struct z8530_channel *c)
{
	unsigned long cflags, dflags;

	printk("Opening sync interface for TX-DMA\n");
	c->sync = 1;
	c->mtu = dev->mtu + 64;
	c->count = 0;
	c->skb = NULL;
	c->skb2 = NULL;

	/*	Allocate the DMA flip buffers. Limit by page size.
	 *	Everyone runs 1500 mtu or less on wan links so this
	 *	should be fine.
	 */

	if (c->mtu > PAGE_SIZE / 2)
		return -EMSGSIZE;

	c->tx_dma_buf[0] = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!c->tx_dma_buf[0])
		return -ENOBUFS;

	c->tx_dma_buf[1] = c->tx_dma_buf[0] + PAGE_SIZE / 2;

	spin_lock_irqsave(c->lock, cflags);

	/*	Load the PIO receive ring
	 */

	z8530_rx_done(c);
	z8530_rx_done(c);

	/*	Load the DMA interfaces up
	 */

	c->rxdma_on = 0;
	c->txdma_on = 0;

	c->tx_dma_used = 0;
	c->dma_num = 0;
	c->dma_ready = 1;
	c->dma_tx = 1;

	/*	Enable DMA control mode
	 */

	/*	TX DMA via DIR/REQ
	 */
	c->regs[R14] |= DTRREQ;
	write_zsreg(c, R14, c->regs[R14]);

	c->regs[R1] &= ~TxINT_ENAB;
	write_zsreg(c, R1, c->regs[R1]);

	/*	Set up the DMA configuration
	 */

	dflags = claim_dma_lock();

	disable_dma(c->txdma);
	clear_dma_ff(c->txdma);
	set_dma_mode(c->txdma, DMA_MODE_WRITE);
	disable_dma(c->txdma);

	release_dma_lock(dflags);

	/*	Select the DMA interrupt handlers
	 */

	c->rxdma_on = 0;
	c->txdma_on = 1;
	c->tx_dma_used = 1;

	c->irqs = &z8530_txdma_sync;
	z8530_rtsdtr(c, 1);
	write_zsreg(c, R3, c->regs[R3] | RxENABLE);
	spin_unlock_irqrestore(c->lock, cflags);

	return 0;
}
EXPORT_SYMBOL(z8530_sync_txdma_open);

/**
 *	z8530_sync_txdma_close - Close down a TX driven DMA channel
 *	@dev: Network device to detach
 *	@c: Z8530 channel to move into discard mode
 *
 *	Shut down a DMA/PIO split mode synchronous interface. Halt the DMA,
 *	and  free the buffers.
 */

int z8530_sync_txdma_close(struct net_device *dev, struct z8530_channel *c)
{
	unsigned long dflags, cflags;
	u8 chk;

	spin_lock_irqsave(c->lock, cflags);

	c->irqs = &z8530_nop;
	c->max = 0;
	c->sync = 0;

	/*	Disable the PC DMA channels
	 */

	dflags = claim_dma_lock();

	disable_dma(c->txdma);
	clear_dma_ff(c->txdma);
	c->txdma_on = 0;
	c->tx_dma_used = 0;

	release_dma_lock(dflags);

	/*	Disable DMA control mode
	 */

	c->regs[R1] &= ~WT_RDY_ENAB;
	write_zsreg(c, R1, c->regs[R1]);
	c->regs[R1] &= ~(WT_RDY_RT | WT_FN_RDYFN | INT_ERR_Rx);
	c->regs[R1] |= INT_ALL_Rx;
	write_zsreg(c, R1, c->regs[R1]);
	c->regs[R14] &= ~DTRREQ;
	write_zsreg(c, R14, c->regs[R14]);

	if (c->tx_dma_buf[0]) {
		free_page((unsigned long)c->tx_dma_buf[0]);
		c->tx_dma_buf[0] = NULL;
	}
	chk = read_zsreg(c, R0);
	write_zsreg(c, R3, c->regs[R3]);
	z8530_rtsdtr(c, 0);

	spin_unlock_irqrestore(c->lock, cflags);
	return 0;
}
EXPORT_SYMBOL(z8530_sync_txdma_close);

/*	Name strings for Z8530 chips. SGI claim to have a 130, Zilog deny
 *	it exists...
 */
static const char * const z8530_type_name[] = {
	"Z8530",
	"Z85C30",
	"Z85230"
};

/**
 *	z8530_describe - Uniformly describe a Z8530 port
 *	@dev: Z8530 device to describe
 *	@mapping: string holding mapping type (eg "I/O" or "Mem")
 *	@io: the port value in question
 *
 *	Describe a Z8530 in a standard format. We must pass the I/O as
 *	the port offset isn't predictable. The main reason for this function
 *	is to try and get a common format of report.
 */

void z8530_describe(struct z8530_dev *dev, char *mapping, unsigned long io)
{
	pr_info("%s: %s found at %s 0x%lX, IRQ %d\n",
		dev->name,
		z8530_type_name[dev->type],
		mapping,
		Z8530_PORT_OF(io),
		dev->irq);
}
EXPORT_SYMBOL(z8530_describe);

/*	Locked operation part of the z8530 init code
 */
static inline int do_z8530_init(struct z8530_dev *dev)
{
	/* NOP the interrupt handlers first - we might get a
	 * floating IRQ transition when we reset the chip
	 */
	dev->chanA.irqs = &z8530_nop;
	dev->chanB.irqs = &z8530_nop;
	dev->chanA.dcdcheck = DCD;
	dev->chanB.dcdcheck = DCD;

	/* Reset the chip */
	write_zsreg(&dev->chanA, R9, 0xC0);
	udelay(200);
	/* Now check its valid */
	write_zsreg(&dev->chanA, R12, 0xAA);
	if (read_zsreg(&dev->chanA, R12) != 0xAA)
		return -ENODEV;
	write_zsreg(&dev->chanA, R12, 0x55);
	if (read_zsreg(&dev->chanA, R12) != 0x55)
		return -ENODEV;

	dev->type = Z8530;

	/*	See the application note.
	 */

	write_zsreg(&dev->chanA, R15, 0x01);

	/*	If we can set the low bit of R15 then
	 *	the chip is enhanced.
	 */

	if (read_zsreg(&dev->chanA, R15) == 0x01) {
		/* This C30 versus 230 detect is from Klaus Kudielka's dmascc */
		/* Put a char in the fifo */
		write_zsreg(&dev->chanA, R8, 0);
		if (read_zsreg(&dev->chanA, R0) & Tx_BUF_EMP)
			dev->type = Z85230;	/* Has a FIFO */
		else
			dev->type = Z85C30;	/* Z85C30, 1 byte FIFO */
	}

	/*	The code assumes R7' and friends are
	 *	off. Use write_zsext() for these and keep
	 *	this bit clear.
	 */

	write_zsreg(&dev->chanA, R15, 0);

	/*	At this point it looks like the chip is behaving
	 */

	memcpy(dev->chanA.regs, reg_init, 16);
	memcpy(dev->chanB.regs, reg_init, 16);

	return 0;
}

/**
 *	z8530_init - Initialise a Z8530 device
 *	@dev: Z8530 device to initialise.
 *
 *	Configure up a Z8530/Z85C30 or Z85230 chip. We check the device
 *	is present, identify the type and then program it to hopefully
 *	keep quite and behave. This matters a lot, a Z8530 in the wrong
 *	state will sometimes get into stupid modes generating 10Khz
 *	interrupt streams and the like.
 *
 *	We set the interrupt handler up to discard any events, in case
 *	we get them during reset or setp.
 *
 *	Return 0 for success, or a negative value indicating the problem
 *	in errno form.
 */

int z8530_init(struct z8530_dev *dev)
{
	unsigned long flags;
	int ret;

	/* Set up the chip level lock */
	spin_lock_init(&dev->lock);
	dev->chanA.lock = &dev->lock;
	dev->chanB.lock = &dev->lock;

	spin_lock_irqsave(&dev->lock, flags);
	ret = do_z8530_init(dev);
	spin_unlock_irqrestore(&dev->lock, flags);

	return ret;
}
EXPORT_SYMBOL(z8530_init);

/**
 *	z8530_shutdown - Shutdown a Z8530 device
 *	@dev: The Z8530 chip to shutdown
 *
 *	We set the interrupt handlers to silence any interrupts. We then
 *	reset the chip and wait 100uS to be sure the reset completed. Just
 *	in case the caller then tries to do stuff.
 *
 *	This is called without the lock held
 */
int z8530_shutdown(struct z8530_dev *dev)
{
	unsigned long flags;
	/* Reset the chip */

	spin_lock_irqsave(&dev->lock, flags);
	dev->chanA.irqs = &z8530_nop;
	dev->chanB.irqs = &z8530_nop;
	write_zsreg(&dev->chanA, R9, 0xC0);
	/* We must lock the udelay, the chip is offlimits here */
	udelay(100);
	spin_unlock_irqrestore(&dev->lock, flags);
	return 0;
}
EXPORT_SYMBOL(z8530_shutdown);

/**
 *	z8530_channel_load - Load channel data
 *	@c: Z8530 channel to configure
 *	@rtable: table of register, value pairs
 *	FIXME: ioctl to allow user uploaded tables
 *
 *	Load a Z8530 channel up from the system data. We use +16 to
 *	indicate the "prime" registers. The value 255 terminates the
 *	table.
 */

int z8530_channel_load(struct z8530_channel *c, u8 *rtable)
{
	unsigned long flags;

	spin_lock_irqsave(c->lock, flags);

	while (*rtable != 255) {
		int reg = *rtable++;

		if (reg > 0x0F)
			write_zsreg(c, R15, c->regs[15] | 1);
		write_zsreg(c, reg & 0x0F, *rtable);
		if (reg > 0x0F)
			write_zsreg(c, R15, c->regs[15] & ~1);
		c->regs[reg] = *rtable++;
	}
	c->rx_function = z8530_null_rx;
	c->skb = NULL;
	c->tx_skb = NULL;
	c->tx_next_skb = NULL;
	c->mtu = 1500;
	c->max = 0;
	c->count = 0;
	c->status = read_zsreg(c, R0);
	c->sync = 1;
	write_zsreg(c, R3, c->regs[R3] | RxENABLE);

	spin_unlock_irqrestore(c->lock, flags);
	return 0;
}
EXPORT_SYMBOL(z8530_channel_load);

/**
 *	z8530_tx_begin - Begin packet transmission
 *	@c: The Z8530 channel to kick
 *
 *	This is the speed sensitive side of transmission. If we are called
 *	and no buffer is being transmitted we commence the next buffer. If
 *	nothing is queued we idle the sync.
 *
 *	Note: We are handling this code path in the interrupt path, keep it
 *	fast or bad things will happen.
 *
 *	Called with the lock held.
 */

static void z8530_tx_begin(struct z8530_channel *c)
{
	unsigned long flags;

	if (c->tx_skb)
		return;

	c->tx_skb = c->tx_next_skb;
	c->tx_next_skb = NULL;
	c->tx_ptr = c->tx_next_ptr;

	if (!c->tx_skb) {
		/* Idle on */
		if (c->dma_tx) {
			flags = claim_dma_lock();
			disable_dma(c->txdma);
			/*	Check if we crapped out.
			 */
			if (get_dma_residue(c->txdma)) {
				c->netdevice->stats.tx_dropped++;
				c->netdevice->stats.tx_fifo_errors++;
			}
			release_dma_lock(flags);
		}
		c->txcount = 0;
	} else {
		c->txcount = c->tx_skb->len;

		if (c->dma_tx) {
			/*	FIXME. DMA is broken for the original 8530,
			 *	on the older parts we need to set a flag and
			 *	wait for a further TX interrupt to fire this
			 *	stage off
			 */

			flags = claim_dma_lock();
			disable_dma(c->txdma);

			/*	These two are needed by the 8530/85C30
			 *	and must be issued when idling.
			 */
			if (c->dev->type != Z85230) {
				write_zsctrl(c, RES_Tx_CRC);
				write_zsctrl(c, RES_EOM_L);
			}
			write_zsreg(c, R10, c->regs[10] & ~ABUNDER);
			clear_dma_ff(c->txdma);
			set_dma_addr(c->txdma, virt_to_bus(c->tx_ptr));
			set_dma_count(c->txdma, c->txcount);
			enable_dma(c->txdma);
			release_dma_lock(flags);
			write_zsctrl(c, RES_EOM_L);
			write_zsreg(c, R5, c->regs[R5] | TxENAB);
		} else {
			/* ABUNDER off */
			write_zsreg(c, R10, c->regs[10]);
			write_zsctrl(c, RES_Tx_CRC);

			while (c->txcount && (read_zsreg(c, R0) & Tx_BUF_EMP)) {
				write_zsreg(c, R8, *c->tx_ptr++);
				c->txcount--;
			}
		}
	}
	/*	Since we emptied tx_skb we can ask for more
	 */
	netif_wake_queue(c->netdevice);
}

/**
 *	z8530_tx_done - TX complete callback
 *	@c: The channel that completed a transmit.
 *
 *	This is called when we complete a packet send. We wake the queue,
 *	start the next packet going and then free the buffer of the existing
 *	packet. This code is fairly timing sensitive.
 *
 *	Called with the register lock held.
 */

static void z8530_tx_done(struct z8530_channel *c)
{
	struct sk_buff *skb;

	/* Actually this can happen.*/
	if (!c->tx_skb)
		return;

	skb = c->tx_skb;
	c->tx_skb = NULL;
	z8530_tx_begin(c);
	c->netdevice->stats.tx_packets++;
	c->netdevice->stats.tx_bytes += skb->len;
	dev_consume_skb_irq(skb);
}

/**
 *	z8530_null_rx - Discard a packet
 *	@c: The channel the packet arrived on
 *	@skb: The buffer
 *
 *	We point the receive handler at this function when idle. Instead
 *	of processing the frames we get to throw them away.
 */
void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb)
{
	dev_kfree_skb_any(skb);
}
EXPORT_SYMBOL(z8530_null_rx);

/**
 *	z8530_rx_done - Receive completion callback
 *	@c: The channel that completed a receive
 *
 *	A new packet is complete. Our goal here is to get back into receive
 *	mode as fast as possible. On the Z85230 we could change to using
 *	ESCC mode, but on the older chips we have no choice. We flip to the
 *	new buffer immediately in DMA mode so that the DMA of the next
 *	frame can occur while we are copying the previous buffer to an sk_buff
 *
 *	Called with the lock held
 */
static void z8530_rx_done(struct z8530_channel *c)
{
	struct sk_buff *skb;
	int ct;

	/*	Is our receive engine in DMA mode
	 */
	if (c->rxdma_on) {
		/*	Save the ready state and the buffer currently
		 *	being used as the DMA target
		 */
		int ready = c->dma_ready;
		unsigned char *rxb = c->rx_buf[c->dma_num];
		unsigned long flags;

		/*	Complete this DMA. Necessary to find the length
		 */
		flags = claim_dma_lock();

		disable_dma(c->rxdma);
		clear_dma_ff(c->rxdma);
		c->rxdma_on = 0;
		ct = c->mtu - get_dma_residue(c->rxdma);
		if (ct < 0)
			ct = 2;	/* Shit happens.. */
		c->dma_ready = 0;

		/*	Normal case: the other slot is free, start the next DMA
		 *	into it immediately.
		 */

		if (ready) {
			c->dma_num ^= 1;
			set_dma_mode(c->rxdma, DMA_MODE_READ | 0x10);
			set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[c->dma_num]));
			set_dma_count(c->rxdma, c->mtu);
			c->rxdma_on = 1;
			enable_dma(c->rxdma);
			/* Stop any frames that we missed the head of
			 * from passing
			 */
			write_zsreg(c, R0, RES_Rx_CRC);
		} else {
			/* Can't occur as we dont reenable the DMA irq until
			 * after the flip is done
			 */
			netdev_warn(c->netdevice, "DMA flip overrun!\n");
		}

		release_dma_lock(flags);

		/*	Shove the old buffer into an sk_buff. We can't DMA
		 *	directly into one on a PC - it might be above the 16Mb
		 *	boundary. Optimisation - we could check to see if we
		 *	can avoid the copy. Optimisation 2 - make the memcpy
		 *	a copychecksum.
		 */

		skb = dev_alloc_skb(ct);
		if (!skb) {
			c->netdevice->stats.rx_dropped++;
			netdev_warn(c->netdevice, "Memory squeeze\n");
		} else {
			skb_put(skb, ct);
			skb_copy_to_linear_data(skb, rxb, ct);
			c->netdevice->stats.rx_packets++;
			c->netdevice->stats.rx_bytes += ct;
		}
		c->dma_ready = 1;
	} else {
		RT_LOCK;
		skb = c->skb;

		/*	The game we play for non DMA is similar. We want to
		 *	get the controller set up for the next packet as fast
		 *	as possible. We potentially only have one byte + the
		 *	fifo length for this. Thus we want to flip to the new
		 *	buffer and then mess around copying and allocating
		 *	things. For the current case it doesn't matter but
		 *	if you build a system where the sync irq isn't blocked
		 *	by the kernel IRQ disable then you need only block the
		 *	sync IRQ for the RT_LOCK area.
		 *
		 */
		ct = c->count;

		c->skb = c->skb2;
		c->count = 0;
		c->max = c->mtu;
		if (c->skb) {
			c->dptr = c->skb->data;
			c->max = c->mtu;
		} else {
			c->count = 0;
			c->max = 0;
		}
		RT_UNLOCK;

		c->skb2 = dev_alloc_skb(c->mtu);
		if (c->skb2)
			skb_put(c->skb2, c->mtu);

		c->netdevice->stats.rx_packets++;
		c->netdevice->stats.rx_bytes += ct;
	}
	/*	If we received a frame we must now process it.
	 */
	if (skb) {
		skb_trim(skb, ct);
		c->rx_function(c, skb);
	} else {
		c->netdevice->stats.rx_dropped++;
		netdev_err(c->netdevice, "Lost a frame\n");
	}
}

/**
 *	spans_boundary - Check a packet can be ISA DMA'd
 *	@skb: The buffer to check
 *
 *	Returns true if the buffer cross a DMA boundary on a PC. The poor
 *	thing can only DMA within a 64K block not across the edges of it.
 */

static inline int spans_boundary(struct sk_buff *skb)
{
	unsigned long a = (unsigned long)skb->data;

	a ^= (a + skb->len);
	if (a & 0x00010000)	/* If the 64K bit is different.. */
		return 1;
	return 0;
}

/**
 *	z8530_queue_xmit - Queue a packet
 *	@c: The channel to use
 *	@skb: The packet to kick down the channel
 *
 *	Queue a packet for transmission. Because we have rather
 *	hard to hit interrupt latencies for the Z85230 per packet
 *	even in DMA mode we do the flip to DMA buffer if needed here
 *	not in the IRQ.
 *
 *	Called from the network code. The lock is not held at this
 *	point.
 */
netdev_tx_t z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb)
{
	unsigned long flags;

	netif_stop_queue(c->netdevice);
	if (c->tx_next_skb)
		return NETDEV_TX_BUSY;

	/* PC SPECIFIC - DMA limits */
	/*	If we will DMA the transmit and its gone over the ISA bus
	 *	limit, then copy to the flip buffer
	 */

	if (c->dma_tx &&
	    ((unsigned long)(virt_to_bus(skb->data + skb->len)) >=
	    16 * 1024 * 1024 || spans_boundary(skb))) {
		/*	Send the flip buffer, and flip the flippy bit.
		 *	We don't care which is used when just so long as
		 *	we never use the same buffer twice in a row. Since
		 *	only one buffer can be going out at a time the other
		 *	has to be safe.
		 */
		c->tx_next_ptr = c->tx_dma_buf[c->tx_dma_used];
		c->tx_dma_used ^= 1;	/* Flip temp buffer */
		skb_copy_from_linear_data(skb, c->tx_next_ptr, skb->len);
	} else {
		c->tx_next_ptr = skb->data;
	}
	RT_LOCK;
	c->tx_next_skb = skb;
	RT_UNLOCK;

	spin_lock_irqsave(c->lock, flags);
	z8530_tx_begin(c);
	spin_unlock_irqrestore(c->lock, flags);

	return NETDEV_TX_OK;
}
EXPORT_SYMBOL(z8530_queue_xmit);

/*	Module support
 */
static const char banner[] __initconst =
	KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";

static int __init z85230_init_driver(void)
{
	printk(banner);
	return 0;
}
module_init(z85230_init_driver);

static void __exit z85230_cleanup_driver(void)
{
}
module_exit(z85230_cleanup_driver);

MODULE_AUTHOR("Red Hat Inc.");
MODULE_DESCRIPTION("Z85x30 synchronous driver core");
MODULE_LICENSE("GPL");
