
/* drivers/atm/firestream.c - FireStream 155 (MB86697) and
 *                            FireStream  50 (MB86695) device driver 
 */
 
/* Written & (C) 2000 by R.E.Wolff@BitWizard.nl 
 * Copied snippets from zatm.c by Werner Almesberger, EPFL LRC/ICA 
 * and ambassador.c Copyright (C) 1995-1999  Madge Networks Ltd 
 */

/*
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  The GNU GPL is contained in /usr/doc/copyright/GPL on a Debian
  system and in the file COPYING in the Linux kernel source.
*/


#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/poison.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/ioport.h> /* for request_region */
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/capability.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/string.h>
#include <asm/io.h>
#include <linux/atomic.h>
#include <asm/uaccess.h>
#include <linux/wait.h>

#include "firestream.h"

static int loopback = 0;
static int num=0x5a;

/* According to measurements (but they look suspicious to me!) done in
 * '97, 37% of the packets are one cell in size. So it pays to have
 * buffers allocated at that size. A large jump in percentage of
 * packets occurs at packets around 536 bytes in length. So it also
 * pays to have those pre-allocated. Unfortunately, we can't fully
 * take advantage of this as the majority of the packets is likely to
 * be TCP/IP (As where obviously the measurement comes from) There the
 * link would be opened with say a 1500 byte MTU, and we can't handle
 * smaller buffers more efficiently than the larger ones. -- REW
 */

/* Due to the way Linux memory management works, specifying "576" as
 * an allocation size here isn't going to help. They are allocated
 * from 1024-byte regions anyway. With the size of the sk_buffs (quite
 * large), it doesn't pay to allocate the smallest size (64) -- REW */

/* This is all guesswork. Hard numbers to back this up or disprove this, 
 * are appreciated. -- REW */

/* The last entry should be about 64k. However, the "buffer size" is
 * passed to the chip in a 16 bit field. I don't know how "65536"
 * would be interpreted. -- REW */

#define NP FS_NR_FREE_POOLS
static int rx_buf_sizes[NP]  = {128,  256,  512, 1024, 2048, 4096, 16384, 65520};
/* log2:                 7     8     9    10    11    12    14     16 */

#if 0
static int rx_pool_sizes[NP] = {1024, 1024, 512, 256,  128,  64,   32,    32};
#else
/* debug */
static int rx_pool_sizes[NP] = {128,  128,  128, 64,   64,   64,   32,    32};
#endif
/* log2:                 10    10    9    8     7     6     5      5  */
/* sumlog2:              17    18    18   18    18    18    19     21 */
/* mem allocated:        128k  256k  256k 256k  256k  256k  512k   2M */
/* tot mem: almost 4M */

/* NP is shorter, so that it fits on a single line. */
#undef NP


/* Small hardware gotcha:

   The FS50 CAM (VP/VC match registers) always take the lowest channel
   number that matches. This is not a problem.

   However, they also ignore whether the channel is enabled or
   not. This means that if you allocate channel 0 to 1.2 and then
   channel 1 to 0.0, then disabeling channel 0 and writing 0 to the
   match channel for channel 0 will "steal" the traffic from channel
   1, even if you correctly disable channel 0.

   Workaround: 

   - When disabling channels, write an invalid VP/VC value to the
   match register. (We use 0xffffffff, which in the worst case 
   matches VP/VC = <maxVP>/<maxVC>, but I expect it not to match
   anything as some "when not in use, program to 0" bits are now
   programmed to 1...)

   - Don't initialize the match registers to 0, as 0.0 is a valid
   channel.
*/


/* Optimization hints and tips.

   The FireStream chips are very capable of reducing the amount of
   "interrupt-traffic" for the CPU. This driver requests an interrupt on EVERY
   action. You could try to minimize this a bit. 

   Besides that, the userspace->kernel copy and the PCI bus are the
   performance limiting issues for this driver.

   You could queue up a bunch of outgoing packets without telling the
   FireStream. I'm not sure that's going to win you much though. The
   Linux layer won't tell us in advance when it's not going to give us
   any more packets in a while. So this is tricky to implement right without
   introducing extra delays. 
  
   -- REW
 */




/* The strings that define what the RX queue entry is all about. */
/* Fujitsu: Please tell me which ones can have a pointer to a 
   freepool descriptor! */
static char *res_strings[] = {
	"RX OK: streaming not EOP", 
	"RX OK: streaming EOP", 
	"RX OK: Single buffer packet", 
	"RX OK: packet mode", 
	"RX OK: F4 OAM (end to end)", 
	"RX OK: F4 OAM (Segment)", 
	"RX OK: F5 OAM (end to end)", 
	"RX OK: F5 OAM (Segment)", 
	"RX OK: RM cell", 
	"RX OK: TRANSP cell", 
	"RX OK: TRANSPC cell", 
	"Unmatched cell", 
	"reserved 12", 
	"reserved 13", 
	"reserved 14", 
	"Unrecognized cell", 
	"reserved 16", 
	"reassemby abort: AAL5 abort", 
	"packet purged", 
	"packet ageing timeout", 
	"channel ageing timeout", 
	"calculated length error", 
	"programmed length limit error", 
	"aal5 crc32 error", 
	"oam transp or transpc crc10 error", 
	"reserved 25", 
	"reserved 26", 
	"reserved 27", 
	"reserved 28", 
	"reserved 29", 
	"reserved 30", 
	"reassembly abort: no buffers", 
	"receive buffer overflow", 
	"change in GFC", 
	"receive buffer full", 
	"low priority discard - no receive descriptor", 
	"low priority discard - missing end of packet", 
	"reserved 41", 
	"reserved 42", 
	"reserved 43", 
	"reserved 44", 
	"reserved 45", 
	"reserved 46", 
	"reserved 47", 
	"reserved 48", 
	"reserved 49", 
	"reserved 50", 
	"reserved 51", 
	"reserved 52", 
	"reserved 53", 
	"reserved 54", 
	"reserved 55", 
	"reserved 56", 
	"reserved 57", 
	"reserved 58", 
	"reserved 59", 
	"reserved 60", 
	"reserved 61", 
	"reserved 62", 
	"reserved 63", 
};  

static char *irq_bitname[] = {
	"LPCO",
	"DPCO",
	"RBRQ0_W",
	"RBRQ1_W",
	"RBRQ2_W",
	"RBRQ3_W",
	"RBRQ0_NF",
	"RBRQ1_NF",
	"RBRQ2_NF",
	"RBRQ3_NF",
	"BFP_SC",
	"INIT",
	"INIT_ERR",
	"USCEO",
	"UPEC0",
	"VPFCO",
	"CRCCO",
	"HECO",
	"TBRQ_W",
	"TBRQ_NF",
	"CTPQ_E",
	"GFC_C0",
	"PCI_FTL",
	"CSQ_W",
	"CSQ_NF",
	"EXT_INT",
	"RXDMA_S"
};


#define PHY_EOF -1
#define PHY_CLEARALL -2

struct reginit_item {
	int reg, val;
};


static struct reginit_item PHY_NTC_INIT[] = {
	{ PHY_CLEARALL, 0x40 }, 
	{ 0x12,  0x0001 },
	{ 0x13,  0x7605 },
	{ 0x1A,  0x0001 },
	{ 0x1B,  0x0005 },
	{ 0x38,  0x0003 },
	{ 0x39,  0x0006 },   /* changed here to make loopback */
	{ 0x01,  0x5262 },
	{ 0x15,  0x0213 },
	{ 0x00,  0x0003 },
	{ PHY_EOF, 0},    /* -1 signals end of list */
};


/* Safetyfeature: If the card interrupts more than this number of times
   in a jiffy (1/100th of a second) then we just disable the interrupt and
   print a message. This prevents the system from hanging. 

   150000 packets per second is close to the limit a PC is going to have
   anyway. We therefore have to disable this for production. -- REW */
#undef IRQ_RATE_LIMIT // 100

/* Interrupts work now. Unlike serial cards, ATM cards don't work all
   that great without interrupts. -- REW */
#undef FS_POLL_FREQ // 100

/* 
   This driver can spew a whole lot of debugging output at you. If you
   need maximum performance, you should disable the DEBUG define. To
   aid in debugging in the field, I'm leaving the compile-time debug
   features enabled, and disable them "runtime". That allows me to
   instruct people with problems to enable debugging without requiring
   them to recompile... -- REW
*/
#define DEBUG

#ifdef DEBUG
#define fs_dprintk(f, str...) if (fs_debug & f) printk (str)
#else
#define fs_dprintk(f, str...) /* nothing */
#endif


static int fs_keystream = 0;

#ifdef DEBUG
/* I didn't forget to set this to zero before shipping. Hit me with a stick 
   if you get this with the debug default not set to zero again. -- REW */
static int fs_debug = 0;
#else
#define fs_debug 0
#endif

