/* drivers/atm/zatm.c - ZeitNet ZN122x device driver */
 
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */


#include <linux/config.h>
#include <linux/module.h>
#include <linux/sched.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/netdevice.h>
#include <linux/delay.h>
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/atm_zatm.h>
#include <linux/capability.h>
#include <linux/bitops.h>
#include <linux/wait.h>
#include <asm/byteorder.h>
#include <asm/system.h>
#include <asm/string.h>
#include <asm/io.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>

#include "uPD98401.h"
#include "uPD98402.h"
#include "zeprom.h"
#include "zatm.h"


/*
 * TODO:
 *
 * Minor features
 *  - support 64 kB SDUs (will have to use multibuffer batches then :-( )
 *  - proper use of CDV, credit = max(1,CDVT*PCR)
 *  - AAL0
 *  - better receive timestamps
 *  - OAM
 */

#define ZATM_COPPER	1

#if 0
#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
#else
#define DPRINTK(format,args...)
#endif

#ifndef CONFIG_ATM_ZATM_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%x\n", (int) (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;

	printk(KERN_NOTICE "----- event dump follows -----\n");
	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]);
	}
	printk(KERN_NOTICE "----- event dump ends here -----\n");
}


#endif /* CONFIG_ATM_ZATM_DEBUG */


#define RING_BUSY	1	/* indication from do_tx that PDU has to be
				   backlogged */

static struct atm_dev *zatm_boards = NULL;
static unsigned long dummy[2] = {0,0};


#define zin_n(r) inl(zatm_dev->base+r*4)
#define zin(r) inl(zatm_dev->base+uPD98401_##r*4)
#define zout(v,r) outl(v,zatm_dev->base+uPD98401_##r*4)
#define zwait while (zin(CMR) & uPD98401_BUSY)

/* RX0, RX1, TX0, TX1 */
static const int mbx_entries[NR_MBX] = { 1024,1024,1024,1024 };
static const int mbx_esize[NR_MBX] = { 16,16,4,4 }; /* entry size in bytes */

#define MBX_SIZE(i) (mbx_entries[i]*mbx_esize[i])


/*-------------------------------- utilities --------------------------------*/


static void zpokel(struct zatm_dev *zatm_dev,u32 value,u32 addr)
{
	zwait;
	zout(value,CER);
	zout(uPD98401_IND_ACC | uPD98401_IA_BALL |
	    (uPD98401_IA_TGT_CM << uPD98401_IA_TGT_SHIFT) | addr,CMR);
}


static u32 zpeekl(struct zatm_dev *zatm_dev,u32 addr)
{
	zwait;
	zout(uPD98401_IND_ACC | uPD98401_IA_BALL | uPD98401_IA_RW |
	  (uPD98401_IA_TGT_CM << uPD98401_IA_TGT_SHIFT) | addr,CMR);
	zwait;
	return zin(CER);
}


/*------------------------------- free lists --------------------------------*/


/*
 * Free buffer head structure:
 *   [0] pointer to buffer (for SAR)
 *   [1] buffer descr link pointer (for SAR)
 *   [2] back pointer to skb (for poll_rx)
 *   [3] data
 *   ...
 */

struct rx_buffer_head {
	u32		buffer;	/* pointer to buffer (for SAR) */
	u32		link;	/* buffer descriptor link pointer (for SAR) */
	struct sk_buff	*skb;	/* back pointer to skb (for poll_rx) */
};


static void refill_pool(struct atm_dev *dev,int pool)
{
	struct zatm_dev *zatm_dev;
	struct sk_buff *skb;
	struct rx_buffer_head *first;
	unsigned long flags;
	int align,offset,free,count,size;

	EVENT("refill_pool\n",0,0);
	zatm_dev = ZATM_DEV(dev);
	size = (64 << (pool <= ZATM_AAL5_POOL_BASE ? 0 :
	    pool-ZATM_AAL5_POOL_BASE))+sizeof(struct rx_buffer_head);
	if (size < PAGE_SIZE) {
		align = 32; /* for 32 byte alignment */
		offset = sizeof(struct rx_buffer_head);
	}
	else {
		align = 4096;
		offset = zatm_dev->pool_info[pool].offset+
		    sizeof(struct rx_buffer_head);
	}
	size += align;
	spin_lock_irqsave(&zatm_dev->lock, flags);
	free = zpeekl(zatm_dev,zatm_dev->pool_base+2*pool) &
	    uPD98401_RXFP_REMAIN;
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	if (free >= zatm_dev->pool_info[pool].low_water) return;
	EVENT("starting ... POOL: 0x%x, 0x%x\n",
	    zpeekl(zatm_dev,zatm_dev->pool_base+2*pool),
	    zpeekl(zatm_dev,zatm_dev->pool_base+2*pool+1));
	EVENT("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
	count = 0;
	first = NULL;
	while (free < zatm_dev->pool_info[pool].high_water) {
		struct rx_buffer_head *head;

		skb = alloc_skb(size,GFP_ATOMIC);
		if (!skb) {
			printk(KERN_WARNING DEV_LABEL "(Itf %d): got no new "
			    "skb (%d) with %d free\n",dev->number,size,free);
			break;
		}
		skb_reserve(skb,(unsigned char *) ((((unsigned long) skb->data+
		    align+offset-1) & ~(unsigned long) (align-1))-offset)-
		    skb->data);
		head = (struct rx_buffer_head *) skb->data;
		skb_reserve(skb,sizeof(struct rx_buffer_head));
		if (!first) first = head;
		count++;
		head->buffer = virt_to_bus(skb->data);
		head->link = 0;
		head->skb = skb;
		EVENT("enq skb 0x%08lx/0x%08lx\n",(unsigned long) skb,
		    (unsigned long) head);
		spin_lock_irqsave(&zatm_dev->lock, flags);
		if (zatm_dev->last_free[pool])
			((struct rx_buffer_head *) (zatm_dev->last_free[pool]->
			    data))[-1].link = virt_to_bus(head);
		zatm_dev->last_free[pool] = skb;
		skb_queue_tail(&zatm_dev->pool[pool],skb);
		spin_unlock_irqrestore(&zatm_dev->lock, flags);
		free++;
	}
	if (first) {
		spin_lock_irqsave(&zatm_dev->lock, flags);
		zwait;
		zout(virt_to_bus(first),CER);
		zout(uPD98401_ADD_BAT | (pool << uPD98401_POOL_SHIFT) | count,
		    CMR);
		spin_unlock_irqrestore(&zatm_dev->lock, flags);
		EVENT ("POOL: 0x%x, 0x%x\n",
		    zpeekl(zatm_dev,zatm_dev->pool_base+2*pool),
		    zpeekl(zatm_dev,zatm_dev->pool_base+2*pool+1));
		EVENT("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
	}
}


static void drain_free(struct atm_dev *dev,int pool)
{
	skb_queue_purge(&ZATM_DEV(dev)->pool[pool]);
}


static int pool_index(int max_pdu)
{
	int i;

	if (max_pdu % ATM_CELL_PAYLOAD)
		printk(KERN_ERR DEV_LABEL ": driver error in pool_index: "
		    "max_pdu is %d\n",max_pdu);
	if (max_pdu > 65536) return -1;
	for (i = 0; (64 << i) < max_pdu; i++);
	return i+ZATM_AAL5_POOL_BASE;
}


/* use_pool isn't reentrant */


static void use_pool(struct atm_dev *dev,int pool)
{
	struct zatm_dev *zatm_dev;
	unsigned long flags;
	int size;

	zatm_dev = ZATM_DEV(dev);
	if (!(zatm_dev->pool_info[pool].ref_count++)) {
		skb_queue_head_init(&zatm_dev->pool[pool]);
		size = pool-ZATM_AAL5_POOL_BASE;
		if (size < 0) size = 0; /* 64B... */
		else if (size > 10) size = 10; /* ... 64kB */
		spin_lock_irqsave(&zatm_dev->lock, flags);
		zpokel(zatm_dev,((zatm_dev->pool_info[pool].low_water/4) <<
		    uPD98401_RXFP_ALERT_SHIFT) |
		    (1 << uPD98401_RXFP_BTSZ_SHIFT) |
		    (size << uPD98401_RXFP_BFSZ_SHIFT),
		    zatm_dev->pool_base+pool*2);
		zpokel(zatm_dev,(unsigned long) dummy,zatm_dev->pool_base+
		    pool*2+1);
		spin_unlock_irqrestore(&zatm_dev->lock, flags);
		zatm_dev->last_free[pool] = NULL;
		refill_pool(dev,pool);
	}
	DPRINTK("pool %d: %d\n",pool,zatm_dev->pool_info[pool].ref_count);
}


static void unuse_pool(struct atm_dev *dev,int pool)
{
	if (!(--ZATM_DEV(dev)->pool_info[pool].ref_count))
		drain_free(dev,pool);
}

/*----------------------------------- RX ------------------------------------*/


#if 0
static void exception(struct atm_vcc *vcc)
{
   static int count = 0;
   struct zatm_dev *zatm_dev = ZATM_DEV(vcc->dev);
   struct zatm_vcc *zatm_vcc = ZATM_VCC(vcc);
   unsigned long *qrp;
   int i;

   if (count++ > 2) return;
   for (i = 0; i < 8; i++)
	printk("TX%d: 0x%08lx\n",i,
	  zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+i));
   for (i = 0; i < 5; i++)
	printk("SH%d: 0x%08lx\n",i,
	  zpeekl(zatm_dev,uPD98401_IM(zatm_vcc->shaper)+16*i));
   qrp = (unsigned long *) zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+
     uPD98401_TXVC_QRP);
   printk("qrp=0x%08lx\n",(unsigned long) qrp);
   for (i = 0; i < 4; i++) printk("QRP[%d]: 0x%08lx",i,qrp[i]);
}
#endif


