diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
new file mode 100644
index 0000000..78e34ee
--- /dev/null
+++ b/drivers/atm/eni.c
@@ -0,0 +1,2299 @@
+/* drivers/atm/eni.c - Efficient Networks ENI155P device driver */
+ 
+/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
+ 
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/sonet.h>
+#include <linux/skbuff.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/uio.h>
+#include <linux/init.h>
+#include <linux/atm_eni.h>
+#include <linux/bitops.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include <asm/uaccess.h>
+#include <asm/string.h>
+#include <asm/byteorder.h>
+
+#include "tonga.h"
+#include "midway.h"
+#include "suni.h"
+#include "eni.h"
+
+#if !defined(__i386__) && !defined(__x86_64__)
+#ifndef ioremap_nocache
+#define ioremap_nocache(X,Y) ioremap(X,Y)
+#endif 
+#endif
+
+/*
+ * TODO:
+ *
+ * Show stoppers
+ *  none
+ *
+ * Minor
+ *  - OAM support
+ *  - fix bugs listed below
+ */
+
+/*
+ * KNOWN BUGS:
+ *
+ * - may run into JK-JK bug and deadlock
+ * - should allocate UBR channel first
+ * - buffer space allocation algorithm is stupid
+ *   (RX: should be maxSDU+maxdelay*rate
+ *    TX: should be maxSDU+min(maxSDU,maxdelay*rate) )
+ * - doesn't support OAM cells
+ * - eni_put_free may hang if not putting memory fragments that _complete_
+ *   2^n block (never happens in real life, though)
+ * - keeps IRQ even if initialization fails
+ */
+
+
+#if 0
+#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
+#else
+#define DPRINTK(format,args...)
+#endif
+
+
+#ifndef CONFIG_ATM_ENI_TUNE_BURST
+#define CONFIG_ATM_ENI_BURST_TX_8W
+#define CONFIG_ATM_ENI_BURST_RX_4W
+#endif
+
+
+#ifndef CONFIG_ATM_ENI_DEBUG
+
+
+#define NULLCHECK(x)
+
+#define EVENT(s,a,b)
+
+
+static void event_dump(void)
+{
+}
+
+
+#else
+
+
+/* 
+ * NULL pointer checking
+ */
+
+#define NULLCHECK(x) \
+	if ((unsigned long) (x) < 0x30) \
+		printk(KERN_CRIT #x "==0x%lx\n",(unsigned long) (x))
+
+/*
+ * Very extensive activity logging. Greatly improves bug detection speed but
+ * costs a few Mbps if enabled.
+ */
+
+#define EV 64
+
+static const char *ev[EV];
+static unsigned long ev_a[EV],ev_b[EV];
+static int ec = 0;
+
+
+static void EVENT(const char *s,unsigned long a,unsigned long b)
+{
+	ev[ec] = s; 
+	ev_a[ec] = a;
+	ev_b[ec] = b;
+	ec = (ec+1) % EV;
+}
+
+
+static void event_dump(void)
+{
+	int n,i;
+
+	for (n = 0; n < EV; n++) {
+		i = (ec+n) % EV;
+		printk(KERN_NOTICE);
+		printk(ev[i] ? ev[i] : "(null)",ev_a[i],ev_b[i]);
+	}
+}
+
+
+#endif /* CONFIG_ATM_ENI_DEBUG */
+
+
+/*
+ * NExx   must not be equal at end
+ * EExx   may be equal at end
+ * xxPJOK verify validity of pointer jumps
+ * xxPMOK operating on a circular buffer of "c" words
+ */
+
+#define NEPJOK(a0,a1,b) \
+    ((a0) < (a1) ? (b) <= (a0) || (b) > (a1) : (b) <= (a0) && (b) > (a1))
+#define EEPJOK(a0,a1,b) \
+    ((a0) < (a1) ? (b) < (a0) || (b) >= (a1) : (b) < (a0) && (b) >= (a1))
+#define NEPMOK(a0,d,b,c) NEPJOK(a0,(a0+d) & (c-1),b)
+#define EEPMOK(a0,d,b,c) EEPJOK(a0,(a0+d) & (c-1),b)
+
+
+static int tx_complete = 0,dma_complete = 0,queued = 0,requeued = 0,
+  backlogged = 0,rx_enqueued = 0,rx_dequeued = 0,pushed = 0,submitted = 0,
+  putting = 0;
+
+static struct atm_dev *eni_boards = NULL;
+
+static u32 *cpu_zeroes = NULL; /* aligned "magic" zeroes */
+static dma_addr_t zeroes;
+
+/* Read/write registers on card */
+#define eni_in(r)	readl(eni_dev->reg+(r)*4)
+#define eni_out(v,r)	writel((v),eni_dev->reg+(r)*4)
+
+
+/*-------------------------------- utilities --------------------------------*/
+
+
+static void dump_mem(struct eni_dev *eni_dev)
+{
+	int i;
+
+	for (i = 0; i < eni_dev->free_len; i++)
+		printk(KERN_DEBUG "  %d: %p %d\n",i,
+		    eni_dev->free_list[i].start,
+		    1 << eni_dev->free_list[i].order);
+}
+
+
+static void dump(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+
+	int i;
+
+	eni_dev = ENI_DEV(dev);
+	printk(KERN_NOTICE "Free memory\n");
+	dump_mem(eni_dev);
+	printk(KERN_NOTICE "TX buffers\n");
+	for (i = 0; i < NR_CHAN; i++)
+		if (eni_dev->tx[i].send)
+			printk(KERN_NOTICE "  TX %d @ %p: %ld\n",i,
+			    eni_dev->tx[i].send,eni_dev->tx[i].words*4);
+	printk(KERN_NOTICE "RX buffers\n");
+	for (i = 0; i < 1024; i++)
+		if (eni_dev->rx_map[i] && ENI_VCC(eni_dev->rx_map[i])->rx)
+			printk(KERN_NOTICE "  RX %d @ %p: %ld\n",i,
+			    ENI_VCC(eni_dev->rx_map[i])->recv,
+			    ENI_VCC(eni_dev->rx_map[i])->words*4);
+	printk(KERN_NOTICE "----\n");
+}
+
+
+static void eni_put_free(struct eni_dev *eni_dev, void __iomem *start,
+    unsigned long size)
+{
+	struct eni_free *list;
+	int len,order;
+
+	DPRINTK("init 0x%lx+%ld(0x%lx)\n",start,size,size);
+	start += eni_dev->base_diff;
+	list = eni_dev->free_list;
+	len = eni_dev->free_len;
+	while (size) {
+		if (len >= eni_dev->free_list_size) {
+			printk(KERN_CRIT "eni_put_free overflow (%p,%ld)\n",
+			    start,size);
+			break;
+		}
+		for (order = 0; !(((unsigned long)start | size) & (1 << order)); order++);
+		if (MID_MIN_BUF_SIZE > (1 << order)) {
+			printk(KERN_CRIT "eni_put_free: order %d too small\n",
+			    order);
+			break;
+		}
+		list[len].start = (void __iomem *) start;
+		list[len].order = order;
+		len++;
+		start += 1 << order;
+		size -= 1 << order;
+	}
+	eni_dev->free_len = len;
+	/*dump_mem(eni_dev);*/
+}
+
+
+static void __iomem *eni_alloc_mem(struct eni_dev *eni_dev, unsigned long *size)
+{
+	struct eni_free *list;
+	void __iomem *start;
+	int len,i,order,best_order,index;
+
+	list = eni_dev->free_list;
+	len = eni_dev->free_len;
+	if (*size < MID_MIN_BUF_SIZE) *size = MID_MIN_BUF_SIZE;
+	if (*size > MID_MAX_BUF_SIZE) return NULL;
+	for (order = 0; (1 << order) < *size; order++);
+	DPRINTK("trying: %ld->%d\n",*size,order);
+	best_order = 65; /* we don't have more than 2^64 of anything ... */
+	index = 0; /* silence GCC */
+	for (i = 0; i < len; i++)
+		if (list[i].order == order) {
+			best_order = order;
+			index = i;
+			break;
+		}
+		else if (best_order > list[i].order && list[i].order > order) {
+				best_order = list[i].order;
+				index = i;
+			}
+	if (best_order == 65) return NULL;
+	start = list[index].start-eni_dev->base_diff;
+	list[index] = list[--len];
+	eni_dev->free_len = len;
+	*size = 1 << order;
+	eni_put_free(eni_dev,start+*size,(1 << best_order)-*size);
+	DPRINTK("%ld bytes (order %d) at 0x%lx\n",*size,order,start);
+	memset_io(start,0,*size);       /* never leak data */
+	/*dump_mem(eni_dev);*/
+	return start;
+}
+
+
+static void eni_free_mem(struct eni_dev *eni_dev, void __iomem *start,
+    unsigned long size)
+{
+	struct eni_free *list;
+	int len,i,order;
+
+	start += eni_dev->base_diff;
+	list = eni_dev->free_list;
+	len = eni_dev->free_len;
+	for (order = -1; size; order++) size >>= 1;
+	DPRINTK("eni_free_mem: %p+0x%lx (order %d)\n",start,size,order);
+	for (i = 0; i < len; i++)
+		if (((unsigned long) list[i].start) == ((unsigned long)start^(1 << order)) &&
+		    list[i].order == order) {
+			DPRINTK("match[%d]: 0x%lx/0x%lx(0x%x), %d/%d\n",i,
+			    list[i].start,start,1 << order,list[i].order,order);
+			list[i] = list[--len];
+			start = (void __iomem *) ((unsigned long) start & ~(unsigned long) (1 << order));
+			order++;
+			i = -1;
+			continue;
+		}
+	if (len >= eni_dev->free_list_size) {
+		printk(KERN_ALERT "eni_free_mem overflow (%p,%d)\n",start,
+		    order);
+		return;
+	}
+	list[len].start = start;
+	list[len].order = order;
+	eni_dev->free_len = len+1;
+	/*dump_mem(eni_dev);*/
+}
+
+
+/*----------------------------------- RX ------------------------------------*/
+
+
+#define ENI_VCC_NOS ((struct atm_vcc *) 1)
+
+
+static void rx_ident_err(struct atm_vcc *vcc)
+{
+	struct atm_dev *dev;
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+
+	dev = vcc->dev;
+	eni_dev = ENI_DEV(dev);
+	/* immediately halt adapter */
+	eni_out(eni_in(MID_MC_S) &
+	    ~(MID_DMA_ENABLE | MID_TX_ENABLE | MID_RX_ENABLE),MID_MC_S);
+	/* dump useful information */
+	eni_vcc = ENI_VCC(vcc);
+	printk(KERN_ALERT DEV_LABEL "(itf %d): driver error - RX ident "
+	    "mismatch\n",dev->number);
+	printk(KERN_ALERT "  VCI %d, rxing %d, words %ld\n",vcc->vci,
+	    eni_vcc->rxing,eni_vcc->words);
+	printk(KERN_ALERT "  host descr 0x%lx, rx pos 0x%lx, descr value "
+	    "0x%x\n",eni_vcc->descr,eni_vcc->rx_pos,
+	    (unsigned) readl(eni_vcc->recv+eni_vcc->descr*4));
+	printk(KERN_ALERT "  last %p, servicing %d\n",eni_vcc->last,
+	    eni_vcc->servicing);
+	EVENT("---dump ends here---\n",0,0);
+	printk(KERN_NOTICE "---recent events---\n");
+	event_dump();
+	ENI_DEV(dev)->fast = NULL; /* really stop it */
+	ENI_DEV(dev)->slow = NULL;
+	skb_queue_head_init(&ENI_DEV(dev)->rx_queue);
+}
+
+
+static int do_rx_dma(struct atm_vcc *vcc,struct sk_buff *skb,
+    unsigned long skip,unsigned long size,unsigned long eff)
+{
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+	u32 dma_rd,dma_wr;
+	u32 dma[RX_DMA_BUF*2];
+	dma_addr_t paddr;
+	unsigned long here;
+	int i,j;
+
+	eni_dev = ENI_DEV(vcc->dev);
+	eni_vcc = ENI_VCC(vcc);
+	paddr = 0; /* GCC, shut up */
+	if (skb) {
+		paddr = pci_map_single(eni_dev->pci_dev,skb->data,skb->len,
+		    PCI_DMA_FROMDEVICE);
+		ENI_PRV_PADDR(skb) = paddr;
+		if (paddr & 3)
+			printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d has "
+			    "mis-aligned RX data (0x%lx)\n",vcc->dev->number,
+			    vcc->vci,(unsigned long) paddr);
+		ENI_PRV_SIZE(skb) = size+skip;
+		    /* PDU plus descriptor */
+		ATM_SKB(skb)->vcc = vcc;
+	}
+	j = 0;
+	if ((eff && skip) || 1) { /* @@@ actually, skip is always == 1 ... */
+		here = (eni_vcc->descr+skip) & (eni_vcc->words-1);
+		dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci
+		    << MID_DMA_VCI_SHIFT) | MID_DT_JK;
+		j++;
+	}
+	here = (eni_vcc->descr+size+skip) & (eni_vcc->words-1);
+	if (!eff) size += skip;
+	else {
+		unsigned long words;
+
+		if (!size) {
+			DPRINTK("strange things happen ...\n");
+			EVENT("strange things happen ... (skip=%ld,eff=%ld)\n",
+			    size,eff);
+		}
+		words = eff;
+		if (paddr & 15) {
+			unsigned long init;
+
+			init = 4-((paddr & 15) >> 2);
+			if (init > words) init = words;
+			dma[j++] = MID_DT_WORD | (init << MID_DMA_COUNT_SHIFT) |
+			    (vcc->vci << MID_DMA_VCI_SHIFT);
+			dma[j++] = paddr;
+			paddr += init << 2;
+			words -= init;
+		}
+#ifdef CONFIG_ATM_ENI_BURST_RX_16W /* may work with some PCI chipsets ... */
+		if (words & ~15) {
+			dma[j++] = MID_DT_16W | ((words >> 4) <<
+			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
+			    MID_DMA_VCI_SHIFT);
+			dma[j++] = paddr;
+			paddr += (words & ~15) << 2;
+			words &= 15;
+		}
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_RX_8W  /* works only with *some* PCI chipsets ... */
+		if (words & ~7) {
+			dma[j++] = MID_DT_8W | ((words >> 3) <<
+			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
+			    MID_DMA_VCI_SHIFT);
+			dma[j++] = paddr;
+			paddr += (words & ~7) << 2;
+			words &= 7;
+		}
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_RX_4W /* recommended */
+		if (words & ~3) {
+			dma[j++] = MID_DT_4W | ((words >> 2) <<
+			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
+			    MID_DMA_VCI_SHIFT);
+			dma[j++] = paddr;
+			paddr += (words & ~3) << 2;
+			words &= 3;
+		}
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_RX_2W /* probably useless if RX_4W, RX_8W, ... */
+		if (words & ~1) {
+			dma[j++] = MID_DT_2W | ((words >> 1) <<
+			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
+			    MID_DMA_VCI_SHIFT);
+			dma[j++] = paddr;
+			paddr += (words & ~1) << 2;
+			words &= 1;
+		}
+#endif
+		if (words) {
+			dma[j++] = MID_DT_WORD | (words << MID_DMA_COUNT_SHIFT)
+			    | (vcc->vci << MID_DMA_VCI_SHIFT);
+			dma[j++] = paddr;
+		}
+	}
+	if (size != eff) {
+		dma[j++] = (here << MID_DMA_COUNT_SHIFT) |
+		    (vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK;
+		j++;
+	}
+	if (!j || j > 2*RX_DMA_BUF) {
+		printk(KERN_CRIT DEV_LABEL "!j or j too big!!!\n");
+		goto trouble;
+	}
+	dma[j-2] |= MID_DMA_END;
+	j = j >> 1;
+	dma_wr = eni_in(MID_DMA_WR_RX);
+	dma_rd = eni_in(MID_DMA_RD_RX);
+	/*
+	 * Can I move the dma_wr pointer by 2j+1 positions without overwriting
+	 * data that hasn't been read (position of dma_rd) yet ?
+	 */
+	if (!NEPMOK(dma_wr,j+j+1,dma_rd,NR_DMA_RX)) { /* @@@ +1 is ugly */
+		printk(KERN_WARNING DEV_LABEL "(itf %d): RX DMA full\n",
+		    vcc->dev->number);
+		goto trouble;
+	}
+        for (i = 0; i < j; i++) {
+		writel(dma[i*2],eni_dev->rx_dma+dma_wr*8);
+		writel(dma[i*2+1],eni_dev->rx_dma+dma_wr*8+4);
+		dma_wr = (dma_wr+1) & (NR_DMA_RX-1);
+        }
+	if (skb) {
+		ENI_PRV_POS(skb) = eni_vcc->descr+size+1;
+		skb_queue_tail(&eni_dev->rx_queue,skb);
+		eni_vcc->last = skb;
+rx_enqueued++;
+	}
+	eni_vcc->descr = here;
+	eni_out(dma_wr,MID_DMA_WR_RX);
+	return 0;
+
+trouble:
+	if (paddr)
+		pci_unmap_single(eni_dev->pci_dev,paddr,skb->len,
+		    PCI_DMA_FROMDEVICE);
+	if (skb) dev_kfree_skb_irq(skb);
+	return -1;
+}
+
+
+static void discard(struct atm_vcc *vcc,unsigned long size)
+{
+	struct eni_vcc *eni_vcc;
+
+	eni_vcc = ENI_VCC(vcc);
+	EVENT("discard (size=%ld)\n",size,0);
+	while (do_rx_dma(vcc,NULL,1,size,0)) EVENT("BUSY LOOP",0,0);
+	    /* could do a full fallback, but that might be more expensive */
+	if (eni_vcc->rxing) ENI_PRV_POS(eni_vcc->last) += size+1;
+	else eni_vcc->rx_pos = (eni_vcc->rx_pos+size+1) & (eni_vcc->words-1);
+}
+
+
+/*
+ * TODO: should check whether direct copies (without DMA setup, dequeuing on
+ * interrupt, etc.) aren't much faster for AAL0
+ */
+
+static int rx_aal0(struct atm_vcc *vcc)
+{
+	struct eni_vcc *eni_vcc;
+	unsigned long descr;
+	unsigned long length;
+	struct sk_buff *skb;
+
+	DPRINTK(">rx_aal0\n");
+	eni_vcc = ENI_VCC(vcc);
+	descr = readl(eni_vcc->recv+eni_vcc->descr*4);
+	if ((descr & MID_RED_IDEN) != (MID_RED_RX_ID << MID_RED_SHIFT)) {
+		rx_ident_err(vcc);
+		return 1;
+	}
+	if (descr & MID_RED_T) {
+		DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
+		    vcc->dev->number);
+		length = 0;
+		atomic_inc(&vcc->stats->rx_err);
+	}
+	else {
+		length = ATM_CELL_SIZE-1; /* no HEC */
+	}
+	skb = length ? atm_alloc_charge(vcc,length,GFP_ATOMIC) : NULL;
+	if (!skb) {
+		discard(vcc,length >> 2);
+		return 0;
+	}
+	skb_put(skb,length);
+	skb->stamp = eni_vcc->timestamp;
+	DPRINTK("got len %ld\n",length);
+	if (do_rx_dma(vcc,skb,1,length >> 2,length >> 2)) return 1;
+	eni_vcc->rxing++;
+	return 0;
+}
+
+
+static int rx_aal5(struct atm_vcc *vcc)
+{
+	struct eni_vcc *eni_vcc;
+	unsigned long descr;
+	unsigned long size,eff,length;
+	struct sk_buff *skb;
+
+	EVENT("rx_aal5\n",0,0);
+	DPRINTK(">rx_aal5\n");
+	eni_vcc = ENI_VCC(vcc);
+	descr = readl(eni_vcc->recv+eni_vcc->descr*4);
+	if ((descr & MID_RED_IDEN) != (MID_RED_RX_ID << MID_RED_SHIFT)) {
+		rx_ident_err(vcc);
+		return 1;
+	}
+	if (descr & (MID_RED_T | MID_RED_CRC_ERR)) {
+		if (descr & MID_RED_T) {
+			EVENT("empty cell (descr=0x%lx)\n",descr,0);
+			DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
+			    vcc->dev->number);
+			size = 0;
+		}
+		else {
+			static unsigned long silence = 0;
+
+			if (time_after(jiffies, silence) || silence == 0) {
+				printk(KERN_WARNING DEV_LABEL "(itf %d): "
+				    "discarding PDU(s) with CRC error\n",
+				    vcc->dev->number);
+				silence = (jiffies+2*HZ)|1;
+			}
+			size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
+			EVENT("CRC error (descr=0x%lx,size=%ld)\n",descr,
+			    size);
+		}
+		eff = length = 0;
+		atomic_inc(&vcc->stats->rx_err);
+	}
+	else {
+		size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
+		DPRINTK("size=%ld\n",size);
+		length = readl(eni_vcc->recv+(((eni_vcc->descr+size-1) &
+		    (eni_vcc->words-1)))*4) & 0xffff;
+				/* -trailer(2)+header(1) */
+		if (length && length <= (size << 2)-8 && length <=
+		  ATM_MAX_AAL5_PDU) eff = (length+3) >> 2;
+		else {				 /* ^ trailer length (8) */
+			EVENT("bad PDU (descr=0x08%lx,length=%ld)\n",descr,
+			    length);
+			printk(KERN_ERR DEV_LABEL "(itf %d): bad AAL5 PDU "
+			    "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n",
+			    vcc->dev->number,vcc->vci,length,size << 2,descr);
+			length = eff = 0;
+			atomic_inc(&vcc->stats->rx_err);
+		}
+	}
+	skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL;
+	if (!skb) {
+		discard(vcc,size);
+		return 0;
+	}
+	skb_put(skb,length);
+	DPRINTK("got len %ld\n",length);
+	if (do_rx_dma(vcc,skb,1,size,eff)) return 1;
+	eni_vcc->rxing++;
+	return 0;
+}
+
+
+static inline int rx_vcc(struct atm_vcc *vcc)
+{
+	void __iomem *vci_dsc;
+	unsigned long tmp;
+	struct eni_vcc *eni_vcc;
+
+	eni_vcc = ENI_VCC(vcc);
+	vci_dsc = ENI_DEV(vcc->dev)->vci+vcc->vci*16;
+	EVENT("rx_vcc(1)\n",0,0);
+	while (eni_vcc->descr != (tmp = (readl(vci_dsc+4) & MID_VCI_DESCR) >>
+	    MID_VCI_DESCR_SHIFT)) {
+		EVENT("rx_vcc(2: host dsc=0x%lx, nic dsc=0x%lx)\n",
+		    eni_vcc->descr,tmp);
+		DPRINTK("CB_DESCR %ld REG_DESCR %d\n",ENI_VCC(vcc)->descr,
+		    (((unsigned) readl(vci_dsc+4) & MID_VCI_DESCR) >>
+		    MID_VCI_DESCR_SHIFT));
+		if (ENI_VCC(vcc)->rx(vcc)) return 1;
+	}
+	/* clear IN_SERVICE flag */
+	writel(readl(vci_dsc) & ~MID_VCI_IN_SERVICE,vci_dsc);
+	/*
+	 * If new data has arrived between evaluating the while condition and
+	 * clearing IN_SERVICE, we wouldn't be notified until additional data
+	 * follows. So we have to loop again to be sure.
+	 */
+	EVENT("rx_vcc(3)\n",0,0);
+	while (ENI_VCC(vcc)->descr != (tmp = (readl(vci_dsc+4) & MID_VCI_DESCR)
+	    >> MID_VCI_DESCR_SHIFT)) {
+		EVENT("rx_vcc(4: host dsc=0x%lx, nic dsc=0x%lx)\n",
+		    eni_vcc->descr,tmp);
+		DPRINTK("CB_DESCR %ld REG_DESCR %d\n",ENI_VCC(vcc)->descr,
+		    (((unsigned) readl(vci_dsc+4) & MID_VCI_DESCR) >>
+		    MID_VCI_DESCR_SHIFT));
+		if (ENI_VCC(vcc)->rx(vcc)) return 1;
+	}
+	return 0;
+}
+
+
+static void poll_rx(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+	struct atm_vcc *curr;
+
+	eni_dev = ENI_DEV(dev);
+	while ((curr = eni_dev->fast)) {
+		EVENT("poll_rx.fast\n",0,0);
+		if (rx_vcc(curr)) return;
+		eni_dev->fast = ENI_VCC(curr)->next;
+		ENI_VCC(curr)->next = ENI_VCC_NOS;
+		barrier();
+		ENI_VCC(curr)->servicing--;
+	}
+	while ((curr = eni_dev->slow)) {
+		EVENT("poll_rx.slow\n",0,0);
+		if (rx_vcc(curr)) return;
+		eni_dev->slow = ENI_VCC(curr)->next;
+		ENI_VCC(curr)->next = ENI_VCC_NOS;
+		barrier();
+		ENI_VCC(curr)->servicing--;
+	}
+}
+
+
+static void get_service(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+	struct atm_vcc *vcc;
+	unsigned long vci;
+
+	DPRINTK(">get_service\n");
+	eni_dev = ENI_DEV(dev);
+	while (eni_in(MID_SERV_WRITE) != eni_dev->serv_read) {
+		vci = readl(eni_dev->service+eni_dev->serv_read*4);
+		eni_dev->serv_read = (eni_dev->serv_read+1) & (NR_SERVICE-1);
+		vcc = eni_dev->rx_map[vci & 1023];
+		if (!vcc) {
+			printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %ld not "
+			    "found\n",dev->number,vci);
+			continue; /* nasty but we try to go on anyway */
+			/* @@@ nope, doesn't work */
+		}
+		EVENT("getting from service\n",0,0);
+		if (ENI_VCC(vcc)->next != ENI_VCC_NOS) {
+			EVENT("double service\n",0,0);
+			DPRINTK("Grr, servicing VCC %ld twice\n",vci);
+			continue;
+		}
+		do_gettimeofday(&ENI_VCC(vcc)->timestamp);
+		ENI_VCC(vcc)->next = NULL;
+		if (vcc->qos.rxtp.traffic_class == ATM_CBR) {
+			if (eni_dev->fast)
+				ENI_VCC(eni_dev->last_fast)->next = vcc;
+			else eni_dev->fast = vcc;
+			eni_dev->last_fast = vcc;
+		}
+		else {
+			if (eni_dev->slow)
+				ENI_VCC(eni_dev->last_slow)->next = vcc;
+			else eni_dev->slow = vcc;
+			eni_dev->last_slow = vcc;
+		}
+putting++;
+		ENI_VCC(vcc)->servicing++;
+	}
+}
+
+
+static void dequeue_rx(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+	struct atm_vcc *vcc;
+	struct sk_buff *skb;
+	void __iomem *vci_dsc;
+	int first;
+
+	eni_dev = ENI_DEV(dev);
+	first = 1;
+	while (1) {
+		skb = skb_dequeue(&eni_dev->rx_queue);
+		if (!skb) {
+			if (first) {
+				DPRINTK(DEV_LABEL "(itf %d): RX but not "
+				    "rxing\n",dev->number);
+				EVENT("nothing to dequeue\n",0,0);
+			}
+			break;
+		}
+		EVENT("dequeued (size=%ld,pos=0x%lx)\n",ENI_PRV_SIZE(skb),
+		    ENI_PRV_POS(skb));
+rx_dequeued++;
+		vcc = ATM_SKB(skb)->vcc;
+		eni_vcc = ENI_VCC(vcc);
+		first = 0;
+		vci_dsc = eni_dev->vci+vcc->vci*16;
+		if (!EEPMOK(eni_vcc->rx_pos,ENI_PRV_SIZE(skb),
+		    (readl(vci_dsc+4) & MID_VCI_READ) >> MID_VCI_READ_SHIFT,
+		    eni_vcc->words)) {
+			EVENT("requeuing\n",0,0);
+			skb_queue_head(&eni_dev->rx_queue,skb);
+			break;
+		}
+		eni_vcc->rxing--;
+		eni_vcc->rx_pos = ENI_PRV_POS(skb) & (eni_vcc->words-1);
+		pci_unmap_single(eni_dev->pci_dev,ENI_PRV_PADDR(skb),skb->len,
+		    PCI_DMA_TODEVICE);
+		if (!skb->len) dev_kfree_skb_irq(skb);
+		else {
+			EVENT("pushing (len=%ld)\n",skb->len,0);
+			if (vcc->qos.aal == ATM_AAL0)
+				*(unsigned long *) skb->data =
+				    ntohl(*(unsigned long *) skb->data);
+			memset(skb->cb,0,sizeof(struct eni_skb_prv));
+			vcc->push(vcc,skb);
+			pushed++;
+		}
+		atomic_inc(&vcc->stats->rx);
+	}
+	wake_up(&eni_dev->rx_wait);
+}
+
+
+static int open_rx_first(struct atm_vcc *vcc)
+{
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+	unsigned long size;
+
+	DPRINTK("open_rx_first\n");
+	eni_dev = ENI_DEV(vcc->dev);
+	eni_vcc = ENI_VCC(vcc);
+	eni_vcc->rx = NULL;
+	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;
+	size = vcc->qos.rxtp.max_sdu*eni_dev->rx_mult/100;
+	if (size > MID_MAX_BUF_SIZE && vcc->qos.rxtp.max_sdu <=
+	    MID_MAX_BUF_SIZE)
+		size = MID_MAX_BUF_SIZE;
+	eni_vcc->recv = eni_alloc_mem(eni_dev,&size);
+	DPRINTK("rx at 0x%lx\n",eni_vcc->recv);
+	eni_vcc->words = size >> 2;
+	if (!eni_vcc->recv) return -ENOBUFS;
+	eni_vcc->rx = vcc->qos.aal == ATM_AAL5 ? rx_aal5 : rx_aal0;
+	eni_vcc->descr = 0;
+	eni_vcc->rx_pos = 0;
+	eni_vcc->rxing = 0;
+	eni_vcc->servicing = 0;
+	eni_vcc->next = ENI_VCC_NOS;
+	return 0;
+}
+
+
+static int open_rx_second(struct atm_vcc *vcc)
+{
+	void __iomem *here;
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+	unsigned long size;
+	int order;
+
+	DPRINTK("open_rx_second\n");
+	eni_dev = ENI_DEV(vcc->dev);
+	eni_vcc = ENI_VCC(vcc);
+	if (!eni_vcc->rx) return 0;
+	/* set up VCI descriptor */
+	here = eni_dev->vci+vcc->vci*16;
+	DPRINTK("loc 0x%x\n",(unsigned) (eni_vcc->recv-eni_dev->ram)/4);
+	size = eni_vcc->words >> 8;
+	for (order = -1; size; order++) size >>= 1;
+	writel(0,here+4); /* descr, read = 0 */
+	writel(0,here+8); /* write, state, count = 0 */
+	if (eni_dev->rx_map[vcc->vci])
+		printk(KERN_CRIT DEV_LABEL "(itf %d): BUG - VCI %d already "
+		    "in use\n",vcc->dev->number,vcc->vci);
+	eni_dev->rx_map[vcc->vci] = vcc; /* now it counts */
+	writel(((vcc->qos.aal != ATM_AAL5 ? MID_MODE_RAW : MID_MODE_AAL5) <<
+	    MID_VCI_MODE_SHIFT) | MID_VCI_PTI_MODE |
+	    (((eni_vcc->recv-eni_dev->ram) >> (MID_LOC_SKIP+2)) <<
+	    MID_VCI_LOCATION_SHIFT) | (order << MID_VCI_SIZE_SHIFT),here);
+	return 0;
+}
+
+
+static void close_rx(struct atm_vcc *vcc)
+{
+	DECLARE_WAITQUEUE(wait,current);
+	void __iomem *here;
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+
+	eni_vcc = ENI_VCC(vcc);
+	if (!eni_vcc->rx) return;
+	eni_dev = ENI_DEV(vcc->dev);
+	if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) {
+		here = eni_dev->vci+vcc->vci*16;
+		/* block receiver */
+		writel((readl(here) & ~MID_VCI_MODE) | (MID_MODE_TRASH <<
+		    MID_VCI_MODE_SHIFT),here);
+		/* wait for receiver to become idle */
+		udelay(27);
+		/* discard pending cell */
+		writel(readl(here) & ~MID_VCI_IN_SERVICE,here);
+		/* don't accept any new ones */
+		eni_dev->rx_map[vcc->vci] = NULL;
+		/* wait for RX queue to drain */
+		DPRINTK("eni_close: waiting for RX ...\n");
+		EVENT("RX closing\n",0,0);
+		add_wait_queue(&eni_dev->rx_wait,&wait);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		barrier();
+		for (;;) {
+			/* transition service->rx: rxing++, servicing-- */
+			if (!eni_vcc->servicing) {
+				barrier();
+				if (!eni_vcc->rxing) break;
+			}
+			EVENT("drain PDUs (rx %ld, serv %ld)\n",eni_vcc->rxing,
+			    eni_vcc->servicing);
+			printk(KERN_INFO "%d+%d RX left\n",eni_vcc->servicing,
+			    eni_vcc->rxing);
+			schedule();
+			set_current_state(TASK_UNINTERRUPTIBLE);
+		}
+		for (;;) {
+			int at_end;
+			u32 tmp;
+
+			tasklet_disable(&eni_dev->task);
+			tmp = readl(eni_dev->vci+vcc->vci*16+4) & MID_VCI_READ;
+			at_end = eni_vcc->rx_pos == tmp >> MID_VCI_READ_SHIFT;
+			tasklet_enable(&eni_dev->task);
+			if (at_end) break;
+			EVENT("drain discard (host 0x%lx, nic 0x%lx)\n",
+			    eni_vcc->rx_pos,tmp);
+			printk(KERN_INFO "draining RX: host 0x%lx, nic 0x%x\n",
+			    eni_vcc->rx_pos,tmp);
+			schedule();
+			set_current_state(TASK_UNINTERRUPTIBLE);
+		}
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&eni_dev->rx_wait,&wait);
+	}
+	eni_free_mem(eni_dev,eni_vcc->recv,eni_vcc->words << 2);
+	eni_vcc->rx = NULL;
+}
+
+
+static int start_rx(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+
+	eni_dev = ENI_DEV(dev);
+	eni_dev->rx_map = (struct atm_vcc **) get_zeroed_page(GFP_KERNEL);
+	if (!eni_dev->rx_map) {
+		printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
+		    dev->number);
+		free_page((unsigned long) eni_dev->free_list);
+		return -ENOMEM;
+	}
+	memset(eni_dev->rx_map,0,PAGE_SIZE);
+	eni_dev->rx_mult = DEFAULT_RX_MULT;
+	eni_dev->fast = eni_dev->last_fast = NULL;
+	eni_dev->slow = eni_dev->last_slow = NULL;
+	init_waitqueue_head(&eni_dev->rx_wait);
+	skb_queue_head_init(&eni_dev->rx_queue);
+	eni_dev->serv_read = eni_in(MID_SERV_WRITE);
+	eni_out(0,MID_DMA_WR_RX);
+	return 0;
+}
+
+
+/*----------------------------------- TX ------------------------------------*/
+
+
+enum enq_res { enq_ok,enq_next,enq_jam };
+
+
+static inline void put_dma(int chan,u32 *dma,int *j,dma_addr_t paddr,
+    u32 size)
+{
+	u32 init,words;
+
+	DPRINTK("put_dma: 0x%lx+0x%x\n",(unsigned long) paddr,size);
+	EVENT("put_dma: 0x%lx+0x%lx\n",(unsigned long) paddr,size);
+#if 0 /* don't complain anymore */
+	if (paddr & 3)
+		printk(KERN_ERR "put_dma: unaligned addr (0x%lx)\n",paddr);
+	if (size & 3)
+		printk(KERN_ERR "put_dma: unaligned size (0x%lx)\n",size);
+#endif
+	if (paddr & 3) {
+		init = 4-(paddr & 3);
+		if (init > size || size < 7) init = size;
+		DPRINTK("put_dma: %lx DMA: %d/%d bytes\n",
+		    (unsigned long) paddr,init,size);
+		dma[(*j)++] = MID_DT_BYTE | (init << MID_DMA_COUNT_SHIFT) |
+		    (chan << MID_DMA_CHAN_SHIFT);
+		dma[(*j)++] = paddr;
+		paddr += init;
+		size -= init;
+	}
+	words = size >> 2;
+	size &= 3;
+	if (words && (paddr & 31)) {
+		init = 8-((paddr & 31) >> 2);
+		if (init > words) init = words;
+		DPRINTK("put_dma: %lx DMA: %d/%d words\n",
+		    (unsigned long) paddr,init,words);
+		dma[(*j)++] = MID_DT_WORD | (init << MID_DMA_COUNT_SHIFT) |
+		    (chan << MID_DMA_CHAN_SHIFT);
+		dma[(*j)++] = paddr;
+		paddr += init << 2;
+		words -= init;
+	}
+#ifdef CONFIG_ATM_ENI_BURST_TX_16W /* may work with some PCI chipsets ... */
+	if (words & ~15) {
+		DPRINTK("put_dma: %lx DMA: %d*16/%d words\n",
+		    (unsigned long) paddr,words >> 4,words);
+		dma[(*j)++] = MID_DT_16W | ((words >> 4) << MID_DMA_COUNT_SHIFT)
+		    | (chan << MID_DMA_CHAN_SHIFT);
+		dma[(*j)++] = paddr;
+		paddr += (words & ~15) << 2;
+		words &= 15;
+	}
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_TX_8W /* recommended */
+	if (words & ~7) {
+		DPRINTK("put_dma: %lx DMA: %d*8/%d words\n",
+		    (unsigned long) paddr,words >> 3,words);
+		dma[(*j)++] = MID_DT_8W | ((words >> 3) << MID_DMA_COUNT_SHIFT)
+		    | (chan << MID_DMA_CHAN_SHIFT);
+		dma[(*j)++] = paddr;
+		paddr += (words & ~7) << 2;
+		words &= 7;
+	}
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_TX_4W /* probably useless if TX_8W or TX_16W */
+	if (words & ~3) {
+		DPRINTK("put_dma: %lx DMA: %d*4/%d words\n",
+		    (unsigned long) paddr,words >> 2,words);
+		dma[(*j)++] = MID_DT_4W | ((words >> 2) << MID_DMA_COUNT_SHIFT)
+		    | (chan << MID_DMA_CHAN_SHIFT);
+		dma[(*j)++] = paddr;
+		paddr += (words & ~3) << 2;
+		words &= 3;
+	}
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_TX_2W /* probably useless if TX_4W, TX_8W, ... */
+	if (words & ~1) {
+		DPRINTK("put_dma: %lx DMA: %d*2/%d words\n",
+		    (unsigned long) paddr,words >> 1,words);
+		dma[(*j)++] = MID_DT_2W | ((words >> 1) << MID_DMA_COUNT_SHIFT)
+		    | (chan << MID_DMA_CHAN_SHIFT);
+		dma[(*j)++] = paddr;
+		paddr += (words & ~1) << 2;
+		words &= 1;
+	}
+#endif
+	if (words) {
+		DPRINTK("put_dma: %lx DMA: %d words\n",(unsigned long) paddr,
+		    words);
+		dma[(*j)++] = MID_DT_WORD | (words << MID_DMA_COUNT_SHIFT) |
+		    (chan << MID_DMA_CHAN_SHIFT);
+		dma[(*j)++] = paddr;
+		paddr += words << 2;
+	}
+	if (size) {
+		DPRINTK("put_dma: %lx DMA: %d bytes\n",(unsigned long) paddr,
+		    size);
+		dma[(*j)++] = MID_DT_BYTE | (size << MID_DMA_COUNT_SHIFT) |
+		    (chan << MID_DMA_CHAN_SHIFT);
+		dma[(*j)++] = paddr;
+	}
+}
+
+
+static enum enq_res do_tx(struct sk_buff *skb)
+{
+	struct atm_vcc *vcc;
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+	struct eni_tx *tx;
+	dma_addr_t paddr;
+	u32 dma_rd,dma_wr;
+	u32 size; /* in words */
+	int aal5,dma_size,i,j;
+
+	DPRINTK(">do_tx\n");
+	NULLCHECK(skb);
+	EVENT("do_tx: skb=0x%lx, %ld bytes\n",(unsigned long) skb,skb->len);
+	vcc = ATM_SKB(skb)->vcc;
+	NULLCHECK(vcc);
+	eni_dev = ENI_DEV(vcc->dev);
+	NULLCHECK(eni_dev);
+	eni_vcc = ENI_VCC(vcc);
+	tx = eni_vcc->tx;
+	NULLCHECK(tx);
+#if 0 /* Enable this for testing with the "align" program */
+	{
+		unsigned int hack = *((char *) skb->data)-'0';
+
+		if (hack < 8) {
+			skb->data += hack;
+			skb->len -= hack;
+		}
+	}
+#endif
+#if 0 /* should work now */
+	if ((unsigned long) skb->data & 3)
+		printk(KERN_ERR DEV_LABEL "(itf %d): VCI %d has mis-aligned "
+		    "TX data\n",vcc->dev->number,vcc->vci);
+#endif
+	/*
+	 * Potential future IP speedup: make hard_header big enough to put
+	 * segmentation descriptor directly into PDU. Saves: 4 slave writes,
+	 * 1 DMA xfer & 2 DMA'ed bytes (protocol layering is for wimps :-)
+	 */
+
+	aal5 = vcc->qos.aal == ATM_AAL5;
+	/* check space in buffer */
+	if (!aal5)
+		size = (ATM_CELL_PAYLOAD >> 2)+TX_DESCR_SIZE;
+			/* cell without HEC plus segmentation header (includes
+			   four-byte cell header) */
+	else {
+		size = skb->len+4*AAL5_TRAILER+ATM_CELL_PAYLOAD-1;
+			/* add AAL5 trailer */
+		size = ((size-(size % ATM_CELL_PAYLOAD)) >> 2)+TX_DESCR_SIZE;
+						/* add segmentation header */
+	}
+	/*
+	 * Can I move tx_pos by size bytes without getting closer than TX_GAP
+	 * to the read pointer ? TX_GAP means to leave some space for what
+	 * the manual calls "too close".
+	 */
+	if (!NEPMOK(tx->tx_pos,size+TX_GAP,
+	    eni_in(MID_TX_RDPTR(tx->index)),tx->words)) {
+		DPRINTK(DEV_LABEL "(itf %d): TX full (size %d)\n",
+		    vcc->dev->number,size);
+		return enq_next;
+	}
+	/* check DMA */
+	dma_wr = eni_in(MID_DMA_WR_TX);
+	dma_rd = eni_in(MID_DMA_RD_TX);
+	dma_size = 3; /* JK for descriptor and final fill, plus final size
+			 mis-alignment fix */
+DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
+	if (!skb_shinfo(skb)->nr_frags) dma_size += 5;
+	else dma_size += 5*(skb_shinfo(skb)->nr_frags+1);
+	if (dma_size > TX_DMA_BUF) {
+		printk(KERN_CRIT DEV_LABEL "(itf %d): needs %d DMA entries "
+		    "(got only %d)\n",vcc->dev->number,dma_size,TX_DMA_BUF);
+	}
+	DPRINTK("dma_wr is %d, tx_pos is %ld\n",dma_wr,tx->tx_pos);
+	if (dma_wr != dma_rd && ((dma_rd+NR_DMA_TX-dma_wr) & (NR_DMA_TX-1)) <
+	     dma_size) {
+		printk(KERN_WARNING DEV_LABEL "(itf %d): TX DMA full\n",
+		    vcc->dev->number);
+		return enq_jam;
+	}
+	paddr = pci_map_single(eni_dev->pci_dev,skb->data,skb->len,
+	    PCI_DMA_TODEVICE);
+	ENI_PRV_PADDR(skb) = paddr;
+	/* prepare DMA queue entries */
+	j = 0;
+	eni_dev->dma[j++] = (((tx->tx_pos+TX_DESCR_SIZE) & (tx->words-1)) <<
+	     MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
+	     MID_DT_JK;
+	j++;
+	if (!skb_shinfo(skb)->nr_frags)
+		if (aal5) put_dma(tx->index,eni_dev->dma,&j,paddr,skb->len);
+		else put_dma(tx->index,eni_dev->dma,&j,paddr+4,skb->len-4);
+	else {
+DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
+		for (i = -1; i < skb_shinfo(skb)->nr_frags; i++)
+			if (i == -1)
+				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
+				    skb->data,
+				    skb->len - skb->data_len);
+			else
+				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
+				    skb_shinfo(skb)->frags[i].page + skb_shinfo(skb)->frags[i].page_offset,
+				    skb_shinfo(skb)->frags[i].size);
+	}
+	if (skb->len & 3)
+		put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3));
+	/* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */
+	eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) <<
+	     MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
+	     MID_DMA_END | MID_DT_JK;
+	j++;
+	DPRINTK("DMA at end: %d\n",j);
+	/* store frame */
+	writel((MID_SEG_TX_ID << MID_SEG_ID_SHIFT) |
+	    (aal5 ? MID_SEG_AAL5 : 0) | (tx->prescaler << MID_SEG_PR_SHIFT) |
+	    (tx->resolution << MID_SEG_RATE_SHIFT) |
+	    (size/(ATM_CELL_PAYLOAD/4)),tx->send+tx->tx_pos*4);
+/*printk("dsc = 0x%08lx\n",(unsigned long) readl(tx->send+tx->tx_pos*4));*/
+	writel((vcc->vci << MID_SEG_VCI_SHIFT) |
+            (aal5 ? 0 : (skb->data[3] & 0xf)) |
+	    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ? MID_SEG_CLP : 0),
+	    tx->send+((tx->tx_pos+1) & (tx->words-1))*4);
+	DPRINTK("size: %d, len:%d\n",size,skb->len);
+	if (aal5)
+		writel(skb->len,tx->send+
+                    ((tx->tx_pos+size-AAL5_TRAILER) & (tx->words-1))*4);
+	j = j >> 1;
+	for (i = 0; i < j; i++) {
+		writel(eni_dev->dma[i*2],eni_dev->tx_dma+dma_wr*8);
+		writel(eni_dev->dma[i*2+1],eni_dev->tx_dma+dma_wr*8+4);
+		dma_wr = (dma_wr+1) & (NR_DMA_TX-1);
+	}
+	ENI_PRV_POS(skb) = tx->tx_pos;
+	ENI_PRV_SIZE(skb) = size;
+	ENI_VCC(vcc)->txing += size;
+	tx->tx_pos = (tx->tx_pos+size) & (tx->words-1);
+	DPRINTK("dma_wr set to %d, tx_pos is now %ld\n",dma_wr,tx->tx_pos);
+	eni_out(dma_wr,MID_DMA_WR_TX);
+	skb_queue_tail(&eni_dev->tx_queue,skb);
+queued++;
+	return enq_ok;
+}
+
+
+static void poll_tx(struct atm_dev *dev)
+{
+	struct eni_tx *tx;
+	struct sk_buff *skb;
+	enum enq_res res;
+	int i;
+
+	DPRINTK(">poll_tx\n");
+	for (i = NR_CHAN-1; i >= 0; i--) {
+		tx = &ENI_DEV(dev)->tx[i];
+		if (tx->send)
+			while ((skb = skb_dequeue(&tx->backlog))) {
+				res = do_tx(skb);
+				if (res == enq_ok) continue;
+				DPRINTK("re-queuing TX PDU\n");
+				skb_queue_head(&tx->backlog,skb);
+requeued++;
+				if (res == enq_jam) return;
+				break;
+			}
+	}
+}
+
+
+static void dequeue_tx(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+	struct atm_vcc *vcc;
+	struct sk_buff *skb;
+	struct eni_tx *tx;
+
+	NULLCHECK(dev);
+	eni_dev = ENI_DEV(dev);
+	NULLCHECK(eni_dev);
+	while ((skb = skb_dequeue(&eni_dev->tx_queue))) {
+		vcc = ATM_SKB(skb)->vcc;
+		NULLCHECK(vcc);
+		tx = ENI_VCC(vcc)->tx;
+		NULLCHECK(ENI_VCC(vcc)->tx);
+		DPRINTK("dequeue_tx: next 0x%lx curr 0x%x\n",ENI_PRV_POS(skb),
+		    (unsigned) eni_in(MID_TX_DESCRSTART(tx->index)));
+		if (ENI_VCC(vcc)->txing < tx->words && ENI_PRV_POS(skb) ==
+		    eni_in(MID_TX_DESCRSTART(tx->index))) {
+			skb_queue_head(&eni_dev->tx_queue,skb);
+			break;
+		}
+		ENI_VCC(vcc)->txing -= ENI_PRV_SIZE(skb);
+		pci_unmap_single(eni_dev->pci_dev,ENI_PRV_PADDR(skb),skb->len,
+		    PCI_DMA_TODEVICE);
+		if (vcc->pop) vcc->pop(vcc,skb);
+		else dev_kfree_skb_irq(skb);
+		atomic_inc(&vcc->stats->tx);
+		wake_up(&eni_dev->tx_wait);
+dma_complete++;
+	}
+}
+
+
+static struct eni_tx *alloc_tx(struct eni_dev *eni_dev,int ubr)
+{
+	int i;
+
+	for (i = !ubr; i < NR_CHAN; i++)
+		if (!eni_dev->tx[i].send) return eni_dev->tx+i;
+	return NULL;
+}
+
+
+static int comp_tx(struct eni_dev *eni_dev,int *pcr,int reserved,int *pre,
+    int *res,int unlimited)
+{
+	static const int pre_div[] = { 4,16,128,2048 };
+	    /* 2^(((x+2)^2-(x+2))/2+1) */
+
+	if (unlimited) *pre = *res = 0;
+	else {
+		if (*pcr > 0) {
+			int div;
+
+			for (*pre = 0; *pre < 3; (*pre)++)
+				if (TS_CLOCK/pre_div[*pre]/64 <= *pcr) break;
+			div = pre_div[*pre]**pcr;
+			DPRINTK("min div %d\n",div);
+			*res = TS_CLOCK/div-1;
+		}
+		else {
+			int div;
+
+			if (!*pcr) *pcr = eni_dev->tx_bw+reserved;
+			for (*pre = 3; *pre >= 0; (*pre)--)
+				if (TS_CLOCK/pre_div[*pre]/64 > -*pcr) break;
+			if (*pre < 3) (*pre)++; /* else fail later */
+			div = pre_div[*pre]*-*pcr;
+			DPRINTK("max div %d\n",div);
+			*res = (TS_CLOCK+div-1)/div-1;
+		}
+		if (*res < 0) *res = 0;
+		if (*res > MID_SEG_MAX_RATE) *res = MID_SEG_MAX_RATE;
+	}
+	*pcr = TS_CLOCK/pre_div[*pre]/(*res+1);
+	DPRINTK("out pcr: %d (%d:%d)\n",*pcr,*pre,*res);
+	return 0;
+}
+
+
+static int reserve_or_set_tx(struct atm_vcc *vcc,struct atm_trafprm *txtp,
+    int set_rsv,int set_shp)
+{
+	struct eni_dev *eni_dev = ENI_DEV(vcc->dev);
+	struct eni_vcc *eni_vcc = ENI_VCC(vcc);
+	struct eni_tx *tx;
+	unsigned long size;
+	void __iomem *mem;
+	int rate,ubr,unlimited,new_tx;
+	int pre,res,order;
+	int error;
+
+	rate = atm_pcr_goal(txtp);
+	ubr = txtp->traffic_class == ATM_UBR;
+	unlimited = ubr && (!rate || rate <= -ATM_OC3_PCR ||
+	    rate >= ATM_OC3_PCR);
+	if (!unlimited) {
+		size = txtp->max_sdu*eni_dev->tx_mult/100;
+		if (size > MID_MAX_BUF_SIZE && txtp->max_sdu <=
+		    MID_MAX_BUF_SIZE)
+			size = MID_MAX_BUF_SIZE;
+	}
+	else {
+		if (eni_dev->ubr) {
+			eni_vcc->tx = eni_dev->ubr;
+			txtp->pcr = ATM_OC3_PCR;
+			return 0;
+		}
+		size = UBR_BUFFER;
+	}
+	new_tx = !eni_vcc->tx;
+	mem = NULL; /* for gcc */
+	if (!new_tx) tx = eni_vcc->tx;
+	else {
+		mem = eni_alloc_mem(eni_dev,&size);
+		if (!mem) return -ENOBUFS;
+		tx = alloc_tx(eni_dev,unlimited);
+		if (!tx) {
+			eni_free_mem(eni_dev,mem,size);
+			return -EBUSY;
+		}
+		DPRINTK("got chan %d\n",tx->index);
+		tx->reserved = tx->shaping = 0;
+		tx->send = mem;
+		tx->words = size >> 2;
+		skb_queue_head_init(&tx->backlog);
+		for (order = 0; size > (1 << (order+10)); order++);
+		eni_out((order << MID_SIZE_SHIFT) |
+		    ((tx->send-eni_dev->ram) >> (MID_LOC_SKIP+2)),
+		    MID_TX_PLACE(tx->index));
+		tx->tx_pos = eni_in(MID_TX_DESCRSTART(tx->index)) &
+		    MID_DESCR_START;
+	}
+	error = comp_tx(eni_dev,&rate,tx->reserved,&pre,&res,unlimited);
+	if (!error  && txtp->min_pcr > rate) error = -EINVAL;
+	if (!error && txtp->max_pcr && txtp->max_pcr != ATM_MAX_PCR &&
+	    txtp->max_pcr < rate) error = -EINVAL;
+	if (!error && !ubr && rate > eni_dev->tx_bw+tx->reserved)
+		error = -EINVAL;
+	if (!error && set_rsv && !set_shp && rate < tx->shaping)
+		error = -EINVAL;
+	if (!error && !set_rsv && rate > tx->reserved && !ubr)
+		error = -EINVAL;
+	if (error) {
+		if (new_tx) {
+			tx->send = NULL;
+			eni_free_mem(eni_dev,mem,size);
+		}
+		return error;
+	}
+	txtp->pcr = rate;
+	if (set_rsv && !ubr) {
+		eni_dev->tx_bw += tx->reserved;
+		tx->reserved = rate;
+		eni_dev->tx_bw -= rate;
+	}
+	if (set_shp || (unlimited && new_tx)) {
+		if (unlimited && new_tx) eni_dev->ubr = tx;
+		tx->prescaler = pre;
+		tx->resolution = res;
+		tx->shaping = rate;
+	}
+	if (set_shp) eni_vcc->tx = tx;
+	DPRINTK("rsv %d shp %d\n",tx->reserved,tx->shaping);
+	return 0;
+}
+
+
+static int open_tx_first(struct atm_vcc *vcc)
+{
+	ENI_VCC(vcc)->tx = NULL;
+	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;
+	ENI_VCC(vcc)->txing = 0;
+	return reserve_or_set_tx(vcc,&vcc->qos.txtp,1,1);
+}
+
+
+static int open_tx_second(struct atm_vcc *vcc)
+{
+	return 0; /* nothing to do */
+}
+
+
+static void close_tx(struct atm_vcc *vcc)
+{
+	DECLARE_WAITQUEUE(wait,current);
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+
+	eni_vcc = ENI_VCC(vcc);
+	if (!eni_vcc->tx) return;
+	eni_dev = ENI_DEV(vcc->dev);
+	/* wait for TX queue to drain */
+	DPRINTK("eni_close: waiting for TX ...\n");
+	add_wait_queue(&eni_dev->tx_wait,&wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	for (;;) {
+		int txing;
+
+		tasklet_disable(&eni_dev->task);
+		txing = skb_peek(&eni_vcc->tx->backlog) || eni_vcc->txing;
+		tasklet_enable(&eni_dev->task);
+		if (!txing) break;
+		DPRINTK("%d TX left\n",eni_vcc->txing);
+		schedule();
+		set_current_state(TASK_UNINTERRUPTIBLE);
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&eni_dev->tx_wait,&wait);
+	if (eni_vcc->tx != eni_dev->ubr) {
+		/*
+		 * Looping a few times in here is probably far cheaper than
+		 * keeping track of TX completions all the time, so let's poll
+		 * a bit ...
+		 */
+		while (eni_in(MID_TX_RDPTR(eni_vcc->tx->index)) !=
+		    eni_in(MID_TX_DESCRSTART(eni_vcc->tx->index)))
+			schedule();
+		eni_free_mem(eni_dev,eni_vcc->tx->send,eni_vcc->tx->words << 2);
+		eni_vcc->tx->send = NULL;
+		eni_dev->tx_bw += eni_vcc->tx->reserved;
+	}
+	eni_vcc->tx = NULL;
+}
+
+
+static int start_tx(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+	int i;
+
+	eni_dev = ENI_DEV(dev);
+	eni_dev->lost = 0;
+	eni_dev->tx_bw = ATM_OC3_PCR;
+	eni_dev->tx_mult = DEFAULT_TX_MULT;
+	init_waitqueue_head(&eni_dev->tx_wait);
+	eni_dev->ubr = NULL;
+	skb_queue_head_init(&eni_dev->tx_queue);
+	eni_out(0,MID_DMA_WR_TX);
+	for (i = 0; i < NR_CHAN; i++) {
+		eni_dev->tx[i].send = NULL;
+		eni_dev->tx[i].index = i;
+	}
+	return 0;
+}
+
+
+/*--------------------------------- common ----------------------------------*/
+
+
+#if 0 /* may become useful again when tuning things */
+
+static void foo(void)
+{
+printk(KERN_INFO
+  "tx_complete=%d,dma_complete=%d,queued=%d,requeued=%d,sub=%d,\n"
+  "backlogged=%d,rx_enqueued=%d,rx_dequeued=%d,putting=%d,pushed=%d\n",
+  tx_complete,dma_complete,queued,requeued,submitted,backlogged,
+  rx_enqueued,rx_dequeued,putting,pushed);
+if (eni_boards) printk(KERN_INFO "loss: %ld\n",ENI_DEV(eni_boards)->lost);
+}
+
+#endif
+
+
+static void bug_int(struct atm_dev *dev,unsigned long reason)
+{
+	struct eni_dev *eni_dev;
+
+	DPRINTK(">bug_int\n");
+	eni_dev = ENI_DEV(dev);
+	if (reason & MID_DMA_ERR_ACK)
+		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
+		    "error\n",dev->number);
+	if (reason & MID_TX_IDENT_MISM)
+		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - ident "
+		    "mismatch\n",dev->number);
+	if (reason & MID_TX_DMA_OVFL)
+		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
+		    "overflow\n",dev->number);
+	EVENT("---dump ends here---\n",0,0);
+	printk(KERN_NOTICE "---recent events---\n");
+	event_dump();
+}
+
+
+static irqreturn_t eni_int(int irq,void *dev_id,struct pt_regs *regs)
+{
+	struct atm_dev *dev;
+	struct eni_dev *eni_dev;
+	u32 reason;
+
+	DPRINTK(">eni_int\n");
+	dev = dev_id;
+	eni_dev = ENI_DEV(dev);
+	reason = eni_in(MID_ISA);
+	DPRINTK(DEV_LABEL ": int 0x%lx\n",(unsigned long) reason);
+	/*
+	 * Must handle these two right now, because reading ISA doesn't clear
+	 * them, so they re-occur and we never make it to the tasklet. Since
+	 * they're rare, we don't mind the occasional invocation of eni_tasklet
+	 * with eni_dev->events == 0.
+	 */
+	if (reason & MID_STAT_OVFL) {
+		EVENT("stat overflow\n",0,0);
+		eni_dev->lost += eni_in(MID_STAT) & MID_OVFL_TRASH;
+	}
+	if (reason & MID_SUNI_INT) {
+		EVENT("SUNI int\n",0,0);
+		dev->phy->interrupt(dev);
+#if 0
+		foo();
+#endif
+	}
+	spin_lock(&eni_dev->lock);
+	eni_dev->events |= reason;
+	spin_unlock(&eni_dev->lock);
+	tasklet_schedule(&eni_dev->task);
+	return IRQ_HANDLED;
+}
+
+
+static void eni_tasklet(unsigned long data)
+{
+	struct atm_dev *dev = (struct atm_dev *) data;
+	struct eni_dev *eni_dev = ENI_DEV(dev);
+	unsigned long flags;
+	u32 events;
+
+	DPRINTK("eni_tasklet (dev %p)\n",dev);
+	spin_lock_irqsave(&eni_dev->lock,flags);
+	events = xchg(&eni_dev->events,0);
+	spin_unlock_irqrestore(&eni_dev->lock,flags);
+	if (events & MID_RX_DMA_COMPLETE) {
+		EVENT("INT: RX DMA complete, starting dequeue_rx\n",0,0);
+		dequeue_rx(dev);
+		EVENT("dequeue_rx done, starting poll_rx\n",0,0);
+		poll_rx(dev);
+		EVENT("poll_rx done\n",0,0);
+		/* poll_tx ? */
+	}
+	if (events & MID_SERVICE) {
+		EVENT("INT: service, starting get_service\n",0,0);
+		get_service(dev);
+		EVENT("get_service done, starting poll_rx\n",0,0);
+		poll_rx(dev);
+		EVENT("poll_rx done\n",0,0);
+	}
+ 	if (events & MID_TX_DMA_COMPLETE) {
+		EVENT("INT: TX DMA COMPLETE\n",0,0);
+		dequeue_tx(dev);
+	}
+	if (events & MID_TX_COMPLETE) {
+		EVENT("INT: TX COMPLETE\n",0,0);
+tx_complete++;
+		wake_up(&eni_dev->tx_wait);
+		/* poll_rx ? */
+	}
+	if (events & (MID_DMA_ERR_ACK | MID_TX_IDENT_MISM | MID_TX_DMA_OVFL)) {
+		EVENT("bug interrupt\n",0,0);
+		bug_int(dev,events);
+	}
+	poll_tx(dev);
+}
+
+
+/*--------------------------------- entries ---------------------------------*/
+
+
+static const char *media_name[] __devinitdata = {
+    "MMF", "SMF", "MMF", "03?", /*  0- 3 */
+    "UTP", "05?", "06?", "07?", /*  4- 7 */
+    "TAXI","09?", "10?", "11?", /*  8-11 */
+    "12?", "13?", "14?", "15?", /* 12-15 */
+    "MMF", "SMF", "18?", "19?", /* 16-19 */
+    "UTP", "21?", "22?", "23?", /* 20-23 */
+    "24?", "25?", "26?", "27?", /* 24-27 */
+    "28?", "29?", "30?", "31?"  /* 28-31 */
+};
+
+
+#define SET_SEPROM \
+  ({ if (!error && !pci_error) { \
+    pci_error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,tonga); \
+    udelay(10); /* 10 usecs */ \
+  } })
+#define GET_SEPROM \
+  ({ if (!error && !pci_error) { \
+    pci_error = pci_read_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,&tonga); \
+    udelay(10); /* 10 usecs */ \
+  } })
+
+
+static int __devinit get_esi_asic(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+	unsigned char tonga;
+	int error,failed,pci_error;
+	int address,i,j;
+
+	eni_dev = ENI_DEV(dev);
+	error = pci_error = 0;
+	tonga = SEPROM_MAGIC | SEPROM_DATA | SEPROM_CLK;
+	SET_SEPROM;
+	for (i = 0; i < ESI_LEN && !error && !pci_error; i++) {
+		/* start operation */
+		tonga |= SEPROM_DATA;
+		SET_SEPROM;
+		tonga |= SEPROM_CLK;
+		SET_SEPROM;
+		tonga &= ~SEPROM_DATA;
+		SET_SEPROM;
+		tonga &= ~SEPROM_CLK;
+		SET_SEPROM;
+		/* send address */
+		address = ((i+SEPROM_ESI_BASE) << 1)+1;
+		for (j = 7; j >= 0; j--) {
+			tonga = (address >> j) & 1 ? tonga | SEPROM_DATA :
+			    tonga & ~SEPROM_DATA;
+			SET_SEPROM;
+			tonga |= SEPROM_CLK;
+			SET_SEPROM;
+			tonga &= ~SEPROM_CLK;
+			SET_SEPROM;
+		}
+		/* get ack */
+		tonga |= SEPROM_DATA;
+		SET_SEPROM;
+		tonga |= SEPROM_CLK;
+		SET_SEPROM;
+		GET_SEPROM;
+		failed = tonga & SEPROM_DATA;
+		tonga &= ~SEPROM_CLK;
+		SET_SEPROM;
+		tonga |= SEPROM_DATA;
+		SET_SEPROM;
+		if (failed) error = -EIO;
+		else {
+			dev->esi[i] = 0;
+			for (j = 7; j >= 0; j--) {
+				dev->esi[i] <<= 1;
+				tonga |= SEPROM_DATA;
+				SET_SEPROM;
+				tonga |= SEPROM_CLK;
+				SET_SEPROM;
+				GET_SEPROM;
+				if (tonga & SEPROM_DATA) dev->esi[i] |= 1;
+				tonga &= ~SEPROM_CLK;
+				SET_SEPROM;
+				tonga |= SEPROM_DATA;
+				SET_SEPROM;
+			}
+			/* get ack */
+			tonga |= SEPROM_DATA;
+			SET_SEPROM;
+			tonga |= SEPROM_CLK;
+			SET_SEPROM;
+			GET_SEPROM;
+			if (!(tonga & SEPROM_DATA)) error = -EIO;
+			tonga &= ~SEPROM_CLK;
+			SET_SEPROM;
+			tonga |= SEPROM_DATA;
+			SET_SEPROM;
+		}
+		/* stop operation */
+		tonga &= ~SEPROM_DATA;
+		SET_SEPROM;
+		tonga |= SEPROM_CLK;
+		SET_SEPROM;
+		tonga |= SEPROM_DATA;
+		SET_SEPROM;
+	}
+	if (pci_error) {
+		printk(KERN_ERR DEV_LABEL "(itf %d): error reading ESI "
+		    "(0x%02x)\n",dev->number,pci_error);
+		error = -EIO;
+	}
+	return error;
+}
+
+
+#undef SET_SEPROM
+#undef GET_SEPROM
+
+
+static int __devinit get_esi_fpga(struct atm_dev *dev, void __iomem *base)
+{
+	void __iomem *mac_base;
+	int i;
+
+	mac_base = base+EPROM_SIZE-sizeof(struct midway_eprom);
+	for (i = 0; i < ESI_LEN; i++) dev->esi[i] = readb(mac_base+(i^3));
+	return 0;
+}
+
+
+static int __devinit eni_do_init(struct atm_dev *dev)
+{
+	struct midway_eprom __iomem *eprom;
+	struct eni_dev *eni_dev;
+	struct pci_dev *pci_dev;
+	unsigned long real_base;
+	void __iomem *base;
+	unsigned char revision;
+	int error,i,last;
+
+	DPRINTK(">eni_init\n");
+	dev->ci_range.vpi_bits = 0;
+	dev->ci_range.vci_bits = NR_VCI_LD;
+	dev->link_rate = ATM_OC3_PCR;
+	eni_dev = ENI_DEV(dev);
+	pci_dev = eni_dev->pci_dev;
+	real_base = pci_resource_start(pci_dev, 0);
+	eni_dev->irq = pci_dev->irq;
+	error = pci_read_config_byte(pci_dev,PCI_REVISION_ID,&revision);
+	if (error) {
+		printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%02x\n",
+		    dev->number,error);
+		return -EINVAL;
+	}
+	if ((error = pci_write_config_word(pci_dev,PCI_COMMAND,
+	    PCI_COMMAND_MEMORY |
+	    (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
+		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory "
+		    "(0x%02x)\n",dev->number,error);
+		return -EIO;
+	}
+	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%lx,irq=%d,",
+	    dev->number,revision,real_base,eni_dev->irq);
+	if (!(base = ioremap_nocache(real_base,MAP_MAX_SIZE))) {
+		printk("\n");
+		printk(KERN_ERR DEV_LABEL "(itf %d): can't set up page "
+		    "mapping\n",dev->number);
+		return error;
+	}
+	eni_dev->base_diff = real_base - (unsigned long) base;
+	/* id may not be present in ASIC Tonga boards - check this @@@ */
+	if (!eni_dev->asic) {
+		eprom = (base+EPROM_SIZE-sizeof(struct midway_eprom));
+		if (readl(&eprom->magic) != ENI155_MAGIC) {
+			printk("\n");
+			printk(KERN_ERR KERN_ERR DEV_LABEL "(itf %d): bad "
+			    "magic - expected 0x%x, got 0x%x\n",dev->number,
+			    ENI155_MAGIC,(unsigned) readl(&eprom->magic));
+			return -EINVAL;
+		}
+	}
+	eni_dev->phy = base+PHY_BASE;
+	eni_dev->reg = base+REG_BASE;
+	eni_dev->ram = base+RAM_BASE;
+	last = MAP_MAX_SIZE-RAM_BASE;
+	for (i = last-RAM_INCREMENT; i >= 0; i -= RAM_INCREMENT) {
+		writel(0x55555555,eni_dev->ram+i);
+		if (readl(eni_dev->ram+i) != 0x55555555) last = i;
+		else {
+			writel(0xAAAAAAAA,eni_dev->ram+i);
+			if (readl(eni_dev->ram+i) != 0xAAAAAAAA) last = i;
+			else writel(i,eni_dev->ram+i);
+		}
+	}
+	for (i = 0; i < last; i += RAM_INCREMENT)
+		if (readl(eni_dev->ram+i) != i) break;
+	eni_dev->mem = i;
+	memset_io(eni_dev->ram,0,eni_dev->mem);
+	/* TODO: should shrink allocation now */
+	printk("mem=%dkB (",eni_dev->mem >> 10);
+	/* TODO: check for non-SUNI, check for TAXI ? */
+	if (!(eni_in(MID_RES_ID_MCON) & 0x200) != !eni_dev->asic) {
+		printk(")\n");
+		printk(KERN_ERR DEV_LABEL "(itf %d): ERROR - wrong id 0x%x\n",
+		    dev->number,(unsigned) eni_in(MID_RES_ID_MCON));
+		return -EINVAL;
+	}
+	error = eni_dev->asic ? get_esi_asic(dev) : get_esi_fpga(dev,base);
+	if (error) return error;
+	for (i = 0; i < ESI_LEN; i++)
+		printk("%s%02X",i ? "-" : "",dev->esi[i]);
+	printk(")\n");
+	printk(KERN_NOTICE DEV_LABEL "(itf %d): %s,%s\n",dev->number,
+	    eni_in(MID_RES_ID_MCON) & 0x200 ? "ASIC" : "FPGA",
+	    media_name[eni_in(MID_RES_ID_MCON) & DAUGTHER_ID]);
+	return suni_init(dev);
+}
+
+
+static int __devinit eni_start(struct atm_dev *dev)
+{
+	struct eni_dev *eni_dev;
+	
+	void __iomem *buf;
+	unsigned long buffer_mem;
+	int error;
+
+	DPRINTK(">eni_start\n");
+	eni_dev = ENI_DEV(dev);
+	if (request_irq(eni_dev->irq,&eni_int,SA_SHIRQ,DEV_LABEL,dev)) {
+		printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
+		    dev->number,eni_dev->irq);
+		return -EAGAIN;
+	}
+	/* @@@ should release IRQ on error */
+	pci_set_master(eni_dev->pci_dev);
+	if ((error = pci_write_config_word(eni_dev->pci_dev,PCI_COMMAND,
+	    PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+	    (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
+		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"
+		    "master (0x%02x)\n",dev->number,error);
+		return error;
+	}
+	if ((error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,
+	    END_SWAP_DMA))) {
+		printk(KERN_ERR DEV_LABEL "(itf %d): can't set endian swap "
+		    "(0x%02x)\n",dev->number,error);
+		return error;
+	}
+	/* determine addresses of internal tables */
+	eni_dev->vci = eni_dev->ram;
+	eni_dev->rx_dma = eni_dev->ram+NR_VCI*16;
+	eni_dev->tx_dma = eni_dev->rx_dma+NR_DMA_RX*8;
+	eni_dev->service = eni_dev->tx_dma+NR_DMA_TX*8;
+	buf = eni_dev->service+NR_SERVICE*4;
+	DPRINTK("vci 0x%lx,rx 0x%lx, tx 0x%lx,srv 0x%lx,buf 0x%lx\n",
+	     eni_dev->vci,eni_dev->rx_dma,eni_dev->tx_dma,
+	     eni_dev->service,buf);
+	spin_lock_init(&eni_dev->lock);
+	tasklet_init(&eni_dev->task,eni_tasklet,(unsigned long) dev);
+	eni_dev->events = 0;
+	/* initialize memory management */
+	buffer_mem = eni_dev->mem - (buf - eni_dev->ram);
+	eni_dev->free_list_size = buffer_mem/MID_MIN_BUF_SIZE/2;
+	eni_dev->free_list = (struct eni_free *) kmalloc(
+	    sizeof(struct eni_free)*(eni_dev->free_list_size+1),GFP_KERNEL);
+	if (!eni_dev->free_list) {
+		printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
+		    dev->number);
+		return -ENOMEM;
+	}
+	eni_dev->free_len = 0;
+	eni_put_free(eni_dev,buf,buffer_mem);
+	memset_io(eni_dev->vci,0,16*NR_VCI); /* clear VCI table */
+	/*
+	 * byte_addr  free (k)
+	 * 0x00000000     512  VCI table
+	 * 0x00004000	  496  RX DMA
+	 * 0x00005000	  492  TX DMA
+	 * 0x00006000	  488  service list
+	 * 0x00007000	  484  buffers
+	 * 0x00080000	    0  end (512kB)
+	 */
+	eni_out(0xffffffff,MID_IE);
+	error = start_tx(dev);
+	if (error) return error;
+	error = start_rx(dev);
+	if (error) return error;
+	error = dev->phy->start(dev);
+	if (error) return error;
+	eni_out(eni_in(MID_MC_S) | (1 << MID_INT_SEL_SHIFT) |
+	    MID_TX_LOCK_MODE | MID_DMA_ENABLE | MID_TX_ENABLE | MID_RX_ENABLE,
+	    MID_MC_S);
+	    /* Tonga uses SBus INTReq1 */
+	(void) eni_in(MID_ISA); /* clear Midway interrupts */
+	return 0;
+}
+
+
+static void eni_close(struct atm_vcc *vcc)
+{
+	DPRINTK(">eni_close\n");
+	if (!ENI_VCC(vcc)) return;
+	clear_bit(ATM_VF_READY,&vcc->flags);
+	close_rx(vcc);
+	close_tx(vcc);
+	DPRINTK("eni_close: done waiting\n");
+	/* deallocate memory */
+	kfree(ENI_VCC(vcc));
+	vcc->dev_data = NULL;
+	clear_bit(ATM_VF_ADDR,&vcc->flags);
+	/*foo();*/
+}
+
+
+static int eni_open(struct atm_vcc *vcc)
+{
+	struct eni_dev *eni_dev;
+	struct eni_vcc *eni_vcc;
+	int error;
+	short vpi = vcc->vpi;
+	int vci = vcc->vci;
+
+	DPRINTK(">eni_open\n");
+	EVENT("eni_open\n",0,0);
+	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
+		vcc->dev_data = NULL;
+	eni_dev = ENI_DEV(vcc->dev);
+	if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
+		set_bit(ATM_VF_ADDR,&vcc->flags);
+	if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)
+		return -EINVAL;
+	DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n",vcc->dev->number,vcc->vpi,
+	    vcc->vci);
+	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
+		eni_vcc = kmalloc(sizeof(struct eni_vcc),GFP_KERNEL);
+		if (!eni_vcc) return -ENOMEM;
+		vcc->dev_data = eni_vcc;
+		eni_vcc->tx = NULL; /* for eni_close after open_rx */
+		if ((error = open_rx_first(vcc))) {
+			eni_close(vcc);
+			return error;
+		}
+		if ((error = open_tx_first(vcc))) {
+			eni_close(vcc);
+			return error;
+		}
+	}
+	if (vci == ATM_VPI_UNSPEC || vpi == ATM_VCI_UNSPEC) return 0;
+	if ((error = open_rx_second(vcc))) {
+		eni_close(vcc);
+		return error;
+	}
+	if ((error = open_tx_second(vcc))) {
+		eni_close(vcc);
+		return error;
+	}
+	set_bit(ATM_VF_READY,&vcc->flags);
+	/* should power down SUNI while !ref_count @@@ */
+	return 0;
+}
+
+
+static int eni_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs)
+{
+	struct eni_dev *eni_dev = ENI_DEV(vcc->dev);
+	struct eni_tx *tx = ENI_VCC(vcc)->tx;
+	struct sk_buff *skb;
+	int error,rate,rsv,shp;
+
+	if (qos->txtp.traffic_class == ATM_NONE) return 0;
+	if (tx == eni_dev->ubr) return -EBADFD;
+	rate = atm_pcr_goal(&qos->txtp);
+	if (rate < 0) rate = -rate;
+	rsv = shp = 0;
+	if ((flgs & ATM_MF_DEC_RSV) && rate && rate < tx->reserved) rsv = 1;
+	if ((flgs & ATM_MF_INC_RSV) && (!rate || rate > tx->reserved)) rsv = 1;
+	if ((flgs & ATM_MF_DEC_SHP) && rate && rate < tx->shaping) shp = 1;
+	if ((flgs & ATM_MF_INC_SHP) && (!rate || rate > tx->shaping)) shp = 1;
+	if (!rsv && !shp) return 0;
+	error = reserve_or_set_tx(vcc,&qos->txtp,rsv,shp);
+	if (error) return error;
+	if (shp && !(flgs & ATM_MF_IMMED)) return 0;
+	/*
+	 * Walk through the send buffer and patch the rate information in all
+	 * segmentation buffer descriptors of this VCC.
+	 */
+	tasklet_disable(&eni_dev->task);
+	skb_queue_walk(&eni_dev->tx_queue, skb) {
+		void __iomem *dsc;
+
+		if (ATM_SKB(skb)->vcc != vcc) continue;
+		dsc = tx->send+ENI_PRV_POS(skb)*4;
+		writel((readl(dsc) & ~(MID_SEG_RATE | MID_SEG_PR)) |
+		    (tx->prescaler << MID_SEG_PR_SHIFT) |
+		    (tx->resolution << MID_SEG_RATE_SHIFT), dsc);
+	}
+	tasklet_enable(&eni_dev->task);
+	return 0;
+}
+
+
+static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
+{
+	struct eni_dev *eni_dev = ENI_DEV(dev);
+
+	if (cmd == ENI_MEMDUMP) {
+		if (!capable(CAP_NET_ADMIN)) return -EPERM;
+		printk(KERN_WARNING "Please use /proc/atm/" DEV_LABEL ":%d "
+		    "instead of obsolete ioctl ENI_MEMDUMP\n",dev->number);
+		dump(dev);
+		return 0;
+	}
+	if (cmd == ENI_SETMULT) {
+		struct eni_multipliers mult;
+
+		if (!capable(CAP_NET_ADMIN)) return -EPERM;
+		if (copy_from_user(&mult, arg,
+		    sizeof(struct eni_multipliers)))
+			return -EFAULT;
+		if ((mult.tx && mult.tx <= 100) || (mult.rx &&mult.rx <= 100) ||
+		    mult.tx > 65536 || mult.rx > 65536)
+			return -EINVAL;
+		if (mult.tx) eni_dev->tx_mult = mult.tx;
+		if (mult.rx) eni_dev->rx_mult = mult.rx;
+		return 0;
+	}
+	if (cmd == ATM_SETCIRANGE) {
+		struct atm_cirange ci;
+
+		if (copy_from_user(&ci, arg,sizeof(struct atm_cirange)))
+			return -EFAULT;
+		if ((ci.vpi_bits == 0 || ci.vpi_bits == ATM_CI_MAX) &&
+		    (ci.vci_bits == NR_VCI_LD || ci.vpi_bits == ATM_CI_MAX))
+		    return 0;
+		return -EINVAL;
+	}
+	if (!dev->phy->ioctl) return -ENOIOCTLCMD;
+	return dev->phy->ioctl(dev,cmd,arg);
+}
+
+
+static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
+    void __user *optval,int optlen)
+{
+	return -EINVAL;
+}
+
+
+static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
+    void __user *optval,int optlen)
+{
+	return -EINVAL;
+}
+
+
+static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb)
+{
+	enum enq_res res;
+
+	DPRINTK(">eni_send\n");
+	if (!ENI_VCC(vcc)->tx) {
+		if (vcc->pop) vcc->pop(vcc,skb);
+		else dev_kfree_skb(skb);
+		return -EINVAL;
+	}
+	if (!skb) {
+		printk(KERN_CRIT "!skb in eni_send ?\n");
+		if (vcc->pop) vcc->pop(vcc,skb);
+		return -EINVAL;
+	}
+	if (vcc->qos.aal == ATM_AAL0) {
+		if (skb->len != ATM_CELL_SIZE-1) {
+			if (vcc->pop) vcc->pop(vcc,skb);
+			else dev_kfree_skb(skb);
+			return -EINVAL;
+		}
+		*(u32 *) skb->data = htonl(*(u32 *) skb->data);
+	}
+submitted++;
+	ATM_SKB(skb)->vcc = vcc;
+	tasklet_disable(&ENI_DEV(vcc->dev)->task);
+	res = do_tx(skb);
+	tasklet_enable(&ENI_DEV(vcc->dev)->task);
+	if (res == enq_ok) return 0;
+	skb_queue_tail(&ENI_VCC(vcc)->tx->backlog,skb);
+backlogged++;
+	tasklet_schedule(&ENI_DEV(vcc->dev)->task);
+	return 0;
+}
+
+static void eni_phy_put(struct atm_dev *dev,unsigned char value,
+    unsigned long addr)
+{
+	writel(value,ENI_DEV(dev)->phy+addr*4);
+}
+
+
+
+static unsigned char eni_phy_get(struct atm_dev *dev,unsigned long addr)
+{
+	return readl(ENI_DEV(dev)->phy+addr*4);
+}
+
+
+static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
+{
+	struct hlist_node *node;
+	struct sock *s;
+	static const char *signal[] = { "LOST","unknown","okay" };
+	struct eni_dev *eni_dev = ENI_DEV(dev);
+	struct atm_vcc *vcc;
+	int left,i;
+
+	left = *pos;
+	if (!left)
+		return sprintf(page,DEV_LABEL "(itf %d) signal %s, %dkB, "
+		    "%d cps remaining\n",dev->number,signal[(int) dev->signal],
+		    eni_dev->mem >> 10,eni_dev->tx_bw);
+	if (!--left)
+		return sprintf(page,"%4sBursts: TX"
+#if !defined(CONFIG_ATM_ENI_BURST_TX_16W) && \
+    !defined(CONFIG_ATM_ENI_BURST_TX_8W) && \
+    !defined(CONFIG_ATM_ENI_BURST_TX_4W) && \
+    !defined(CONFIG_ATM_ENI_BURST_TX_2W)
+		    " none"
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_TX_16W
+		    " 16W"
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_TX_8W
+		    " 8W"
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_TX_4W
+		    " 4W"
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_TX_2W
+		    " 2W"
+#endif
+		    ", RX"
+#if !defined(CONFIG_ATM_ENI_BURST_RX_16W) && \
+    !defined(CONFIG_ATM_ENI_BURST_RX_8W) && \
+    !defined(CONFIG_ATM_ENI_BURST_RX_4W) && \
+    !defined(CONFIG_ATM_ENI_BURST_RX_2W)
+		    " none"
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_RX_16W
+		    " 16W"
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_RX_8W
+		    " 8W"
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_RX_4W
+		    " 4W"
+#endif
+#ifdef CONFIG_ATM_ENI_BURST_RX_2W
+		    " 2W"
+#endif
+#ifndef CONFIG_ATM_ENI_TUNE_BURST
+		    " (default)"
+#endif
+		    "\n","");
+	if (!--left) 
+		return sprintf(page,"%4sBuffer multipliers: tx %d%%, rx %d%%\n",
+		    "",eni_dev->tx_mult,eni_dev->rx_mult);
+	for (i = 0; i < NR_CHAN; i++) {
+		struct eni_tx *tx = eni_dev->tx+i;
+
+		if (!tx->send) continue;
+		if (!--left) {
+			return sprintf(page,"tx[%d]:    0x%ld-0x%ld "
+			    "(%6ld bytes), rsv %d cps, shp %d cps%s\n",i,
+			    (unsigned long) (tx->send - eni_dev->ram),
+			    tx->send-eni_dev->ram+tx->words*4-1,tx->words*4,
+			    tx->reserved,tx->shaping,
+			    tx == eni_dev->ubr ? " (UBR)" : "");
+		}
+		if (--left) continue;
+		return sprintf(page,"%10sbacklog %u packets\n","",
+		    skb_queue_len(&tx->backlog));
+	}
+	read_lock(&vcc_sklist_lock);
+	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
+		struct hlist_head *head = &vcc_hash[i];
+
+		sk_for_each(s, node, head) {
+			struct eni_vcc *eni_vcc;
+			int length;
+
+			vcc = atm_sk(s);
+			if (vcc->dev != dev)
+				continue;
+			eni_vcc = ENI_VCC(vcc);
+			if (--left) continue;
+			length = sprintf(page,"vcc %4d: ",vcc->vci);
+			if (eni_vcc->rx) {
+				length += sprintf(page+length,"0x%ld-0x%ld "
+				    "(%6ld bytes)",
+				    (unsigned long) (eni_vcc->recv - eni_dev->ram),
+				    eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1,
+				    eni_vcc->words*4);
+				if (eni_vcc->tx) length += sprintf(page+length,", ");
+			}
+			if (eni_vcc->tx)
+				length += sprintf(page+length,"tx[%d], txing %d bytes",
+				    eni_vcc->tx->index,eni_vcc->txing);
+			page[length] = '\n';
+			read_unlock(&vcc_sklist_lock);
+			return length+1;
+		}
+	}
+	read_unlock(&vcc_sklist_lock);
+	for (i = 0; i < eni_dev->free_len; i++) {
+		struct eni_free *fe = eni_dev->free_list+i;
+		unsigned long offset;
+
+		if (--left) continue;
+		offset = (unsigned long) eni_dev->ram+eni_dev->base_diff;
+		return sprintf(page,"free      %p-%p (%6d bytes)\n",
+		    fe->start-offset,fe->start-offset+(1 << fe->order)-1,
+		    1 << fe->order);
+	}
+	return 0;
+}
+
+
+static const struct atmdev_ops ops = {
+	.open		= eni_open,
+	.close		= eni_close,
+	.ioctl		= eni_ioctl,
+	.getsockopt	= eni_getsockopt,
+	.setsockopt	= eni_setsockopt,
+	.send		= eni_send,
+	.phy_put	= eni_phy_put,
+	.phy_get	= eni_phy_get,
+	.change_qos	= eni_change_qos,
+	.proc_read	= eni_proc_read
+};
+
+
+static int __devinit eni_init_one(struct pci_dev *pci_dev,
+    const struct pci_device_id *ent)
+{
+	struct atm_dev *dev;
+	struct eni_dev *eni_dev;
+	int error = -ENOMEM;
+
+	DPRINTK("eni_init_one\n");
+
+	if (pci_enable_device(pci_dev)) {
+		error = -EIO;
+		goto out0;
+	}
+
+	eni_dev = (struct eni_dev *) kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
+	if (!eni_dev) goto out0;
+	if (!cpu_zeroes) {
+		cpu_zeroes = pci_alloc_consistent(pci_dev,ENI_ZEROES_SIZE,
+		    &zeroes);
+		if (!cpu_zeroes) goto out1;
+	}
+	dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL);
+	if (!dev) goto out2;
+	pci_set_drvdata(pci_dev, dev);
+	eni_dev->pci_dev = pci_dev;
+	dev->dev_data = eni_dev;
+	eni_dev->asic = ent->driver_data;
+	error = eni_do_init(dev);
+	if (error) goto out3;
+	error = eni_start(dev);
+	if (error) goto out3;
+	eni_dev->more = eni_boards;
+	eni_boards = dev;
+	return 0;
+out3:
+	atm_dev_deregister(dev);
+out2:
+	pci_free_consistent(eni_dev->pci_dev,ENI_ZEROES_SIZE,cpu_zeroes,zeroes);
+	cpu_zeroes = NULL;
+out1:
+	kfree(eni_dev);
+out0:
+	return error;
+}
+
+
+static struct pci_device_id eni_pci_tbl[] = {
+	{ PCI_VENDOR_ID_EF, PCI_DEVICE_ID_EF_ATM_FPGA, PCI_ANY_ID, PCI_ANY_ID,
+	  0, 0, 0 /* FPGA */ },
+	{ PCI_VENDOR_ID_EF, PCI_DEVICE_ID_EF_ATM_ASIC, PCI_ANY_ID, PCI_ANY_ID,
+	  0, 0, 1 /* ASIC */ },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci,eni_pci_tbl);
+
+
+static void __devexit eni_remove_one(struct pci_dev *pci_dev)
+{
+	/* grrr */
+}
+
+
+static struct pci_driver eni_driver = {
+	.name		= DEV_LABEL,
+	.id_table	= eni_pci_tbl,
+	.probe		= eni_init_one,
+	.remove		= __devexit_p(eni_remove_one),
+};
+
+
+static int __init eni_init(void)
+{
+	struct sk_buff *skb; /* dummy for sizeof */
+
+	if (sizeof(skb->cb) < sizeof(struct eni_skb_prv)) {
+		printk(KERN_ERR "eni_detect: skb->cb is too small (%Zd < %Zd)\n",
+		    sizeof(skb->cb),sizeof(struct eni_skb_prv));
+		return -EIO;
+	}
+	return pci_register_driver(&eni_driver);
+}
+
+
+module_init(eni_init);
+/* @@@ since exit routine not defined, this module can not be unloaded */
+
+MODULE_LICENSE("GPL");