#ifdef MODULE
#ifdef DEBUG 
module_param(fs_debug, int, 0644);
#endif
module_param(loopback, int, 0);
module_param(num, int, 0);
module_param(fs_keystream, int, 0);
/* XXX Add rx_buf_sizes, and rx_pool_sizes As per request Amar. -- REW */
#endif


#define FS_DEBUG_FLOW    0x00000001
#define FS_DEBUG_OPEN    0x00000002
#define FS_DEBUG_QUEUE   0x00000004
#define FS_DEBUG_IRQ     0x00000008
#define FS_DEBUG_INIT    0x00000010
#define FS_DEBUG_SEND    0x00000020
#define FS_DEBUG_PHY     0x00000040
#define FS_DEBUG_CLEANUP 0x00000080
#define FS_DEBUG_QOS     0x00000100
#define FS_DEBUG_TXQ     0x00000200
#define FS_DEBUG_ALLOC   0x00000400
#define FS_DEBUG_TXMEM   0x00000800
#define FS_DEBUG_QSIZE   0x00001000


#define func_enter() fs_dprintk(FS_DEBUG_FLOW, "fs: enter %s\n", __func__)
#define func_exit()  fs_dprintk(FS_DEBUG_FLOW, "fs: exit  %s\n", __func__)


static struct fs_dev *fs_boards = NULL;

#ifdef DEBUG

static void my_hd (void *addr, int len)
{
	int j, ch;
	unsigned char *ptr = addr;

	while (len > 0) {
		printk ("%p ", ptr);
		for (j=0;j < ((len < 16)?len:16);j++) {
			printk ("%02x %s", ptr[j], (j==7)?" ":"");
		}
		for (  ;j < 16;j++) {
			printk ("   %s", (j==7)?" ":"");
		}
		for (j=0;j < ((len < 16)?len:16);j++) {
			ch = ptr[j];
			printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
		}
		printk ("\n");
		ptr += 16;
		len -= 16;
	}
}
#else /* DEBUG */
static void my_hd (void *addr, int len){}
#endif /* DEBUG */

/********** free an skb (as per ATM device driver documentation) **********/

/* Hmm. If this is ATM specific, why isn't there an ATM routine for this?
 * I copied it over from the ambassador driver. -- REW */

static inline void fs_kfree_skb (struct sk_buff * skb) 
{
	if (ATM_SKB(skb)->vcc->pop)
		ATM_SKB(skb)->vcc->pop (ATM_SKB(skb)->vcc, skb);
	else
		dev_kfree_skb_any (skb);
}




/* It seems the ATM forum recommends this horribly complicated 16bit
 * floating point format. Turns out the Ambassador uses the exact same
 * encoding. I just copied it over. If Mitch agrees, I'll move it over
 * to the atm_misc file or something like that. (and remove it from 
 * here and the ambassador driver) -- REW
 */

/* The good thing about this format is that it is monotonic. So, 
   a conversion routine need not be very complicated. To be able to
   round "nearest" we need to take along a few extra bits. Lets
   put these after 16 bits, so that we can just return the top 16
   bits of the 32bit number as the result:

   int mr (unsigned int rate, int r) 
     {
     int e = 16+9;
     static int round[4]={0, 0, 0xffff, 0x8000};
     if (!rate) return 0;
     while (rate & 0xfc000000) {
       rate >>= 1;
       e++;
     }
     while (! (rate & 0xfe000000)) {
       rate <<= 1;
       e--;
     }

// Now the mantissa is in positions bit 16-25. Excepf for the "hidden 1" that's in bit 26.
     rate &= ~0x02000000;
// Next add in the exponent
     rate |= e << (16+9);
// And perform the rounding:
     return (rate + round[r]) >> 16;
   }

   14 lines-of-code. Compare that with the 120 that the Ambassador
   guys needed. (would be 8 lines shorter if I'd try to really reduce
   the number of lines:

   int mr (unsigned int rate, int r) 
   {
     int e = 16+9;
     static int round[4]={0, 0, 0xffff, 0x8000};
     if (!rate) return 0;
     for (;  rate & 0xfc000000 ;rate >>= 1, e++);
     for (;!(rate & 0xfe000000);rate <<= 1, e--);
     return ((rate & ~0x02000000) | (e << (16+9)) + round[r]) >> 16;
   }

   Exercise for the reader: Remove one more line-of-code, without
   cheating. (Just joining two lines is cheating). (I know it's
   possible, don't think you've beat me if you found it... If you
   manage to lose two lines or more, keep me updated! ;-)

   -- REW */


#define ROUND_UP      1
#define ROUND_DOWN    2
#define ROUND_NEAREST 3
/********** make rate (not quite as much fun as Horizon) **********/

static int make_rate(unsigned int rate, int r,
		      u16 *bits, unsigned int *actual)
{
	unsigned char exp = -1; /* hush gcc */
	unsigned int man = -1;  /* hush gcc */
  
	fs_dprintk (FS_DEBUG_QOS, "make_rate %u", rate);
  
	/* rates in cells per second, ITU format (nasty 16-bit floating-point)
	   given 5-bit e and 9-bit m:
	   rate = EITHER (1+m/2^9)*2^e    OR 0
	   bits = EITHER 1<<14 | e<<9 | m OR 0
	   (bit 15 is "reserved", bit 14 "non-zero")
	   smallest rate is 0 (special representation)
	   largest rate is (1+511/512)*2^31 = 4290772992 (< 2^32-1)
	   smallest non-zero rate is (1+0/512)*2^0 = 1 (> 0)
	   simple algorithm:
	   find position of top bit, this gives e
	   remove top bit and shift (rounding if feeling clever) by 9-e
	*/
	/* Ambassador ucode bug: please don't set bit 14! so 0 rate not
	   representable. // This should move into the ambassador driver
	   when properly merged. -- REW */
  
	if (rate > 0xffc00000U) {
		/* larger than largest representable rate */
    
		if (r == ROUND_UP) {
			return -EINVAL;
		} else {
			exp = 31;
			man = 511;
		}
    
	} else if (rate) {
		/* representable rate */
    
		exp = 31;
		man = rate;
    
		/* invariant: rate = man*2^(exp-31) */
		while (!(man & (1<<31))) {
			exp = exp - 1;
			man = man<<1;
		}
    
		/* man has top bit set
		   rate = (2^31+(man-2^31))*2^(exp-31)
		   rate = (1+(man-2^31)/2^31)*2^exp 
		*/
		man = man<<1;
		man &= 0xffffffffU; /* a nop on 32-bit systems */
		/* rate = (1+man/2^32)*2^exp
    
		   exp is in the range 0 to 31, man is in the range 0 to 2^32-1
		   time to lose significance... we want m in the range 0 to 2^9-1
		   rounding presents a minor problem... we first decide which way
		   we are rounding (based on given rounding direction and possibly
		   the bits of the mantissa that are to be discarded).
		*/

		switch (r) {
		case ROUND_DOWN: {
			/* just truncate */
			man = man>>(32-9);
			break;
		}
		case ROUND_UP: {
			/* check all bits that we are discarding */
			if (man & (~0U>>9)) {
				man = (man>>(32-9)) + 1;
				if (man == (1<<9)) {
					/* no need to check for round up outside of range */
					man = 0;
					exp += 1;
				}
			} else {
				man = (man>>(32-9));
			}
			break;
		}
		case ROUND_NEAREST: {
			/* check msb that we are discarding */
			if (man & (1<<(32-9-1))) {
				man = (man>>(32-9)) + 1;
				if (man == (1<<9)) {
					/* no need to check for round up outside of range */
					man = 0;
					exp += 1;
				}
			} else {
				man = (man>>(32-9));
			}
			break;
		}
		}
    
	} else {
		/* zero rate - not representable */
    
		if (r == ROUND_DOWN) {
			return -EINVAL;
		} else {
			exp = 0;
			man = 0;
		}
	}
  
	fs_dprintk (FS_DEBUG_QOS, "rate: man=%u, exp=%hu", man, exp);
  
	if (bits)
		*bits = /* (1<<14) | */ (exp<<9) | man;
  
	if (actual)
		*actual = (exp >= 9)
			? (1 << exp) + (man << (exp-9))
			: (1 << exp) + ((man + (1<<(9-exp-1))) >> (9-exp));
  
	return 0;
}




/* FireStream access routines */
/* For DEEP-DOWN debugging these can be rigged to intercept accesses to
   certain registers or to just log all accesses. */

static inline void write_fs (struct fs_dev *dev, int offset, u32 val)
{
	writel (val, dev->base + offset);
}


static inline u32  read_fs (struct fs_dev *dev, int offset)
{
	return readl (dev->base + offset);
}



static inline struct FS_QENTRY *get_qentry (struct fs_dev *dev, struct queue *q)
{
	return bus_to_virt (read_fs (dev, Q_WP(q->offset)) & Q_ADDR_MASK);
}