static const char *err_txt[] = {
	"No error",
	"RX buf underflow",
	"RX FIFO overrun",
	"Maximum len violation",
	"CRC error",
	"User abort",
	"Length violation",
	"T1 error",
	"Deactivated",
	"???",
	"???",
	"???",
	"???",
	"???",
	"???",
	"???"
};


static void poll_rx(struct atm_dev *dev,int mbx)
{
	struct zatm_dev *zatm_dev;
	unsigned long pos;
	u32 x;
	int error;

	EVENT("poll_rx\n",0,0);
	zatm_dev = ZATM_DEV(dev);
	pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));
	while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {
		u32 *here;
		struct sk_buff *skb;
		struct atm_vcc *vcc;
		int cells,size,chan;

		EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);
		here = (u32 *) pos;
		if (((pos += 16) & 0xffff) == zatm_dev->mbx_end[mbx])
			pos = zatm_dev->mbx_start[mbx];
		cells = here[0] & uPD98401_AAL5_SIZE;
#if 0
printk("RX IND: 0x%x, 0x%x, 0x%x, 0x%x\n",here[0],here[1],here[2],here[3]);
{
unsigned long *x;
		printk("POOL: 0x%08x, 0x%08x\n",zpeekl(zatm_dev,
		      zatm_dev->pool_base),
		      zpeekl(zatm_dev,zatm_dev->pool_base+1));
		x = (unsigned long *) here[2];
		printk("[0..3] = 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx\n",
		    x[0],x[1],x[2],x[3]);
}
#endif
		error = 0;
		if (here[3] & uPD98401_AAL5_ERR) {
			error = (here[3] & uPD98401_AAL5_ES) >>
			    uPD98401_AAL5_ES_SHIFT;
			if (error == uPD98401_AAL5_ES_DEACT ||
			    error == uPD98401_AAL5_ES_FREE) continue;
		}
EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >>
  uPD98401_AAL5_ES_SHIFT,error);
		skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb;
		__net_timestamp(skb);
#if 0
printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3],
  ((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1],
  ((unsigned *) skb->data)[0]);
#endif
		EVENT("skb 0x%lx, here 0x%lx\n",(unsigned long) skb,
		    (unsigned long) here);
#if 0
printk("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
#endif
		size = error ? 0 : ntohs(((__be16 *) skb->data)[cells*
		    ATM_CELL_PAYLOAD/sizeof(u16)-3]);
		EVENT("got skb 0x%lx, size %d\n",(unsigned long) skb,size);
		chan = (here[3] & uPD98401_AAL5_CHAN) >>
		    uPD98401_AAL5_CHAN_SHIFT;
		if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {
			int pos = ZATM_VCC(vcc)->pool;

			vcc = zatm_dev->rx_map[chan];
			if (skb == zatm_dev->last_free[pos])
				zatm_dev->last_free[pos] = NULL;
			skb_unlink(skb, zatm_dev->pool + pos);
		}
		else {
			printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "
			    "for non-existing channel\n",dev->number);
			size = 0;
			vcc = NULL;
			event_dump();
		}
		if (error) {
			static unsigned long silence = 0;
			static int last_error = 0;

			if (error != last_error ||
			    time_after(jiffies, silence)  || silence == 0){
				printk(KERN_WARNING DEV_LABEL "(itf %d): "
				    "chan %d error %s\n",dev->number,chan,
				    err_txt[error]);
				last_error = error;
				silence = (jiffies+2*HZ)|1;
			}
			size = 0;
		}
		if (size && (size > cells*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER ||
		    size <= (cells-1)*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER)) {
			printk(KERN_ERR DEV_LABEL "(itf %d): size %d with %d "
			    "cells\n",dev->number,size,cells);
			size = 0;
			event_dump();
		}
		if (size > ATM_MAX_AAL5_PDU) {
			printk(KERN_ERR DEV_LABEL "(itf %d): size too big "
			    "(%d)\n",dev->number,size);
			size = 0;
			event_dump();
		}
		if (!size) {
			dev_kfree_skb_irq(skb);
			if (vcc) atomic_inc(&vcc->stats->rx_err);
			continue;
		}
		if (!atm_charge(vcc,skb->truesize)) {
			dev_kfree_skb_irq(skb);
			continue;
		}
		skb->len = size;
		ATM_SKB(skb)->vcc = vcc;
		vcc->push(vcc,skb);
		atomic_inc(&vcc->stats->rx);
	}
	zout(pos & 0xffff,MTA(mbx));
#if 0 /* probably a stupid idea */
	refill_pool(dev,zatm_vcc->pool);
		/* maybe this saves us a few interrupts */
#endif
}


static int open_rx_first(struct atm_vcc *vcc)
{
	struct zatm_dev *zatm_dev;
	struct zatm_vcc *zatm_vcc;
	unsigned long flags;
	unsigned short chan;
	int cells;

	DPRINTK("open_rx_first (0x%x)\n",inb_p(0xc053));
	zatm_dev = ZATM_DEV(vcc->dev);
	zatm_vcc = ZATM_VCC(vcc);
	zatm_vcc->rx_chan = 0;
	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;
	if (vcc->qos.aal == ATM_AAL5) {
		if (vcc->qos.rxtp.max_sdu > 65464)
			vcc->qos.rxtp.max_sdu = 65464;
			/* fix this - we may want to receive 64kB SDUs
			   later */
		cells = (vcc->qos.rxtp.max_sdu+ATM_AAL5_TRAILER+
		    ATM_CELL_PAYLOAD-1)/ATM_CELL_PAYLOAD;
		zatm_vcc->pool = pool_index(cells*ATM_CELL_PAYLOAD);
	}
	else {
		cells = 1;
		zatm_vcc->pool = ZATM_AAL0_POOL;
	}
	if (zatm_vcc->pool < 0) return -EMSGSIZE;
	spin_lock_irqsave(&zatm_dev->lock, flags);
	zwait;
	zout(uPD98401_OPEN_CHAN,CMR);
	zwait;
	DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));
	chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	DPRINTK("chan is %d\n",chan);
	if (!chan) return -EAGAIN;
	use_pool(vcc->dev,zatm_vcc->pool);
	DPRINTK("pool %d\n",zatm_vcc->pool);
	/* set up VC descriptor */
	spin_lock_irqsave(&zatm_dev->lock, flags);
	zpokel(zatm_dev,zatm_vcc->pool << uPD98401_RXVC_POOL_SHIFT,
	    chan*VC_SIZE/4);
	zpokel(zatm_dev,uPD98401_RXVC_OD | (vcc->qos.aal == ATM_AAL5 ?
	    uPD98401_RXVC_AR : 0) | cells,chan*VC_SIZE/4+1);
	zpokel(zatm_dev,0,chan*VC_SIZE/4+2);
	zatm_vcc->rx_chan = chan;
	zatm_dev->rx_map[chan] = vcc;
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	return 0;
}


static int open_rx_second(struct atm_vcc *vcc)
{
	struct zatm_dev *zatm_dev;
	struct zatm_vcc *zatm_vcc;
	unsigned long flags;
	int pos,shift;

	DPRINTK("open_rx_second (0x%x)\n",inb_p(0xc053));
	zatm_dev = ZATM_DEV(vcc->dev);
	zatm_vcc = ZATM_VCC(vcc);
	if (!zatm_vcc->rx_chan) return 0;
	spin_lock_irqsave(&zatm_dev->lock, flags);
	/* should also handle VPI @@@ */
	pos = vcc->vci >> 1;
	shift = (1-(vcc->vci & 1)) << 4;
	zpokel(zatm_dev,(zpeekl(zatm_dev,pos) & ~(0xffff << shift)) |
	    ((zatm_vcc->rx_chan | uPD98401_RXLT_ENBL) << shift),pos);
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	return 0;
}


static void close_rx(struct atm_vcc *vcc)
{
	struct zatm_dev *zatm_dev;
	struct zatm_vcc *zatm_vcc;
	unsigned long flags;
	int pos,shift;

	zatm_vcc = ZATM_VCC(vcc);
	zatm_dev = ZATM_DEV(vcc->dev);
	if (!zatm_vcc->rx_chan) return;
	DPRINTK("close_rx\n");
	/* disable receiver */
	if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) {
		spin_lock_irqsave(&zatm_dev->lock, flags);
		pos = vcc->vci >> 1;
		shift = (1-(vcc->vci & 1)) << 4;
		zpokel(zatm_dev,zpeekl(zatm_dev,pos) & ~(0xffff << shift),pos);
		zwait;
		zout(uPD98401_NOP,CMR);
		zwait;
		zout(uPD98401_NOP,CMR);
		spin_unlock_irqrestore(&zatm_dev->lock, flags);
	}
	spin_lock_irqsave(&zatm_dev->lock, flags);
	zwait;
	zout(uPD98401_DEACT_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<
	    uPD98401_CHAN_ADDR_SHIFT),CMR);
	zwait;
	udelay(10); /* why oh why ... ? */
	zout(uPD98401_CLOSE_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<
	    uPD98401_CHAN_ADDR_SHIFT),CMR);
	zwait;
	if (!(zin(CMR) & uPD98401_CHAN_ADDR))
		printk(KERN_CRIT DEV_LABEL "(itf %d): can't close RX channel "
		    "%d\n",vcc->dev->number,zatm_vcc->rx_chan);
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	zatm_dev->rx_map[zatm_vcc->rx_chan] = NULL;
	zatm_vcc->rx_chan = 0;
	unuse_pool(vcc->dev,zatm_vcc->pool);
}


static int start_rx(struct atm_dev *dev)
{
	struct zatm_dev *zatm_dev;
	int size,i;

DPRINTK("start_rx\n");
	zatm_dev = ZATM_DEV(dev);
	size = sizeof(struct atm_vcc *)*zatm_dev->chans;
	zatm_dev->rx_map = (struct atm_vcc **) kmalloc(size,GFP_KERNEL);
	if (!zatm_dev->rx_map) return -ENOMEM;
	memset(zatm_dev->rx_map,0,size);
	/* set VPI/VCI split (use all VCIs and give what's left to VPIs) */
	zpokel(zatm_dev,(1 << dev->ci_range.vci_bits)-1,uPD98401_VRR);
	/* prepare free buffer pools */
	for (i = 0; i <= ZATM_LAST_POOL; i++) {
		zatm_dev->pool_info[i].ref_count = 0;
		zatm_dev->pool_info[i].rqa_count = 0;
		zatm_dev->pool_info[i].rqu_count = 0;
		zatm_dev->pool_info[i].low_water = LOW_MARK;
		zatm_dev->pool_info[i].high_water = HIGH_MARK;
		zatm_dev->pool_info[i].offset = 0;
		zatm_dev->pool_info[i].next_off = 0;
		zatm_dev->pool_info[i].next_cnt = 0;
		zatm_dev->pool_info[i].next_thres = OFF_CNG_THRES;
	}
	return 0;
}


/*----------------------------------- TX ------------------------------------*/


static int do_tx(struct sk_buff *skb)
{
	struct atm_vcc *vcc;
	struct zatm_dev *zatm_dev;
	struct zatm_vcc *zatm_vcc;
	u32 *dsc;
	unsigned long flags;

	EVENT("do_tx\n",0,0);
	DPRINTK("sending skb %p\n",skb);
	vcc = ATM_SKB(skb)->vcc;
	zatm_dev = ZATM_DEV(vcc->dev);
	zatm_vcc = ZATM_VCC(vcc);
	EVENT("iovcnt=%d\n",skb_shinfo(skb)->nr_frags,0);
	spin_lock_irqsave(&zatm_dev->lock, flags);
	if (!skb_shinfo(skb)->nr_frags) {
		if (zatm_vcc->txing == RING_ENTRIES-1) {
			spin_unlock_irqrestore(&zatm_dev->lock, flags);
			return RING_BUSY;
		}
		zatm_vcc->txing++;
		dsc = zatm_vcc->ring+zatm_vcc->ring_curr;
		zatm_vcc->ring_curr = (zatm_vcc->ring_curr+RING_WORDS) &
		    (RING_ENTRIES*RING_WORDS-1);
		dsc[1] = 0;
		dsc[2] = skb->len;
		dsc[3] = virt_to_bus(skb->data);
		mb();
		dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP | uPD98401_TXPD_SM
		    | (vcc->qos.aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 |
		    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?
		    uPD98401_CLPM_1 : uPD98401_CLPM_0));
		EVENT("dsc (0x%lx)\n",(unsigned long) dsc,0);
	}
	else {
printk("NONONONOO!!!!\n");
		dsc = NULL;
#if 0
		u32 *put;
		int i;

		dsc = (u32 *) kmalloc(uPD98401_TXPD_SIZE*2+
		    uPD98401_TXBD_SIZE*ATM_SKB(skb)->iovcnt,GFP_ATOMIC);
		if (!dsc) {
			if (vcc->pop) vcc->pop(vcc,skb);
			else dev_kfree_skb_irq(skb);
			return -EAGAIN;
		}
		/* @@@ should check alignment */
		put = dsc+8;
		dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP |
		    (vcc->aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 |
		    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?
		    uPD98401_CLPM_1 : uPD98401_CLPM_0));
		dsc[1] = 0;
		dsc[2] = ATM_SKB(skb)->iovcnt*uPD98401_TXBD_SIZE;
		dsc[3] = virt_to_bus(put);
		for (i = 0; i < ATM_SKB(skb)->iovcnt; i++) {
			*put++ = ((struct iovec *) skb->data)[i].iov_len;
			*put++ = virt_to_bus(((struct iovec *)
			    skb->data)[i].iov_base);
		}
		put[-2] |= uPD98401_TXBD_LAST;