static void submit_qentry (struct fs_dev *dev, struct queue *q, struct FS_QENTRY *qe)
{
	u32 wp;
	struct FS_QENTRY *cqe;

	/* XXX Sanity check: the write pointer can be checked to be 
	   still the same as the value passed as qe... -- REW */
	/*  udelay (5); */
	while ((wp = read_fs (dev, Q_WP (q->offset))) & Q_FULL) {
		fs_dprintk (FS_DEBUG_TXQ, "Found queue at %x full. Waiting.\n", 
			    q->offset);
		schedule ();
	}

	wp &= ~0xf;
	cqe = bus_to_virt (wp);
	if (qe != cqe) {
		fs_dprintk (FS_DEBUG_TXQ, "q mismatch! %p %p\n", qe, cqe);
	}

	write_fs (dev, Q_WP(q->offset), Q_INCWRAP);

	{
		static int c;
		if (!(c++ % 100))
			{
				int rp, wp;
				rp =  read_fs (dev, Q_RP(q->offset));
				wp =  read_fs (dev, Q_WP(q->offset));
				fs_dprintk (FS_DEBUG_TXQ, "q at %d: %x-%x: %x entries.\n", 
					    q->offset, rp, wp, wp-rp);
			}
	}
}

#ifdef DEBUG_EXTRA
static struct FS_QENTRY pq[60];
static int qp;

static struct FS_BPENTRY dq[60];
static int qd;
static void *da[60];
#endif 

static void submit_queue (struct fs_dev *dev, struct queue *q, 
			  u32 cmd, u32 p1, u32 p2, u32 p3)
{
	struct FS_QENTRY *qe;

	qe = get_qentry (dev, q);
	qe->cmd = cmd;
	qe->p0 = p1;
	qe->p1 = p2;
	qe->p2 = p3;
	submit_qentry (dev,  q, qe);

#ifdef DEBUG_EXTRA
	pq[qp].cmd = cmd;
	pq[qp].p0 = p1;
	pq[qp].p1 = p2;
	pq[qp].p2 = p3;
	qp++;
	if (qp >= 60) qp = 0;
#endif
}

/* Test the "other" way one day... -- REW */
#if 1
#define submit_command submit_queue
#else

static void submit_command (struct fs_dev *dev, struct queue *q, 
			    u32 cmd, u32 p1, u32 p2, u32 p3)
{
	write_fs (dev, CMDR0, cmd);
	write_fs (dev, CMDR1, p1);
	write_fs (dev, CMDR2, p2);
	write_fs (dev, CMDR3, p3);
}
#endif



static void process_return_queue (struct fs_dev *dev, struct queue *q)
{
	long rq;
	struct FS_QENTRY *qe;
	void *tc;
  
	while (!((rq = read_fs (dev, Q_RP(q->offset))) & Q_EMPTY)) {
		fs_dprintk (FS_DEBUG_QUEUE, "reaping return queue entry at %lx\n", rq); 
		qe = bus_to_virt (rq);
    
		fs_dprintk (FS_DEBUG_QUEUE, "queue entry: %08x %08x %08x %08x. (%d)\n", 
			    qe->cmd, qe->p0, qe->p1, qe->p2, STATUS_CODE (qe));

		switch (STATUS_CODE (qe)) {
		case 5:
			tc = bus_to_virt (qe->p0);
			fs_dprintk (FS_DEBUG_ALLOC, "Free tc: %p\n", tc);
			kfree (tc);
			break;
		}
    
		write_fs (dev, Q_RP(q->offset), Q_INCWRAP);
	}
}


static void process_txdone_queue (struct fs_dev *dev, struct queue *q)
{
	long rq;
	long tmp;
	struct FS_QENTRY *qe;
	struct sk_buff *skb;
	struct FS_BPENTRY *td;

	while (!((rq = read_fs (dev, Q_RP(q->offset))) & Q_EMPTY)) {
		fs_dprintk (FS_DEBUG_QUEUE, "reaping txdone entry at %lx\n", rq); 
		qe = bus_to_virt (rq);
    
		fs_dprintk (FS_DEBUG_QUEUE, "queue entry: %08x %08x %08x %08x: %d\n", 
			    qe->cmd, qe->p0, qe->p1, qe->p2, STATUS_CODE (qe));

		if (STATUS_CODE (qe) != 2)
			fs_dprintk (FS_DEBUG_TXMEM, "queue entry: %08x %08x %08x %08x: %d\n", 
				    qe->cmd, qe->p0, qe->p1, qe->p2, STATUS_CODE (qe));


		switch (STATUS_CODE (qe)) {
		case 0x01: /* This is for AAL0 where we put the chip in streaming mode */
			/* Fall through */
		case 0x02:
			/* Process a real txdone entry. */
			tmp = qe->p0;
			if (tmp & 0x0f)
				printk (KERN_WARNING "td not aligned: %ld\n", tmp);
			tmp &= ~0x0f;
			td = bus_to_virt (tmp);

			fs_dprintk (FS_DEBUG_QUEUE, "Pool entry: %08x %08x %08x %08x %p.\n", 
				    td->flags, td->next, td->bsa, td->aal_bufsize, td->skb );
      
			skb = td->skb;
			if (skb == FS_VCC (ATM_SKB(skb)->vcc)->last_skb) {
				FS_VCC (ATM_SKB(skb)->vcc)->last_skb = NULL;
				wake_up_interruptible (& FS_VCC (ATM_SKB(skb)->vcc)->close_wait);
			}
			td->dev->ntxpckts--;

			{
				static int c=0;
	
				if (!(c++ % 100)) {
					fs_dprintk (FS_DEBUG_QSIZE, "[%d]", td->dev->ntxpckts);
				}
			}

			atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);

			fs_dprintk (FS_DEBUG_TXMEM, "i");
			fs_dprintk (FS_DEBUG_ALLOC, "Free t-skb: %p\n", skb);
			fs_kfree_skb (skb);

			fs_dprintk (FS_DEBUG_ALLOC, "Free trans-d: %p\n", td); 
			memset (td, ATM_POISON_FREE, sizeof(struct FS_BPENTRY));
			kfree (td);
			break;
		default:
			/* Here we get the tx purge inhibit command ... */
			/* Action, I believe, is "don't do anything". -- REW */
			;
		}
    
		write_fs (dev, Q_RP(q->offset), Q_INCWRAP);
	}
}


static void process_incoming (struct fs_dev *dev, struct queue *q)
{
	long rq;
	struct FS_QENTRY *qe;
	struct FS_BPENTRY *pe;    
	struct sk_buff *skb;
	unsigned int channo;
	struct atm_vcc *atm_vcc;

	while (!((rq = read_fs (dev, Q_RP(q->offset))) & Q_EMPTY)) {
		fs_dprintk (FS_DEBUG_QUEUE, "reaping incoming queue entry at %lx\n", rq); 
		qe = bus_to_virt (rq);
    
		fs_dprintk (FS_DEBUG_QUEUE, "queue entry: %08x %08x %08x %08x.  ", 
			    qe->cmd, qe->p0, qe->p1, qe->p2);

		fs_dprintk (FS_DEBUG_QUEUE, "-> %x: %s\n", 
			    STATUS_CODE (qe), 
			    res_strings[STATUS_CODE(qe)]);

		pe = bus_to_virt (qe->p0);
		fs_dprintk (FS_DEBUG_QUEUE, "Pool entry: %08x %08x %08x %08x %p %p.\n", 
			    pe->flags, pe->next, pe->bsa, pe->aal_bufsize, 
			    pe->skb, pe->fp);
      
		channo = qe->cmd & 0xffff;

		if (channo < dev->nchannels)
			atm_vcc = dev->atm_vccs[channo];
		else
			atm_vcc = NULL;

		/* Single buffer packet */
		switch (STATUS_CODE (qe)) {
		case 0x1:
			/* Fall through for streaming mode */
		case 0x2:/* Packet received OK.... */
			if (atm_vcc) {
				skb = pe->skb;
				pe->fp->n--;
#if 0
				fs_dprintk (FS_DEBUG_QUEUE, "Got skb: %p\n", skb);
				if (FS_DEBUG_QUEUE & fs_debug) my_hd (bus_to_virt (pe->bsa), 0x20);
#endif
				skb_put (skb, qe->p1 & 0xffff); 
				ATM_SKB(skb)->vcc = atm_vcc;
				atomic_inc(&atm_vcc->stats->rx);
				__net_timestamp(skb);
				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
				atm_vcc->push (atm_vcc, skb);
				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", pe);
				kfree (pe);
			} else {
				printk (KERN_ERR "Got a receive on a non-open channel %d.\n", channo);
			}
			break;
		case 0x17:/* AAL 5 CRC32 error. IFF the length field is nonzero, a buffer
			     has been consumed and needs to be processed. -- REW */
			if (qe->p1 & 0xffff) {
				pe = bus_to_virt (qe->p0);
				pe->fp->n--;
				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", pe->skb);
				dev_kfree_skb_any (pe->skb);
				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", pe);
				kfree (pe);
			}
			if (atm_vcc)
				atomic_inc(&atm_vcc->stats->rx_drop);
			break;
		case 0x1f: /*  Reassembly abort: no buffers. */
			/* Silently increment error counter. */
			if (atm_vcc)
				atomic_inc(&atm_vcc->stats->rx_drop);
			break;
		default: /* Hmm. Haven't written the code to handle the others yet... -- REW */
			printk (KERN_WARNING "Don't know what to do with RX status %x: %s.\n", 
				STATUS_CODE(qe), res_strings[STATUS_CODE (qe)]);
		}
		write_fs (dev, Q_RP(q->offset), Q_INCWRAP);
	}
}