#endif
	}
	ZATM_PRV_DSC(skb) = dsc;
	skb_queue_tail(&zatm_vcc->tx_queue,skb);
	DPRINTK("QRP=0x%08lx\n",zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+
	  uPD98401_TXVC_QRP));
	zwait;
	zout(uPD98401_TX_READY | (zatm_vcc->tx_chan <<
	    uPD98401_CHAN_ADDR_SHIFT),CMR);
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	EVENT("done\n",0,0);
	return 0;
}


static inline void dequeue_tx(struct atm_vcc *vcc)
{
	struct zatm_vcc *zatm_vcc;
	struct sk_buff *skb;

	EVENT("dequeue_tx\n",0,0);
	zatm_vcc = ZATM_VCC(vcc);
	skb = skb_dequeue(&zatm_vcc->tx_queue);
	if (!skb) {
		printk(KERN_CRIT DEV_LABEL "(itf %d): dequeue_tx but not "
		    "txing\n",vcc->dev->number);
		return;
	}
#if 0 /* @@@ would fail on CLP */
if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD_V | uPD98401_TXPD_DP |
  uPD98401_TXPD_SM | uPD98401_TXPD_AAL5)) printk("@#*$!!!!  (%08x)\n",
  *ZATM_PRV_DSC(skb));
#endif
	*ZATM_PRV_DSC(skb) = 0; /* mark as invalid */
	zatm_vcc->txing--;
	if (vcc->pop) vcc->pop(vcc,skb);
	else dev_kfree_skb_irq(skb);
	while ((skb = skb_dequeue(&zatm_vcc->backlog)))
		if (do_tx(skb) == RING_BUSY) {
			skb_queue_head(&zatm_vcc->backlog,skb);
			break;
		}
	atomic_inc(&vcc->stats->tx);
	wake_up(&zatm_vcc->tx_wait);
}


static void poll_tx(struct atm_dev *dev,int mbx)
{
	struct zatm_dev *zatm_dev;
	unsigned long pos;
	u32 x;

	EVENT("poll_tx\n",0,0);
	zatm_dev = ZATM_DEV(dev);
	pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));
	while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {
		int chan;

#if 1
		u32 data,*addr;

		EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);
		addr = (u32 *) pos;
		data = *addr;
		chan = (data & uPD98401_TXI_CONN) >> uPD98401_TXI_CONN_SHIFT;
		EVENT("addr = 0x%lx, data = 0x%08x,",(unsigned long) addr,
		    data);
		EVENT("chan = %d\n",chan,0);
#else
NO !
		chan = (zatm_dev->mbx_start[mbx][pos >> 2] & uPD98401_TXI_CONN)
		>> uPD98401_TXI_CONN_SHIFT;
#endif
		if (chan < zatm_dev->chans && zatm_dev->tx_map[chan])
			dequeue_tx(zatm_dev->tx_map[chan]);
		else {
			printk(KERN_CRIT DEV_LABEL "(itf %d): TX indication "
			    "for non-existing channel %d\n",dev->number,chan);
			event_dump();
		}
		if (((pos += 4) & 0xffff) == zatm_dev->mbx_end[mbx])
			pos = zatm_dev->mbx_start[mbx];
	}
	zout(pos & 0xffff,MTA(mbx));
}


/*
 * BUG BUG BUG: Doesn't handle "new-style" rate specification yet.
 */

static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
{
	struct zatm_dev *zatm_dev;
	unsigned long flags;
	unsigned long i,m,c;
	int shaper;

	DPRINTK("alloc_shaper (min = %d, max = %d)\n",min,max);
	zatm_dev = ZATM_DEV(dev);
	if (!zatm_dev->free_shapers) return -EAGAIN;
	for (shaper = 0; !((zatm_dev->free_shapers >> shaper) & 1); shaper++);
	zatm_dev->free_shapers &= ~1 << shaper;
	if (ubr) {
		c = 5;
		i = m = 1;
		zatm_dev->ubr_ref_cnt++;
		zatm_dev->ubr = shaper;
	}
	else {
		if (min) {
			if (min <= 255) {
				i = min;
				m = ATM_OC3_PCR;
			}
			else {
				i = 255;
				m = ATM_OC3_PCR*255/min;
			}
		}
		else {
			if (max > zatm_dev->tx_bw) max = zatm_dev->tx_bw;
			if (max <= 255) {
				i = max;
				m = ATM_OC3_PCR;
			}
			else {
				i = 255;
				m = (ATM_OC3_PCR*255+max-1)/max;
			}
		}
		if (i > m) {
			printk(KERN_CRIT DEV_LABEL "shaper algorithm botched "
			    "[%d,%d] -> i=%ld,m=%ld\n",min,max,i,m);
			m = i;
		}
		*pcr = i*ATM_OC3_PCR/m;
		c = 20; /* @@@ should use max_cdv ! */
		if ((min && *pcr < min) || (max && *pcr > max)) return -EINVAL;
		if (zatm_dev->tx_bw < *pcr) return -EAGAIN;
		zatm_dev->tx_bw -= *pcr;
	}
	spin_lock_irqsave(&zatm_dev->lock, flags);
	DPRINTK("i = %d, m = %d, PCR = %d\n",i,m,*pcr);
	zpokel(zatm_dev,(i << uPD98401_IM_I_SHIFT) | m,uPD98401_IM(shaper));
	zpokel(zatm_dev,c << uPD98401_PC_C_SHIFT,uPD98401_PC(shaper));
	zpokel(zatm_dev,0,uPD98401_X(shaper));
	zpokel(zatm_dev,0,uPD98401_Y(shaper));
	zpokel(zatm_dev,uPD98401_PS_E,uPD98401_PS(shaper));
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	return shaper;
}


static void dealloc_shaper(struct atm_dev *dev,int shaper)
{
	struct zatm_dev *zatm_dev;
	unsigned long flags;

	zatm_dev = ZATM_DEV(dev);
	if (shaper == zatm_dev->ubr) {
		if (--zatm_dev->ubr_ref_cnt) return;
		zatm_dev->ubr = -1;
	}
	spin_lock_irqsave(&zatm_dev->lock, flags);
	zpokel(zatm_dev,zpeekl(zatm_dev,uPD98401_PS(shaper)) & ~uPD98401_PS_E,
	    uPD98401_PS(shaper));
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	zatm_dev->free_shapers |= 1 << shaper;
}


static void close_tx(struct atm_vcc *vcc)
{
	struct zatm_dev *zatm_dev;
	struct zatm_vcc *zatm_vcc;
	unsigned long flags;
	int chan;

	zatm_vcc = ZATM_VCC(vcc);
	zatm_dev = ZATM_DEV(vcc->dev);
	chan = zatm_vcc->tx_chan;
	if (!chan) return;
	DPRINTK("close_tx\n");
	if (skb_peek(&zatm_vcc->backlog)) {
		printk("waiting for backlog to drain ...\n");
		event_dump();
		wait_event(zatm_vcc->tx_wait, !skb_peek(&zatm_vcc->backlog));
	}
	if (skb_peek(&zatm_vcc->tx_queue)) {
		printk("waiting for TX queue to drain ...\n");
		event_dump();
		wait_event(zatm_vcc->tx_wait, !skb_peek(&zatm_vcc->tx_queue));
	}
	spin_lock_irqsave(&zatm_dev->lock, flags);
#if 0
	zwait;
	zout(uPD98401_DEACT_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);
#endif
	zwait;
	zout(uPD98401_CLOSE_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);
	zwait;
	if (!(zin(CMR) & uPD98401_CHAN_ADDR))
		printk(KERN_CRIT DEV_LABEL "(itf %d): can't close TX channel "
		    "%d\n",vcc->dev->number,chan);
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	zatm_vcc->tx_chan = 0;
	zatm_dev->tx_map[chan] = NULL;
	if (zatm_vcc->shaper != zatm_dev->ubr) {
		zatm_dev->tx_bw += vcc->qos.txtp.min_pcr;
		dealloc_shaper(vcc->dev,zatm_vcc->shaper);
	}
	kfree(zatm_vcc->ring);
}


static int open_tx_first(struct atm_vcc *vcc)
{
	struct zatm_dev *zatm_dev;
	struct zatm_vcc *zatm_vcc;
	unsigned long flags;
	u32 *loop;
	unsigned short chan;
	int pcr,unlimited;

	DPRINTK("open_tx_first\n");
	zatm_dev = ZATM_DEV(vcc->dev);
	zatm_vcc = ZATM_VCC(vcc);
	zatm_vcc->tx_chan = 0;
	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;
	spin_lock_irqsave(&zatm_dev->lock, flags);
	zwait;
	zout(uPD98401_OPEN_CHAN,CMR);
	zwait;
	DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));
	chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	DPRINTK("chan is %d\n",chan);
	if (!chan) return -EAGAIN;
	unlimited = vcc->qos.txtp.traffic_class == ATM_UBR &&
	    (!vcc->qos.txtp.max_pcr || vcc->qos.txtp.max_pcr == ATM_MAX_PCR ||
	    vcc->qos.txtp.max_pcr >= ATM_OC3_PCR);
	if (unlimited && zatm_dev->ubr != -1) zatm_vcc->shaper = zatm_dev->ubr;
	else {
		if (unlimited) vcc->qos.txtp.max_sdu = ATM_MAX_AAL5_PDU;
		if ((zatm_vcc->shaper = alloc_shaper(vcc->dev,&pcr,
		    vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,unlimited))
		    < 0) {
			close_tx(vcc);
			return zatm_vcc->shaper;
		}
		if (pcr > ATM_OC3_PCR) pcr = ATM_OC3_PCR;
		vcc->qos.txtp.min_pcr = vcc->qos.txtp.max_pcr = pcr;
	}
	zatm_vcc->tx_chan = chan;
	skb_queue_head_init(&zatm_vcc->tx_queue);
	init_waitqueue_head(&zatm_vcc->tx_wait);
	/* initialize ring */
	zatm_vcc->ring = kmalloc(RING_SIZE,GFP_KERNEL);
	if (!zatm_vcc->ring) return -ENOMEM;
	memset(zatm_vcc->ring,0,RING_SIZE);
	loop = zatm_vcc->ring+RING_ENTRIES*RING_WORDS;
	loop[0] = uPD98401_TXPD_V;
	loop[1] = loop[2] = 0;
	loop[3] = virt_to_bus(zatm_vcc->ring);
	zatm_vcc->ring_curr = 0;
	zatm_vcc->txing = 0;
	skb_queue_head_init(&zatm_vcc->backlog);
	zpokel(zatm_dev,virt_to_bus(zatm_vcc->ring),
	    chan*VC_SIZE/4+uPD98401_TXVC_QRP);
	return 0;
}


static int open_tx_second(struct atm_vcc *vcc)
{
	struct zatm_dev *zatm_dev;
	struct zatm_vcc *zatm_vcc;
	unsigned long flags;

	DPRINTK("open_tx_second\n");
	zatm_dev = ZATM_DEV(vcc->dev);
	zatm_vcc = ZATM_VCC(vcc);
	if (!zatm_vcc->tx_chan) return 0;
	/* set up VC descriptor */
	spin_lock_irqsave(&zatm_dev->lock, flags);
	zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4);
	zpokel(zatm_dev,uPD98401_TXVC_L | (zatm_vcc->shaper <<
	    uPD98401_TXVC_SHP_SHIFT) | (vcc->vpi << uPD98401_TXVC_VPI_SHIFT) |
	    vcc->vci,zatm_vcc->tx_chan*VC_SIZE/4+1);
	zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4+2);
	spin_unlock_irqrestore(&zatm_dev->lock, flags);
	zatm_dev->tx_map[zatm_vcc->tx_chan] = vcc;
	return 0;
}


static int start_tx(struct atm_dev *dev)
{
	struct zatm_dev *zatm_dev;
	int i;

	DPRINTK("start_tx\n");
	zatm_dev = ZATM_DEV(dev);
	zatm_dev->tx_map = (struct atm_vcc **) kmalloc(sizeof(struct atm_vcc *)*
	    zatm_dev->chans,GFP_KERNEL);
	if (!zatm_dev->tx_map) return -ENOMEM;
	zatm_dev->tx_bw = ATM_OC3_PCR;
	zatm_dev->free_shapers = (1 << NR_SHAPERS)-1;
	zatm_dev->ubr = -1;
	zatm_dev->ubr_ref_cnt = 0;
	/* initialize shapers */
	for (i = 0; i < NR_SHAPERS; i++) zpokel(zatm_dev,0,uPD98401_PS(i));
	return 0;
}


/*------------------------------- interrupts --------------------------------*/