#define DO_DIRECTION(tp) ((tp)->traffic_class != ATM_NONE)

static int fs_open(struct atm_vcc *atm_vcc)
{
	struct fs_dev *dev;
	struct fs_vcc *vcc;
	struct fs_transmit_config *tc;
	struct atm_trafprm * txtp;
	struct atm_trafprm * rxtp;
	/*  struct fs_receive_config *rc;*/
	/*  struct FS_QENTRY *qe; */
	int error;
	int bfp;
	int to;
	unsigned short tmc0;
	short vpi = atm_vcc->vpi;
	int vci = atm_vcc->vci;

	func_enter ();

	dev = FS_DEV(atm_vcc->dev);
	fs_dprintk (FS_DEBUG_OPEN, "fs: open on dev: %p, vcc at %p\n", 
		    dev, atm_vcc);

	if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
		set_bit(ATM_VF_ADDR, &atm_vcc->flags);

	if ((atm_vcc->qos.aal != ATM_AAL5) &&
	    (atm_vcc->qos.aal != ATM_AAL2))
	  return -EINVAL; /* XXX AAL0 */

	fs_dprintk (FS_DEBUG_OPEN, "fs: (itf %d): open %d.%d\n", 
		    atm_vcc->dev->number, atm_vcc->vpi, atm_vcc->vci);	

	/* XXX handle qos parameters (rate limiting) ? */

	vcc = kmalloc(sizeof(struct fs_vcc), GFP_KERNEL);
	fs_dprintk (FS_DEBUG_ALLOC, "Alloc VCC: %p(%Zd)\n", vcc, sizeof(struct fs_vcc));
	if (!vcc) {
		clear_bit(ATM_VF_ADDR, &atm_vcc->flags);
		return -ENOMEM;
	}
  
	atm_vcc->dev_data = vcc;
	vcc->last_skb = NULL;

	init_waitqueue_head (&vcc->close_wait);

	txtp = &atm_vcc->qos.txtp;
	rxtp = &atm_vcc->qos.rxtp;

	if (!test_bit(ATM_VF_PARTIAL, &atm_vcc->flags)) {
		if (IS_FS50(dev)) {
			/* Increment the channel numer: take a free one next time.  */
			for (to=33;to;to--, dev->channo++) {
				/* We only have 32 channels */
				if (dev->channo >= 32)
					dev->channo = 0;
				/* If we need to do RX, AND the RX is inuse, try the next */
				if (DO_DIRECTION(rxtp) && dev->atm_vccs[dev->channo])
					continue;
				/* If we need to do TX, AND the TX is inuse, try the next */
				if (DO_DIRECTION(txtp) && test_bit (dev->channo, dev->tx_inuse))
					continue;
				/* Ok, both are free! (or not needed) */
				break;
			}
			if (!to) {
				printk ("No more free channels for FS50..\n");
				return -EBUSY;
			}
			vcc->channo = dev->channo;
			dev->channo &= dev->channel_mask;
      
		} else {
			vcc->channo = (vpi << FS155_VCI_BITS) | (vci);
			if (((DO_DIRECTION(rxtp) && dev->atm_vccs[vcc->channo])) ||
			    ( DO_DIRECTION(txtp) && test_bit (vcc->channo, dev->tx_inuse))) {
				printk ("Channel is in use for FS155.\n");
				return -EBUSY;
			}
		}
		fs_dprintk (FS_DEBUG_OPEN, "OK. Allocated channel %x(%d).\n", 
			    vcc->channo, vcc->channo);
	}

	if (DO_DIRECTION (txtp)) {
		tc = kmalloc (sizeof (struct fs_transmit_config), GFP_KERNEL);
		fs_dprintk (FS_DEBUG_ALLOC, "Alloc tc: %p(%Zd)\n",
			    tc, sizeof (struct fs_transmit_config));
		if (!tc) {
			fs_dprintk (FS_DEBUG_OPEN, "fs: can't alloc transmit_config.\n");
			return -ENOMEM;
		}

		/* Allocate the "open" entry from the high priority txq. This makes
		   it most likely that the chip will notice it. It also prevents us
		   from having to wait for completion. On the other hand, we may
		   need to wait for completion anyway, to see if it completed
		   successfully. */

		switch (atm_vcc->qos.aal) {
		case ATM_AAL2:
		case ATM_AAL0:
		  tc->flags = 0
		    | TC_FLAGS_TRANSPARENT_PAYLOAD
		    | TC_FLAGS_PACKET
		    | (1 << 28)
		    | TC_FLAGS_TYPE_UBR /* XXX Change to VBR -- PVDL */
		    | TC_FLAGS_CAL0;
		  break;
		case ATM_AAL5:
		  tc->flags = 0
			| TC_FLAGS_AAL5
			| TC_FLAGS_PACKET  /* ??? */
			| TC_FLAGS_TYPE_CBR
			| TC_FLAGS_CAL0;
		  break;
		default:
			printk ("Unknown aal: %d\n", atm_vcc->qos.aal);
			tc->flags = 0;
		}
		/* Docs are vague about this atm_hdr field. By the way, the FS
		 * chip makes odd errors if lower bits are set.... -- REW */
		tc->atm_hdr =  (vpi << 20) | (vci << 4); 
		tmc0 = 0;
		{
			int pcr = atm_pcr_goal (txtp);

			fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr);

			/* XXX Hmm. officially we're only allowed to do this if rounding 
			   is round_down -- REW */
			if (IS_FS50(dev)) {
				if (pcr > 51840000/53/8)  pcr = 51840000/53/8;
			} else {
				if (pcr > 155520000/53/8) pcr = 155520000/53/8;
			}
			if (!pcr) {
				/* no rate cap */
				tmc0 = IS_FS50(dev)?0x61BE:0x64c9; /* Just copied over the bits from Fujitsu -- REW */
			} else {
				int r;
				if (pcr < 0) {
					r = ROUND_DOWN;
					pcr = -pcr;
				} else {
					r = ROUND_UP;
				}
				error = make_rate (pcr, r, &tmc0, NULL);
				if (error) {
					kfree(tc);
					return error;
				}
			}
			fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr);
		}
      
		tc->TMC[0] = tmc0 | 0x4000;
		tc->TMC[1] = 0; /* Unused */
		tc->TMC[2] = 0; /* Unused */
		tc->TMC[3] = 0; /* Unused */
    
		tc->spec = 0;    /* UTOPIA address, UDF, HEC: Unused -> 0 */
		tc->rtag[0] = 0; /* What should I do with routing tags??? 
				    -- Not used -- AS -- Thanks -- REW*/
		tc->rtag[1] = 0;
		tc->rtag[2] = 0;

		if (fs_debug & FS_DEBUG_OPEN) {
			fs_dprintk (FS_DEBUG_OPEN, "TX config record:\n");
			my_hd (tc, sizeof (*tc));
		}

		/* We now use the "submit_command" function to submit commands to
		   the firestream. There is a define up near the definition of
		   that routine that switches this routine between immediate write
		   to the immediate command registers and queuing the commands in
		   the HPTXQ for execution. This last technique might be more
		   efficient if we know we're going to submit a whole lot of
		   commands in one go, but this driver is not setup to be able to
		   use such a construct. So it probably doen't matter much right
		   now. -- REW */
    
		/* The command is IMMediate and INQueue. The parameters are out-of-line.. */
		submit_command (dev, &dev->hp_txq, 
				QE_CMD_CONFIG_TX | QE_CMD_IMM_INQ | vcc->channo,
				virt_to_bus (tc), 0, 0);

		submit_command (dev, &dev->hp_txq, 
				QE_CMD_TX_EN | QE_CMD_IMM_INQ | vcc->channo,
				0, 0, 0);
		set_bit (vcc->channo, dev->tx_inuse);
	}

	if (DO_DIRECTION (rxtp)) {
		dev->atm_vccs[vcc->channo] = atm_vcc;

		for (bfp = 0;bfp < FS_NR_FREE_POOLS; bfp++)
			if (atm_vcc->qos.rxtp.max_sdu <= dev->rx_fp[bfp].bufsize) break;
		if (bfp >= FS_NR_FREE_POOLS) {
			fs_dprintk (FS_DEBUG_OPEN, "No free pool fits sdu: %d.\n", 
				    atm_vcc->qos.rxtp.max_sdu);
			/* XXX Cleanup? -- Would just calling fs_close work??? -- REW */

			/* XXX clear tx inuse. Close TX part? */
			dev->atm_vccs[vcc->channo] = NULL;
			kfree (vcc);
			return -EINVAL;
		}

		switch (atm_vcc->qos.aal) {
		case ATM_AAL0:
		case ATM_AAL2:
			submit_command (dev, &dev->hp_txq,
					QE_CMD_CONFIG_RX | QE_CMD_IMM_INQ | vcc->channo,
					RC_FLAGS_TRANSP |
					RC_FLAGS_BFPS_BFP * bfp |
					RC_FLAGS_RXBM_PSB, 0, 0);
			break;
		case ATM_AAL5:
			submit_command (dev, &dev->hp_txq,
					QE_CMD_CONFIG_RX | QE_CMD_IMM_INQ | vcc->channo,
					RC_FLAGS_AAL5 |
					RC_FLAGS_BFPS_BFP * bfp |
					RC_FLAGS_RXBM_PSB, 0, 0);
			break;
		};
		if (IS_FS50 (dev)) {
			submit_command (dev, &dev->hp_txq, 
					QE_CMD_REG_WR | QE_CMD_IMM_INQ,
					0x80 + vcc->channo,
					(vpi << 16) | vci, 0 ); /* XXX -- Use defines. */
		}
		submit_command (dev, &dev->hp_txq, 
				QE_CMD_RX_EN | QE_CMD_IMM_INQ | vcc->channo,
				0, 0, 0);
	}
    
	/* Indicate we're done! */
	set_bit(ATM_VF_READY, &atm_vcc->flags);

	func_exit ();
	return 0;
}