static irqreturn_t zatm_int(int irq,void *dev_id,struct pt_regs *regs)
{
	struct atm_dev *dev;
	struct zatm_dev *zatm_dev;
	u32 reason;
	int handled = 0;

	dev = dev_id;
	zatm_dev = ZATM_DEV(dev);
	while ((reason = zin(GSR))) {
		handled = 1;
		EVENT("reason 0x%x\n",reason,0);
		if (reason & uPD98401_INT_PI) {
			EVENT("PHY int\n",0,0);
			dev->phy->interrupt(dev);
		}
		if (reason & uPD98401_INT_RQA) {
			unsigned long pools;
			int i;

			pools = zin(RQA);
			EVENT("RQA (0x%08x)\n",pools,0);
			for (i = 0; pools; i++) {
				if (pools & 1) {
					refill_pool(dev,i);
					zatm_dev->pool_info[i].rqa_count++;
				}
				pools >>= 1;
			}
		}
		if (reason & uPD98401_INT_RQU) {
			unsigned long pools;
			int i;
			pools = zin(RQU);
			printk(KERN_WARNING DEV_LABEL "(itf %d): RQU 0x%08lx\n",
			    dev->number,pools);
			event_dump();
			for (i = 0; pools; i++) {
				if (pools & 1) {
					refill_pool(dev,i);
					zatm_dev->pool_info[i].rqu_count++;
				}
				pools >>= 1;
			}
		}
		/* don't handle RD */
		if (reason & uPD98401_INT_SPE)
			printk(KERN_ALERT DEV_LABEL "(itf %d): system parity "
			    "error at 0x%08x\n",dev->number,zin(ADDR));
		if (reason & uPD98401_INT_CPE)
			printk(KERN_ALERT DEV_LABEL "(itf %d): control memory "
			    "parity error at 0x%08x\n",dev->number,zin(ADDR));
		if (reason & uPD98401_INT_SBE) {
			printk(KERN_ALERT DEV_LABEL "(itf %d): system bus "
			    "error at 0x%08x\n",dev->number,zin(ADDR));
			event_dump();
		}
		/* don't handle IND */
		if (reason & uPD98401_INT_MF) {
			printk(KERN_CRIT DEV_LABEL "(itf %d): mailbox full "
			    "(0x%x)\n",dev->number,(reason & uPD98401_INT_MF)
			    >> uPD98401_INT_MF_SHIFT);
			event_dump();
			    /* @@@ should try to recover */
		}
		if (reason & uPD98401_INT_MM) {
			if (reason & 1) poll_rx(dev,0);
			if (reason & 2) poll_rx(dev,1);
			if (reason & 4) poll_tx(dev,2);
			if (reason & 8) poll_tx(dev,3);
		}
		/* @@@ handle RCRn */
	}
	return IRQ_RETVAL(handled);
}


/*----------------------------- (E)EPROM access -----------------------------*/


static void __devinit eprom_set(struct zatm_dev *zatm_dev,unsigned long value,
    unsigned short cmd)
{
	int error;

	if ((error = pci_write_config_dword(zatm_dev->pci_dev,cmd,value)))
		printk(KERN_ERR DEV_LABEL ": PCI write failed (0x%02x)\n",
		    error);
}


static unsigned long __devinit eprom_get(struct zatm_dev *zatm_dev,
    unsigned short cmd)
{
	unsigned int value;
	int error;

	if ((error = pci_read_config_dword(zatm_dev->pci_dev,cmd,&value)))
		printk(KERN_ERR DEV_LABEL ": PCI read failed (0x%02x)\n",
		    error);
	return value;
}


static void __devinit eprom_put_bits(struct zatm_dev *zatm_dev,
    unsigned long data,int bits,unsigned short cmd)
{
	unsigned long value;
	int i;

	for (i = bits-1; i >= 0; i--) {
		value = ZEPROM_CS | (((data >> i) & 1) ? ZEPROM_DI : 0);
		eprom_set(zatm_dev,value,cmd);
		eprom_set(zatm_dev,value | ZEPROM_SK,cmd);
		eprom_set(zatm_dev,value,cmd);
	}
}


static void __devinit eprom_get_byte(struct zatm_dev *zatm_dev,
    unsigned char *byte,unsigned short cmd)
{
	int i;

	*byte = 0;
	for (i = 8; i; i--) {
		eprom_set(zatm_dev,ZEPROM_CS,cmd);
		eprom_set(zatm_dev,ZEPROM_CS | ZEPROM_SK,cmd);
		*byte <<= 1;
		if (eprom_get(zatm_dev,cmd) & ZEPROM_DO) *byte |= 1;
		eprom_set(zatm_dev,ZEPROM_CS,cmd);
	}
}


static unsigned char __devinit eprom_try_esi(struct atm_dev *dev,
    unsigned short cmd,int offset,int swap)
{
	unsigned char buf[ZEPROM_SIZE];
	struct zatm_dev *zatm_dev;
	int i;

	zatm_dev = ZATM_DEV(dev);
	for (i = 0; i < ZEPROM_SIZE; i += 2) {
		eprom_set(zatm_dev,ZEPROM_CS,cmd); /* select EPROM */
		eprom_put_bits(zatm_dev,ZEPROM_CMD_READ,ZEPROM_CMD_LEN,cmd);
		eprom_put_bits(zatm_dev,i >> 1,ZEPROM_ADDR_LEN,cmd);
		eprom_get_byte(zatm_dev,buf+i+swap,cmd);
		eprom_get_byte(zatm_dev,buf+i+1-swap,cmd);
		eprom_set(zatm_dev,0,cmd); /* deselect EPROM */
	}
	memcpy(dev->esi,buf+offset,ESI_LEN);
	return memcmp(dev->esi,"\0\0\0\0\0",ESI_LEN); /* assumes ESI_LEN == 6 */
}


static void __devinit eprom_get_esi(struct atm_dev *dev)
{
	if (eprom_try_esi(dev,ZEPROM_V1_REG,ZEPROM_V1_ESI_OFF,1)) return;
	(void) eprom_try_esi(dev,ZEPROM_V2_REG,ZEPROM_V2_ESI_OFF,0);
}


/*--------------------------------- entries ---------------------------------*/


static int __init zatm_init(struct atm_dev *dev)
{
	struct zatm_dev *zatm_dev;
	struct pci_dev *pci_dev;
	unsigned short command;
	unsigned char revision;
	int error,i,last;
	unsigned long t0,t1,t2;

	DPRINTK(">zatm_init\n");
	zatm_dev = ZATM_DEV(dev);
	spin_lock_init(&zatm_dev->lock);
	pci_dev = zatm_dev->pci_dev;
	zatm_dev->base = pci_resource_start(pci_dev, 0);
	zatm_dev->irq = pci_dev->irq;
	if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command)) ||
	    (error = pci_read_config_byte(pci_dev,PCI_REVISION_ID,&revision))) {
		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,
	    command | PCI_COMMAND_IO | PCI_COMMAND_MASTER))) {
		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable IO (0x%02x)"
		    "\n",dev->number,error);
		return -EIO;
	}
	eprom_get_esi(dev);
	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%x,irq=%d,",
	    dev->number,revision,zatm_dev->base,zatm_dev->irq);
	/* reset uPD98401 */
	zout(0,SWR);
	while (!(zin(GSR) & uPD98401_INT_IND));
	zout(uPD98401_GMR_ONE /*uPD98401_BURST4*/,GMR);
	last = MAX_CRAM_SIZE;
	for (i = last-RAM_INCREMENT; i >= 0; i -= RAM_INCREMENT) {
		zpokel(zatm_dev,0x55555555,i);
		if (zpeekl(zatm_dev,i) != 0x55555555) last = i;
		else {
			zpokel(zatm_dev,0xAAAAAAAA,i);
			if (zpeekl(zatm_dev,i) != 0xAAAAAAAA) last = i;
			else zpokel(zatm_dev,i,i);
		}
	}
	for (i = 0; i < last; i += RAM_INCREMENT)
		if (zpeekl(zatm_dev,i) != i) break;
	zatm_dev->mem = i << 2;
	while (i) zpokel(zatm_dev,0,--i);
	/* reset again to rebuild memory pointers */
	zout(0,SWR);
	while (!(zin(GSR) & uPD98401_INT_IND));
	zout(uPD98401_GMR_ONE | uPD98401_BURST8 | uPD98401_BURST4 |
	    uPD98401_BURST2 | uPD98401_GMR_PM | uPD98401_GMR_DR,GMR);
	/* TODO: should shrink allocation now */
	printk("mem=%dkB,%s (",zatm_dev->mem >> 10,zatm_dev->copper ? "UTP" :
	    "MMF");
	for (i = 0; i < ESI_LEN; i++)
		printk("%02X%s",dev->esi[i],i == ESI_LEN-1 ? ")\n" : "-");
	do {
		unsigned long flags;

		spin_lock_irqsave(&zatm_dev->lock, flags);
		t0 = zpeekl(zatm_dev,uPD98401_TSR);
		udelay(10);
		t1 = zpeekl(zatm_dev,uPD98401_TSR);
		udelay(1010);
		t2 = zpeekl(zatm_dev,uPD98401_TSR);
		spin_unlock_irqrestore(&zatm_dev->lock, flags);
	}
	while (t0 > t1 || t1 > t2); /* loop if wrapping ... */
	zatm_dev->khz = t2-2*t1+t0;
	printk(KERN_NOTICE DEV_LABEL "(itf %d): uPD98401 %d.%d at %d.%03d "
	    "MHz\n",dev->number,
	    (zin(VER) & uPD98401_MAJOR) >> uPD98401_MAJOR_SHIFT,
            zin(VER) & uPD98401_MINOR,zatm_dev->khz/1000,zatm_dev->khz % 1000);
	return uPD98402_init(dev);
}