static void fs_close(struct atm_vcc *atm_vcc)
{
	struct fs_dev *dev = FS_DEV (atm_vcc->dev);
	struct fs_vcc *vcc = FS_VCC (atm_vcc);
	struct atm_trafprm * txtp;
	struct atm_trafprm * rxtp;

	func_enter ();

	clear_bit(ATM_VF_READY, &atm_vcc->flags);

	fs_dprintk (FS_DEBUG_QSIZE, "--==**[%d]**==--", dev->ntxpckts);
	if (vcc->last_skb) {
		fs_dprintk (FS_DEBUG_QUEUE, "Waiting for skb %p to be sent.\n", 
			    vcc->last_skb);
		/* We're going to wait for the last packet to get sent on this VC. It would
		   be impolite not to send them don't you think? 
		   XXX
		   We don't know which packets didn't get sent. So if we get interrupted in 
		   this sleep_on, we'll lose any reference to these packets. Memory leak!
		   On the other hand, it's awfully convenient that we can abort a "close" that
		   is taking too long. Maybe just use non-interruptible sleep on? -- REW */
		wait_event_interruptible(vcc->close_wait, !vcc->last_skb);
	}

	txtp = &atm_vcc->qos.txtp;
	rxtp = &atm_vcc->qos.rxtp;
  

	/* See App note XXX (Unpublished as of now) for the reason for the 
	   removal of the "CMD_IMM_INQ" part of the TX_PURGE_INH... -- REW */

	if (DO_DIRECTION (txtp)) {
		submit_command (dev,  &dev->hp_txq,
				QE_CMD_TX_PURGE_INH | /*QE_CMD_IMM_INQ|*/ vcc->channo, 0,0,0);
		clear_bit (vcc->channo, dev->tx_inuse);
	}

	if (DO_DIRECTION (rxtp)) {
		submit_command (dev,  &dev->hp_txq,
				QE_CMD_RX_PURGE_INH | QE_CMD_IMM_INQ | vcc->channo, 0,0,0);
		dev->atm_vccs [vcc->channo] = NULL;
  
		/* This means that this is configured as a receive channel */
		if (IS_FS50 (dev)) {
			/* Disable the receive filter. Is 0/0 indeed an invalid receive
			   channel? -- REW.  Yes it is. -- Hang. Ok. I'll use -1
			   (0xfff...) -- REW */
			submit_command (dev, &dev->hp_txq, 
					QE_CMD_REG_WR | QE_CMD_IMM_INQ,
					0x80 + vcc->channo, -1, 0 ); 
		}
	}

	fs_dprintk (FS_DEBUG_ALLOC, "Free vcc: %p\n", vcc);
	kfree (vcc);

	func_exit ();
}


static int fs_send (struct atm_vcc *atm_vcc, struct sk_buff *skb)
{
	struct fs_dev *dev = FS_DEV (atm_vcc->dev);
	struct fs_vcc *vcc = FS_VCC (atm_vcc);
	struct FS_BPENTRY *td;

	func_enter ();

	fs_dprintk (FS_DEBUG_TXMEM, "I");
	fs_dprintk (FS_DEBUG_SEND, "Send: atm_vcc %p skb %p vcc %p dev %p\n", 
		    atm_vcc, skb, vcc, dev);

	fs_dprintk (FS_DEBUG_ALLOC, "Alloc t-skb: %p (atm_send)\n", skb);

	ATM_SKB(skb)->vcc = atm_vcc;

	vcc->last_skb = skb;

	td = kmalloc (sizeof (struct FS_BPENTRY), GFP_ATOMIC);
	fs_dprintk (FS_DEBUG_ALLOC, "Alloc transd: %p(%Zd)\n", td, sizeof (struct FS_BPENTRY));
	if (!td) {
		/* Oops out of mem */
		return -ENOMEM;
	}

	fs_dprintk (FS_DEBUG_SEND, "first word in buffer: %x\n", 
		    *(int *) skb->data);

	td->flags =  TD_EPI | TD_DATA | skb->len;
	td->next = 0;
	td->bsa  = virt_to_bus (skb->data);
	td->skb = skb;
	td->dev = dev;
	dev->ntxpckts++;

#ifdef DEBUG_EXTRA
	da[qd] = td;
	dq[qd].flags = td->flags;
	dq[qd].next  = td->next;
	dq[qd].bsa   = td->bsa;
	dq[qd].skb   = td->skb;
	dq[qd].dev   = td->dev;
	qd++;
	if (qd >= 60) qd = 0;
#endif

	submit_queue (dev, &dev->hp_txq, 
		      QE_TRANSMIT_DE | vcc->channo,
		      virt_to_bus (td), 0, 
		      virt_to_bus (td));

	fs_dprintk (FS_DEBUG_QUEUE, "in send: txq %d txrq %d\n", 
		    read_fs (dev, Q_EA (dev->hp_txq.offset)) -
		    read_fs (dev, Q_SA (dev->hp_txq.offset)),
		    read_fs (dev, Q_EA (dev->tx_relq.offset)) -
		    read_fs (dev, Q_SA (dev->tx_relq.offset)));

	func_exit ();
	return 0;
}


/* Some function placeholders for functions we don't yet support. */

#if 0
static int fs_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
	func_enter ();
	func_exit ();
	return -ENOIOCTLCMD;
}


static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,
			 void __user *optval,int optlen)
{
	func_enter ();
	func_exit ();
	return 0;
}


static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname,
			 void __user *optval,unsigned int optlen)
{
	func_enter ();
	func_exit ();
	return 0;
}


static void fs_phy_put(struct atm_dev *dev,unsigned char value,
		       unsigned long addr)
{
	func_enter ();
	func_exit ();
}


static unsigned char fs_phy_get(struct atm_dev *dev,unsigned long addr)
{
	func_enter ();
	func_exit ();
	return 0;
}


static int fs_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flags)
{
	func_enter ();
	func_exit ();
	return 0;
};

#endif


static const struct atmdev_ops ops = {
	.open =         fs_open,
	.close =        fs_close,
	.send =         fs_send,
	.owner =        THIS_MODULE,
	/* ioctl:          fs_ioctl, */
	/* getsockopt:     fs_getsockopt, */
	/* setsockopt:     fs_setsockopt, */
	/* change_qos:     fs_change_qos, */

	/* For now implement these internally here... */  
	/* phy_put:        fs_phy_put, */
	/* phy_get:        fs_phy_get, */
};


static void undocumented_pci_fix(struct pci_dev *pdev)
{
	u32 tint;

	/* The Windows driver says: */
	/* Switch off FireStream Retry Limit Threshold 
	 */

	/* The register at 0x28 is documented as "reserved", no further
	   comments. */

	pci_read_config_dword (pdev, 0x28, &tint);
	if (tint != 0x80) {
		tint = 0x80;
		pci_write_config_dword (pdev, 0x28, tint);
	}
}



/**************************************************************************
 *                              PHY routines                              *
 **************************************************************************/

static void write_phy(struct fs_dev *dev, int regnum, int val)
{
	submit_command (dev,  &dev->hp_txq, QE_CMD_PRP_WR | QE_CMD_IMM_INQ,
			regnum, val, 0);
}

static int init_phy(struct fs_dev *dev, struct reginit_item *reginit)
{
	int i;

	func_enter ();
	while (reginit->reg != PHY_EOF) {
		if (reginit->reg == PHY_CLEARALL) {
			/* "PHY_CLEARALL means clear all registers. Numregisters is in "val". */
			for (i=0;i<reginit->val;i++) {
				write_phy (dev, i, 0);
			}
		} else {
			write_phy (dev, reginit->reg, reginit->val);
		}
		reginit++;
	}
	func_exit ();
	return 0;
}