static int __init zatm_start(struct atm_dev *dev)
{
	struct zatm_dev *zatm_dev = ZATM_DEV(dev);
	struct pci_dev *pdev = zatm_dev->pci_dev;
	unsigned long curr;
	int pools,vccs,rx;
	int error, i, ld;

	DPRINTK("zatm_start\n");
	zatm_dev->rx_map = zatm_dev->tx_map = NULL;
 	for (i = 0; i < NR_MBX; i++)
 		zatm_dev->mbx_start[i] = 0;
 	error = request_irq(zatm_dev->irq, zatm_int, SA_SHIRQ, DEV_LABEL, dev);
	if (error < 0) {
 		printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
 		    dev->number,zatm_dev->irq);
		goto done;
	}
	/* define memory regions */
	pools = NR_POOLS;
	if (NR_SHAPERS*SHAPER_SIZE > pools*POOL_SIZE)
		pools = NR_SHAPERS*SHAPER_SIZE/POOL_SIZE;
	vccs = (zatm_dev->mem-NR_SHAPERS*SHAPER_SIZE-pools*POOL_SIZE)/
	    (2*VC_SIZE+RX_SIZE);
	ld = -1;
	for (rx = 1; rx < vccs; rx <<= 1) ld++;
	dev->ci_range.vpi_bits = 0; /* @@@ no VPI for now */
	dev->ci_range.vci_bits = ld;
	dev->link_rate = ATM_OC3_PCR;
	zatm_dev->chans = vccs; /* ??? */
	curr = rx*RX_SIZE/4;
	DPRINTK("RX pool 0x%08lx\n",curr);
	zpokel(zatm_dev,curr,uPD98401_PMA); /* receive pool */
	zatm_dev->pool_base = curr;
	curr += pools*POOL_SIZE/4;
	DPRINTK("Shapers 0x%08lx\n",curr);
	zpokel(zatm_dev,curr,uPD98401_SMA); /* shapers */
	curr += NR_SHAPERS*SHAPER_SIZE/4;
	DPRINTK("Free    0x%08lx\n",curr);
	zpokel(zatm_dev,curr,uPD98401_TOS); /* free pool */
	printk(KERN_INFO DEV_LABEL "(itf %d): %d shapers, %d pools, %d RX, "
	    "%ld VCs\n",dev->number,NR_SHAPERS,pools,rx,
	    (zatm_dev->mem-curr*4)/VC_SIZE);
	/* create mailboxes */
	for (i = 0; i < NR_MBX; i++) {
		void *mbx;
		dma_addr_t mbx_dma;

		if (!mbx_entries[i])
			continue;
		mbx = pci_alloc_consistent(pdev, 2*MBX_SIZE(i), &mbx_dma);
		if (!mbx) {
			error = -ENOMEM;
			goto out;
		}
		/*
		 * Alignment provided by pci_alloc_consistent() isn't enough
		 * for this device.
		 */
		if (((unsigned long)mbx ^ mbx_dma) & 0xffff) {
			printk(KERN_ERR DEV_LABEL "(itf %d): system "
			       "bus incompatible with driver\n", dev->number);
			pci_free_consistent(pdev, 2*MBX_SIZE(i), mbx, mbx_dma);
			error = -ENODEV;
			goto out;
		}
		DPRINTK("mbx@0x%08lx-0x%08lx\n", mbx, mbx + MBX_SIZE(i));
		zatm_dev->mbx_start[i] = (unsigned long)mbx;
		zatm_dev->mbx_dma[i] = mbx_dma;
		zatm_dev->mbx_end[i] = (zatm_dev->mbx_start[i] + MBX_SIZE(i)) &
					0xffff;
		zout(mbx_dma >> 16, MSH(i));
		zout(mbx_dma, MSL(i));
		zout(zatm_dev->mbx_end[i], MBA(i));
		zout((unsigned long)mbx & 0xffff, MTA(i));
		zout((unsigned long)mbx & 0xffff, MWA(i));
	}
	error = start_tx(dev);
	if (error)
		goto out;
	error = start_rx(dev);
	if (error)
		goto out_tx;
	error = dev->phy->start(dev);
	if (error)
		goto out_rx;
	zout(0xffffffff,IMR); /* enable interrupts */
	/* enable TX & RX */
	zout(zin(GMR) | uPD98401_GMR_SE | uPD98401_GMR_RE,GMR);
done:
	return error;

out_rx:
	kfree(zatm_dev->rx_map);
out_tx:
	kfree(zatm_dev->tx_map);
out:
	while (i-- > 0) {
		pci_free_consistent(pdev, 2*MBX_SIZE(i), 
				    (void *)zatm_dev->mbx_start[i],
				    zatm_dev->mbx_dma[i]);
	}
	free_irq(zatm_dev->irq, dev);
	goto done;
}


static void zatm_close(struct atm_vcc *vcc)
{
        DPRINTK(">zatm_close\n");
        if (!ZATM_VCC(vcc)) return;
	clear_bit(ATM_VF_READY,&vcc->flags);
        close_rx(vcc);
	EVENT("close_tx\n",0,0);
        close_tx(vcc);
        DPRINTK("zatm_close: done waiting\n");
        /* deallocate memory */
        kfree(ZATM_VCC(vcc));
	vcc->dev_data = NULL;
	clear_bit(ATM_VF_ADDR,&vcc->flags);
}


static int zatm_open(struct atm_vcc *vcc)
{
	struct zatm_dev *zatm_dev;
	struct zatm_vcc *zatm_vcc;
	short vpi = vcc->vpi;
	int vci = vcc->vci;
	int error;

	DPRINTK(">zatm_open\n");
	zatm_dev = ZATM_DEV(vcc->dev);
	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
		vcc->dev_data = NULL;
	if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
		set_bit(ATM_VF_ADDR,&vcc->flags);
	if (vcc->qos.aal != ATM_AAL5) return -EINVAL; /* @@@ AAL0 */
	DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n",vcc->dev->number,vcc->vpi,
	    vcc->vci);
	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
		zatm_vcc = kmalloc(sizeof(struct zatm_vcc),GFP_KERNEL);
		if (!zatm_vcc) {
			clear_bit(ATM_VF_ADDR,&vcc->flags);
			return -ENOMEM;
		}
		vcc->dev_data = zatm_vcc;
		ZATM_VCC(vcc)->tx_chan = 0; /* for zatm_close after open_rx */
		if ((error = open_rx_first(vcc))) {
	                zatm_close(vcc);
	                return error;
	        }
		if ((error = open_tx_first(vcc))) {
			zatm_close(vcc);
			return error;
	        }
	}
	if (vci == ATM_VPI_UNSPEC || vpi == ATM_VCI_UNSPEC) return 0;
	if ((error = open_rx_second(vcc))) {
		zatm_close(vcc);
		return error;
        }
	if ((error = open_tx_second(vcc))) {
		zatm_close(vcc);
		return error;
        }
	set_bit(ATM_VF_READY,&vcc->flags);
        return 0;
}


static int zatm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flags)
{
	printk("Not yet implemented\n");
	return -ENOSYS;
	/* @@@ */
}


static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
	struct zatm_dev *zatm_dev;
	unsigned long flags;

	zatm_dev = ZATM_DEV(dev);
	switch (cmd) {
		case ZATM_GETPOOLZ:
			if (!capable(CAP_NET_ADMIN)) return -EPERM;
			/* fall through */
		case ZATM_GETPOOL:
			{
				struct zatm_pool_info info;
				int pool;

				if (get_user(pool,
				    &((struct zatm_pool_req __user *) arg)->pool_num))
					return -EFAULT;
				if (pool < 0 || pool > ZATM_LAST_POOL)
					return -EINVAL;
				spin_lock_irqsave(&zatm_dev->lock, flags);
				info = zatm_dev->pool_info[pool];
				if (cmd == ZATM_GETPOOLZ) {
					zatm_dev->pool_info[pool].rqa_count = 0;
					zatm_dev->pool_info[pool].rqu_count = 0;
				}
				spin_unlock_irqrestore(&zatm_dev->lock, flags);
				return copy_to_user(
				    &((struct zatm_pool_req __user *) arg)->info,
				    &info,sizeof(info)) ? -EFAULT : 0;
			}
		case ZATM_SETPOOL:
			{
				struct zatm_pool_info info;
				int pool;

				if (!capable(CAP_NET_ADMIN)) return -EPERM;
				if (get_user(pool,
				    &((struct zatm_pool_req __user *) arg)->pool_num))
					return -EFAULT;
				if (pool < 0 || pool > ZATM_LAST_POOL)
					return -EINVAL;
				if (copy_from_user(&info,
				    &((struct zatm_pool_req __user *) arg)->info,
				    sizeof(info))) return -EFAULT;
				if (!info.low_water)
					info.low_water = zatm_dev->
					    pool_info[pool].low_water;
				if (!info.high_water)
					info.high_water = zatm_dev->
					    pool_info[pool].high_water;
				if (!info.next_thres)
					info.next_thres = zatm_dev->
					    pool_info[pool].next_thres;
				if (info.low_water >= info.high_water ||
				    info.low_water < 0)
					return -EINVAL;
				spin_lock_irqsave(&zatm_dev->lock, flags);
				zatm_dev->pool_info[pool].low_water =
				    info.low_water;
				zatm_dev->pool_info[pool].high_water =
				    info.high_water;
				zatm_dev->pool_info[pool].next_thres =
				    info.next_thres;
				spin_unlock_irqrestore(&zatm_dev->lock, flags);
				return 0;
			}
		default:
        		if (!dev->phy->ioctl) return -ENOIOCTLCMD;
		        return dev->phy->ioctl(dev,cmd,arg);
	}
}


static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
    void __user *optval,int optlen)
{
	return -EINVAL;
}


static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
    void __user *optval,int optlen)
{
	return -EINVAL;
}

static int zatm_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
	int error;

	EVENT(">zatm_send 0x%lx\n",(unsigned long) skb,0);
	if (!ZATM_VCC(vcc)->tx_chan || !test_bit(ATM_VF_READY,&vcc->flags)) {
		if (vcc->pop) vcc->pop(vcc,skb);
		else dev_kfree_skb(skb);
		return -EINVAL;
	}
	if (!skb) {
		printk(KERN_CRIT "!skb in zatm_send ?\n");
		if (vcc->pop) vcc->pop(vcc,skb);
		return -EINVAL;
	}
	ATM_SKB(skb)->vcc = vcc;
	error = do_tx(skb);
	if (error != RING_BUSY) return error;
	skb_queue_tail(&ZATM_VCC(vcc)->backlog,skb);
	return 0;
}


static void zatm_phy_put(struct atm_dev *dev,unsigned char value,
    unsigned long addr)
{
	struct zatm_dev *zatm_dev;

	zatm_dev = ZATM_DEV(dev);
	zwait;
	zout(value,CER);
	zout(uPD98401_IND_ACC | uPD98401_IA_B0 |
	    (uPD98401_IA_TGT_PHY << uPD98401_IA_TGT_SHIFT) | addr,CMR);
}


static unsigned char zatm_phy_get(struct atm_dev *dev,unsigned long addr)
{
	struct zatm_dev *zatm_dev;

	zatm_dev = ZATM_DEV(dev);
	zwait;
	zout(uPD98401_IND_ACC | uPD98401_IA_B0 | uPD98401_IA_RW |
	  (uPD98401_IA_TGT_PHY << uPD98401_IA_TGT_SHIFT) | addr,CMR);
	zwait;
	return zin(CER) & 0xff;
}


static const struct atmdev_ops ops = {
	.open		= zatm_open,
	.close		= zatm_close,
	.ioctl		= zatm_ioctl,
	.getsockopt	= zatm_getsockopt,
	.setsockopt	= zatm_setsockopt,
	.send		= zatm_send,
	.phy_put	= zatm_phy_put,
	.phy_get	= zatm_phy_get,
	.change_qos	= zatm_change_qos,
};

static int __devinit zatm_init_one(struct pci_dev *pci_dev,
				   const struct pci_device_id *ent)
{
	struct atm_dev *dev;
	struct zatm_dev *zatm_dev;
	int ret = -ENOMEM;

	zatm_dev = (struct zatm_dev *) kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
	if (!zatm_dev) {
		printk(KERN_EMERG "%s: memory shortage\n", DEV_LABEL);
		goto out;
	}

	dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
	if (!dev)
		goto out_free;

	ret = pci_enable_device(pci_dev);
	if (ret < 0)
		goto out_deregister;

	ret = pci_request_regions(pci_dev, DEV_LABEL);
	if (ret < 0)
		goto out_disable;

	zatm_dev->pci_dev = pci_dev;
	dev->dev_data = zatm_dev;
	zatm_dev->copper = (int)ent->driver_data;
	if ((ret = zatm_init(dev)) || (ret = zatm_start(dev)))
		goto out_release;

	pci_set_drvdata(pci_dev, dev);
	zatm_dev->more = zatm_boards;
	zatm_boards = dev;
	ret = 0;
out:
	return ret;

out_release:
	pci_release_regions(pci_dev);
out_disable:
	pci_disable_device(pci_dev);
out_deregister:
	atm_dev_deregister(dev);
out_free:
	kfree(zatm_dev);
	goto out;
}


MODULE_LICENSE("GPL");

static struct pci_device_id zatm_pci_tbl[] __devinitdata = {
	{ PCI_VENDOR_ID_ZEITNET, PCI_DEVICE_ID_ZEITNET_1221,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ZATM_COPPER },
	{ PCI_VENDOR_ID_ZEITNET, PCI_DEVICE_ID_ZEITNET_1225,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, zatm_pci_tbl);

static struct pci_driver zatm_driver = {
	.name =		DEV_LABEL,
	.id_table =	zatm_pci_tbl,
	.probe =	zatm_init_one,
};

static int __init zatm_init_module(void)
{
	return pci_register_driver(&zatm_driver);
}

module_init(zatm_init_module);
/* module_exit not defined so not unloadable */