static void reset_chip (struct fs_dev *dev)
{
	int i;

	write_fs (dev, SARMODE0, SARMODE0_SRTS0);

	/* Undocumented delay */
	udelay (128);

	/* The "internal registers are documented to all reset to zero, but 
	   comments & code in the Windows driver indicates that the pools are
	   NOT reset. */
	for (i=0;i < FS_NR_FREE_POOLS;i++) {
		write_fs (dev, FP_CNF (RXB_FP(i)), 0);
		write_fs (dev, FP_SA  (RXB_FP(i)), 0);
		write_fs (dev, FP_EA  (RXB_FP(i)), 0);
		write_fs (dev, FP_CNT (RXB_FP(i)), 0);
		write_fs (dev, FP_CTU (RXB_FP(i)), 0);
	}

	/* The same goes for the match channel registers, although those are
	   NOT documented that way in the Windows driver. -- REW */
	/* The Windows driver DOES write 0 to these registers somewhere in
	   the init sequence. However, a small hardware-feature, will
	   prevent reception of data on VPI/VCI = 0/0 (Unless the channel
	   allocated happens to have no disabled channels that have a lower
	   number. -- REW */

	/* Clear the match channel registers. */
	if (IS_FS50 (dev)) {
		for (i=0;i<FS50_NR_CHANNELS;i++) {
			write_fs (dev, 0x200 + i * 4, -1);
		}
	}
}

static void *aligned_kmalloc(int size, gfp_t flags, int alignment)
{
	void  *t;

	if (alignment <= 0x10) {
		t = kmalloc (size, flags);
		if ((unsigned long)t & (alignment-1)) {
			printk ("Kmalloc doesn't align things correctly! %p\n", t);
			kfree (t);
			return aligned_kmalloc (size, flags, alignment * 4);
		}
		return t;
	}
	printk (KERN_ERR "Request for > 0x10 alignment not yet implemented (hard!)\n");
	return NULL;
}

static int init_q(struct fs_dev *dev, struct queue *txq, int queue,
		  int nentries, int is_rq)
{
	int sz = nentries * sizeof (struct FS_QENTRY);
	struct FS_QENTRY *p;

	func_enter ();

	fs_dprintk (FS_DEBUG_INIT, "Inititing queue at %x: %d entries:\n", 
		    queue, nentries);

	p = aligned_kmalloc (sz, GFP_KERNEL, 0x10);
	fs_dprintk (FS_DEBUG_ALLOC, "Alloc queue: %p(%d)\n", p, sz);

	if (!p) return 0;

	write_fs (dev, Q_SA(queue), virt_to_bus(p));
	write_fs (dev, Q_EA(queue), virt_to_bus(p+nentries-1));
	write_fs (dev, Q_WP(queue), virt_to_bus(p));
	write_fs (dev, Q_RP(queue), virt_to_bus(p));
	if (is_rq) {
		/* Configuration for the receive queue: 0: interrupt immediately,
		   no pre-warning to empty queues: We do our best to keep the
		   queue filled anyway. */
		write_fs (dev, Q_CNF(queue), 0 ); 
	}

	txq->sa = p;
	txq->ea = p;
	txq->offset = queue; 

	func_exit ();
	return 1;
}


static int init_fp(struct fs_dev *dev, struct freepool *fp, int queue,
		   int bufsize, int nr_buffers)
{
	func_enter ();

	fs_dprintk (FS_DEBUG_INIT, "Inititing free pool at %x:\n", queue);

	write_fs (dev, FP_CNF(queue), (bufsize * RBFP_RBS) | RBFP_RBSVAL | RBFP_CME);
	write_fs (dev, FP_SA(queue),  0);
	write_fs (dev, FP_EA(queue),  0);
	write_fs (dev, FP_CTU(queue), 0);
	write_fs (dev, FP_CNT(queue), 0);

	fp->offset = queue; 
	fp->bufsize = bufsize;
	fp->nr_buffers = nr_buffers;

	func_exit ();
	return 1;
}


static inline int nr_buffers_in_freepool (struct fs_dev *dev, struct freepool *fp)
{
#if 0
	/* This seems to be unreliable.... */
	return read_fs (dev, FP_CNT (fp->offset));
#else
	return fp->n;
#endif
}


/* Check if this gets going again if a pool ever runs out.  -- Yes, it
   does. I've seen "receive abort: no buffers" and things started
   working again after that...  -- REW */

static void top_off_fp (struct fs_dev *dev, struct freepool *fp,
			gfp_t gfp_flags)
{
	struct FS_BPENTRY *qe, *ne;
	struct sk_buff *skb;
	int n = 0;
	u32 qe_tmp;

	fs_dprintk (FS_DEBUG_QUEUE, "Topping off queue at %x (%d-%d/%d)\n", 
		    fp->offset, read_fs (dev, FP_CNT (fp->offset)), fp->n, 
		    fp->nr_buffers);
	while (nr_buffers_in_freepool(dev, fp) < fp->nr_buffers) {

		skb = alloc_skb (fp->bufsize, gfp_flags);
		fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-skb: %p(%d)\n", skb, fp->bufsize);
		if (!skb) break;
		ne = kmalloc (sizeof (struct FS_BPENTRY), gfp_flags);
		fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-d: %p(%Zd)\n", ne, sizeof (struct FS_BPENTRY));
		if (!ne) {
			fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", skb);
			dev_kfree_skb_any (skb);
			break;
		}

		fs_dprintk (FS_DEBUG_QUEUE, "Adding skb %p desc %p -> %p(%p) ", 
			    skb, ne, skb->data, skb->head);
		n++;
		ne->flags = FP_FLAGS_EPI | fp->bufsize;
		ne->next  = virt_to_bus (NULL);
		ne->bsa   = virt_to_bus (skb->data);
		ne->aal_bufsize = fp->bufsize;
		ne->skb = skb;
		ne->fp = fp;

		/*
		 * FIXME: following code encodes and decodes
		 * machine pointers (could be 64-bit) into a
		 * 32-bit register.
		 */

		qe_tmp = read_fs (dev, FP_EA(fp->offset));
		fs_dprintk (FS_DEBUG_QUEUE, "link at %x\n", qe_tmp);
		if (qe_tmp) {
			qe = bus_to_virt ((long) qe_tmp);
			qe->next = virt_to_bus(ne);
			qe->flags &= ~FP_FLAGS_EPI;
		} else
			write_fs (dev, FP_SA(fp->offset), virt_to_bus(ne));

		write_fs (dev, FP_EA(fp->offset), virt_to_bus (ne));
		fp->n++;   /* XXX Atomic_inc? */
		write_fs (dev, FP_CTU(fp->offset), 1);
	}

	fs_dprintk (FS_DEBUG_QUEUE, "Added %d entries. \n", n);
}

static void free_queue(struct fs_dev *dev, struct queue *txq)
{
	func_enter ();

	write_fs (dev, Q_SA(txq->offset), 0);
	write_fs (dev, Q_EA(txq->offset), 0);
	write_fs (dev, Q_RP(txq->offset), 0);
	write_fs (dev, Q_WP(txq->offset), 0);
	/* Configuration ? */

	fs_dprintk (FS_DEBUG_ALLOC, "Free queue: %p\n", txq->sa);
	kfree (txq->sa);

	func_exit ();
}

static void free_freepool(struct fs_dev *dev, struct freepool *fp)
{
	func_enter ();

	write_fs (dev, FP_CNF(fp->offset), 0);
	write_fs (dev, FP_SA (fp->offset), 0);
	write_fs (dev, FP_EA (fp->offset), 0);
	write_fs (dev, FP_CNT(fp->offset), 0);
	write_fs (dev, FP_CTU(fp->offset), 0);

	func_exit ();
}



static irqreturn_t fs_irq (int irq, void *dev_id) 
{
	int i;
	u32 status;
	struct fs_dev *dev = dev_id;

	status = read_fs (dev, ISR);
	if (!status)
		return IRQ_NONE;

	func_enter ();

#ifdef IRQ_RATE_LIMIT
	/* Aaargh! I'm ashamed. This costs more lines-of-code than the actual 
	   interrupt routine!. (Well, used to when I wrote that comment) -- REW */
	{
		static int lastjif;
		static int nintr=0;
    
		if (lastjif == jiffies) {
			if (++nintr > IRQ_RATE_LIMIT) {
				free_irq (dev->irq, dev_id);
				printk (KERN_ERR "fs: Too many interrupts. Turning off interrupt %d.\n", 
					dev->irq);
			}
		} else {
			lastjif = jiffies;
			nintr = 0;
		}
	}
#endif
	fs_dprintk (FS_DEBUG_QUEUE, "in intr: txq %d txrq %d\n", 
		    read_fs (dev, Q_EA (dev->hp_txq.offset)) -
		    read_fs (dev, Q_SA (dev->hp_txq.offset)),
		    read_fs (dev, Q_EA (dev->tx_relq.offset)) -
		    read_fs (dev, Q_SA (dev->tx_relq.offset)));

	/* print the bits in the ISR register. */
	if (fs_debug & FS_DEBUG_IRQ) {
		/* The FS_DEBUG things are unnecessary here. But this way it is
		   clear for grep that these are debug prints. */
		fs_dprintk (FS_DEBUG_IRQ,  "IRQ status:");
		for (i=0;i<27;i++) 
			if (status & (1 << i)) 
				fs_dprintk (FS_DEBUG_IRQ, " %s", irq_bitname[i]);
		fs_dprintk (FS_DEBUG_IRQ, "\n");
	}
  
	if (status & ISR_RBRQ0_W) {
		fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (0)!!!!\n");
		process_incoming (dev, &dev->rx_rq[0]);
		/* items mentioned on RBRQ0 are from FP 0 or 1. */
		top_off_fp (dev, &dev->rx_fp[0], GFP_ATOMIC);
		top_off_fp (dev, &dev->rx_fp[1], GFP_ATOMIC);
	}

	if (status & ISR_RBRQ1_W) {
		fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (1)!!!!\n");
		process_incoming (dev, &dev->rx_rq[1]);
		top_off_fp (dev, &dev->rx_fp[2], GFP_ATOMIC);
		top_off_fp (dev, &dev->rx_fp[3], GFP_ATOMIC);
	}

	if (status & ISR_RBRQ2_W) {
		fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (2)!!!!\n");
		process_incoming (dev, &dev->rx_rq[2]);
		top_off_fp (dev, &dev->rx_fp[4], GFP_ATOMIC);
		top_off_fp (dev, &dev->rx_fp[5], GFP_ATOMIC);
	}

	if (status & ISR_RBRQ3_W) {
		fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (3)!!!!\n");
		process_incoming (dev, &dev->rx_rq[3]);
		top_off_fp (dev, &dev->rx_fp[6], GFP_ATOMIC);
		top_off_fp (dev, &dev->rx_fp[7], GFP_ATOMIC);
	}

	if (status & ISR_CSQ_W) {
		fs_dprintk (FS_DEBUG_IRQ, "Command executed ok!\n");
		process_return_queue (dev, &dev->st_q);
	}

	if (status & ISR_TBRQ_W) {
		fs_dprintk (FS_DEBUG_IRQ, "Data tramsitted!\n");
		process_txdone_queue (dev, &dev->tx_relq);
	}

	func_exit ();
	return IRQ_HANDLED;
}


#ifdef FS_POLL_FREQ
static void fs_poll (unsigned long data)
{
	struct fs_dev *dev = (struct fs_dev *) data;
  
	fs_irq (0, dev);
	dev->timer.expires = jiffies + FS_POLL_FREQ;
	add_timer (&dev->timer);
}
#endif

static int fs_init(struct fs_dev *dev)
{
	struct pci_dev  *pci_dev;
	int isr, to;
	int i;

	func_enter ();
	pci_dev = dev->pci_dev;

	printk (KERN_INFO "found a FireStream %d card, base %16llx, irq%d.\n",
		IS_FS50(dev)?50:155,
		(unsigned long long)pci_resource_start(pci_dev, 0),
		dev->pci_dev->irq);

	if (fs_debug & FS_DEBUG_INIT)
		my_hd ((unsigned char *) dev, sizeof (*dev));

	undocumented_pci_fix (pci_dev);

	dev->hw_base = pci_resource_start(pci_dev, 0);

	dev->base = ioremap(dev->hw_base, 0x1000);

	reset_chip (dev);
  
	write_fs (dev, SARMODE0, 0 
		  | (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
		  | (1 * SARMODE0_INTMODE_READCLEAR)
		  | (1 * SARMODE0_CWRE)
		  | (IS_FS50(dev) ? SARMODE0_PRPWT_FS50_5:
			  SARMODE0_PRPWT_FS155_3)
		  | (1 * SARMODE0_CALSUP_1)
		  | (IS_FS50(dev) ? (0
				   | SARMODE0_RXVCS_32
				   | SARMODE0_ABRVCS_32 
				   | SARMODE0_TXVCS_32):
		                  (0
				   | SARMODE0_RXVCS_1k
				   | SARMODE0_ABRVCS_1k 
				   | SARMODE0_TXVCS_1k)));

	/* 10ms * 100 is 1 second. That should be enough, as AN3:9 says it takes
	   1ms. */
	to = 100;
	while (--to) {
		isr = read_fs (dev, ISR);

		/* This bit is documented as "RESERVED" */
		if (isr & ISR_INIT_ERR) {
			printk (KERN_ERR "Error initializing the FS... \n");
			goto unmap;
		}
		if (isr & ISR_INIT) {
			fs_dprintk (FS_DEBUG_INIT, "Ha! Initialized OK!\n");
			break;
		}

		/* Try again after 10ms. */
		msleep(10);
	}

	if (!to) {
		printk (KERN_ERR "timeout initializing the FS... \n");
		goto unmap;
	}

	/* XXX fix for fs155 */
	dev->channel_mask = 0x1f; 
	dev->channo = 0;

	/* AN3: 10 */
	write_fs (dev, SARMODE1, 0 
		  | (fs_keystream * SARMODE1_DEFHEC) /* XXX PHY */
		  | ((loopback == 1) * SARMODE1_TSTLP) /* XXX Loopback mode enable... */
		  | (1 * SARMODE1_DCRM)
		  | (1 * SARMODE1_DCOAM)
		  | (0 * SARMODE1_OAMCRC)
		  | (0 * SARMODE1_DUMPE)
		  | (0 * SARMODE1_GPLEN) 
		  | (0 * SARMODE1_GNAM)
		  | (0 * SARMODE1_GVAS)
		  | (0 * SARMODE1_GPAS)
		  | (1 * SARMODE1_GPRI)
		  | (0 * SARMODE1_PMS)
		  | (0 * SARMODE1_GFCR)
		  | (1 * SARMODE1_HECM2)
		  | (1 * SARMODE1_HECM1)
		  | (1 * SARMODE1_HECM0)
		  | (1 << 12) /* That's what hang's driver does. Program to 0 */
		  | (0 * 0xff) /* XXX FS155 */);


	/* Cal prescale etc */

	/* AN3: 11 */
	write_fs (dev, TMCONF, 0x0000000f);
	write_fs (dev, CALPRESCALE, 0x01010101 * num);
	write_fs (dev, 0x80, 0x000F00E4);

	/* AN3: 12 */
	write_fs (dev, CELLOSCONF, 0
		  | (   0 * CELLOSCONF_CEN)
		  | (       CELLOSCONF_SC1)
		  | (0x80 * CELLOSCONF_COBS)
		  | (num  * CELLOSCONF_COPK)  /* Changed from 0xff to 0x5a */
		  | (num  * CELLOSCONF_COST));/* after a hint from Hang. 
					       * performance jumped 50->70... */

	/* Magic value by Hang */
	write_fs (dev, CELLOSCONF_COST, 0x0B809191);

	if (IS_FS50 (dev)) {
		write_fs (dev, RAS0, RAS0_DCD_XHLT);
		dev->atm_dev->ci_range.vpi_bits = 12;
		dev->atm_dev->ci_range.vci_bits = 16;
		dev->nchannels = FS50_NR_CHANNELS;
	} else {
		write_fs (dev, RAS0, RAS0_DCD_XHLT 
			  | (((1 << FS155_VPI_BITS) - 1) * RAS0_VPSEL)
			  | (((1 << FS155_VCI_BITS) - 1) * RAS0_VCSEL));
		/* We can chose the split arbitrarily. We might be able to 
		   support more. Whatever. This should do for now. */
		dev->atm_dev->ci_range.vpi_bits = FS155_VPI_BITS;
		dev->atm_dev->ci_range.vci_bits = FS155_VCI_BITS;
    
		/* Address bits we can't use should be compared to 0. */
		write_fs (dev, RAC, 0);

		/* Manual (AN9, page 6) says ASF1=0 means compare Utopia address
		 * too.  I can't find ASF1 anywhere. Anyway, we AND with just the
		 * other bits, then compare with 0, which is exactly what we
		 * want. */
		write_fs (dev, RAM, (1 << (28 - FS155_VPI_BITS - FS155_VCI_BITS)) - 1);
		dev->nchannels = FS155_NR_CHANNELS;
	}
	dev->atm_vccs = kcalloc (dev->nchannels, sizeof (struct atm_vcc *),
				 GFP_KERNEL);
	fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%Zd)\n",
		    dev->atm_vccs, dev->nchannels * sizeof (struct atm_vcc *));

	if (!dev->atm_vccs) {
		printk (KERN_WARNING "Couldn't allocate memory for VCC buffers. Woops!\n");
		/* XXX Clean up..... */
		goto unmap;
	}

	dev->tx_inuse = kzalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);
	fs_dprintk (FS_DEBUG_ALLOC, "Alloc tx_inuse: %p(%d)\n", 
		    dev->atm_vccs, dev->nchannels / 8);

	if (!dev->tx_inuse) {
		printk (KERN_WARNING "Couldn't allocate memory for tx_inuse bits!\n");
		/* XXX Clean up..... */
		goto unmap;
	}
	/* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */
	/* -- RAS2 : FS50 only: Default is OK. */

	/* DMAMODE, default should be OK. -- REW */
	write_fs (dev, DMAMR, DMAMR_TX_MODE_FULL);

	init_q (dev, &dev->hp_txq, TX_PQ(TXQ_HP), TXQ_NENTRIES, 0);
	init_q (dev, &dev->lp_txq, TX_PQ(TXQ_LP), TXQ_NENTRIES, 0);
	init_q (dev, &dev->tx_relq, TXB_RQ, TXQ_NENTRIES, 1);
	init_q (dev, &dev->st_q, ST_Q, TXQ_NENTRIES, 1);

	for (i=0;i < FS_NR_FREE_POOLS;i++) {
		init_fp (dev, &dev->rx_fp[i], RXB_FP(i), 
			 rx_buf_sizes[i], rx_pool_sizes[i]);
		top_off_fp (dev, &dev->rx_fp[i], GFP_KERNEL);
	}


	for (i=0;i < FS_NR_RX_QUEUES;i++)
		init_q (dev, &dev->rx_rq[i], RXB_RQ(i), RXRQ_NENTRIES, 1);

	dev->irq = pci_dev->irq;
	if (request_irq (dev->irq, fs_irq, IRQF_SHARED, "firestream", dev)) {
		printk (KERN_WARNING "couldn't get irq %d for firestream.\n", pci_dev->irq);
		/* XXX undo all previous stuff... */
		goto unmap;
	}
	fs_dprintk (FS_DEBUG_INIT, "Grabbed irq %d for dev at %p.\n", dev->irq, dev);
  
	/* We want to be notified of most things. Just the statistics count
	   overflows are not interesting */
	write_fs (dev, IMR, 0
		  | ISR_RBRQ0_W 
		  | ISR_RBRQ1_W 
		  | ISR_RBRQ2_W 
		  | ISR_RBRQ3_W 
		  | ISR_TBRQ_W
		  | ISR_CSQ_W);

	write_fs (dev, SARMODE0, 0 
		  | (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
		  | (1 * SARMODE0_GINT)
		  | (1 * SARMODE0_INTMODE_READCLEAR)
		  | (0 * SARMODE0_CWRE)
		  | (IS_FS50(dev)?SARMODE0_PRPWT_FS50_5: 
		                  SARMODE0_PRPWT_FS155_3)
		  | (1 * SARMODE0_CALSUP_1)
		  | (IS_FS50 (dev)?(0
				    | SARMODE0_RXVCS_32
				    | SARMODE0_ABRVCS_32 
				    | SARMODE0_TXVCS_32):
		                   (0
				    | SARMODE0_RXVCS_1k
				    | SARMODE0_ABRVCS_1k 
				    | SARMODE0_TXVCS_1k))
		  | (1 * SARMODE0_RUN));

	init_phy (dev, PHY_NTC_INIT);

	if (loopback == 2) {
		write_phy (dev, 0x39, 0x000e);
	}

#ifdef FS_POLL_FREQ
	init_timer (&dev->timer);
	dev->timer.data = (unsigned long) dev;
	dev->timer.function = fs_poll;
	dev->timer.expires = jiffies + FS_POLL_FREQ;
	add_timer (&dev->timer);
#endif

	dev->atm_dev->dev_data = dev;
  
	func_exit ();
	return 0;
unmap:
	iounmap(dev->base);
	return 1;
}

static int firestream_init_one(struct pci_dev *pci_dev,
			       const struct pci_device_id *ent)
{
	struct atm_dev *atm_dev;
	struct fs_dev *fs_dev;
	
	if (pci_enable_device(pci_dev)) 
		goto err_out;

	fs_dev = kzalloc (sizeof (struct fs_dev), GFP_KERNEL);
	fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%Zd)\n",
		    fs_dev, sizeof (struct fs_dev));
	if (!fs_dev)
		goto err_out;
	atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL);
	if (!atm_dev)
		goto err_out_free_fs_dev;
  
	fs_dev->pci_dev = pci_dev;
	fs_dev->atm_dev = atm_dev;
	fs_dev->flags = ent->driver_data;

	if (fs_init(fs_dev))
		goto err_out_free_atm_dev;

	fs_dev->next = fs_boards;
	fs_boards = fs_dev;
	return 0;

 err_out_free_atm_dev:
	atm_dev_deregister(atm_dev);
 err_out_free_fs_dev:
 	kfree(fs_dev);
 err_out:
	return -ENODEV;
}

static void firestream_remove_one(struct pci_dev *pdev)
{
	int i;
	struct fs_dev *dev, *nxtdev;
	struct fs_vcc *vcc;
	struct FS_BPENTRY *fp, *nxt;
  
	func_enter ();

#if 0
	printk ("hptxq:\n");
	for (i=0;i<60;i++) {
		printk ("%d: %08x %08x %08x %08x \n", 
			i, pq[qp].cmd, pq[qp].p0, pq[qp].p1, pq[qp].p2);
		qp++;
		if (qp >= 60) qp = 0;
	}

	printk ("descriptors:\n");
	for (i=0;i<60;i++) {
		printk ("%d: %p: %08x %08x %p %p\n", 
			i, da[qd], dq[qd].flags, dq[qd].bsa, dq[qd].skb, dq[qd].dev);
		qd++;
		if (qd >= 60) qd = 0;
	}
#endif

	for (dev = fs_boards;dev != NULL;dev=nxtdev) {
		fs_dprintk (FS_DEBUG_CLEANUP, "Releasing resources for dev at %p.\n", dev);

		/* XXX Hit all the tx channels too! */

		for (i=0;i < dev->nchannels;i++) {
			if (dev->atm_vccs[i]) {
				vcc = FS_VCC (dev->atm_vccs[i]);
				submit_command (dev,  &dev->hp_txq,
						QE_CMD_TX_PURGE_INH | QE_CMD_IMM_INQ | vcc->channo, 0,0,0);
				submit_command (dev,  &dev->hp_txq,
						QE_CMD_RX_PURGE_INH | QE_CMD_IMM_INQ | vcc->channo, 0,0,0);

			}
		}

		/* XXX Wait a while for the chip to release all buffers. */

		for (i=0;i < FS_NR_FREE_POOLS;i++) {
			for (fp=bus_to_virt (read_fs (dev, FP_SA(dev->rx_fp[i].offset)));
			     !(fp->flags & FP_FLAGS_EPI);fp = nxt) {
				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", fp->skb);
				dev_kfree_skb_any (fp->skb);
				nxt = bus_to_virt (fp->next);
				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", fp);
				kfree (fp);
			}
			fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", fp->skb);
			dev_kfree_skb_any (fp->skb);
			fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", fp);
			kfree (fp);
		}

		/* Hang the chip in "reset", prevent it clobbering memory that is
		   no longer ours. */
		reset_chip (dev);

		fs_dprintk (FS_DEBUG_CLEANUP, "Freeing irq%d.\n", dev->irq);
		free_irq (dev->irq, dev);
		del_timer_sync (&dev->timer);

		atm_dev_deregister(dev->atm_dev);
		free_queue (dev, &dev->hp_txq);
		free_queue (dev, &dev->lp_txq);
		free_queue (dev, &dev->tx_relq);
		free_queue (dev, &dev->st_q);

		fs_dprintk (FS_DEBUG_ALLOC, "Free atmvccs: %p\n", dev->atm_vccs);
		kfree (dev->atm_vccs);

		for (i=0;i< FS_NR_FREE_POOLS;i++)
			free_freepool (dev, &dev->rx_fp[i]);
    
		for (i=0;i < FS_NR_RX_QUEUES;i++)
			free_queue (dev, &dev->rx_rq[i]);

		iounmap(dev->base);
		fs_dprintk (FS_DEBUG_ALLOC, "Free fs-dev: %p\n", dev);
		nxtdev = dev->next;
		kfree (dev);
	}

	func_exit ();
}

static struct pci_device_id firestream_pci_tbl[] = {
	{ PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50), FS_IS50},
	{ PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155), FS_IS155},
	{ 0, }
};

MODULE_DEVICE_TABLE(pci, firestream_pci_tbl);

static struct pci_driver firestream_driver = {
	.name		= "firestream",
	.id_table	= firestream_pci_tbl,
	.probe		= firestream_init_one,
	.remove		= firestream_remove_one,
};

static int __init firestream_init_module (void)
{
	int error;

	func_enter ();
	error = pci_register_driver(&firestream_driver);
	func_exit ();
	return error;
}

static void __exit firestream_cleanup_module(void)
{
	pci_unregister_driver(&firestream_driver);
}

module_init(firestream_init_module);
module_exit(firestream_cleanup_module);

MODULE_LICENSE("GPL");



