/*      cops.c: LocalTalk driver for Linux.
 *
 *	Authors:
 *      - Jay Schulist <jschlst@samba.org>
 *
 *	With more than a little help from;
 *	- Alan Cox <alan@lxorguk.ukuu.org.uk>
 *
 *      Derived from:
 *      - skeleton.c: A network driver outline for linux.
 *        Written 1993-94 by Donald Becker.
 *	- ltpc.c: A driver for the LocalTalk PC card.
 *	  Written by Bradford W. Johnson.
 *
 *      Copyright 1993 United States Government as represented by the
 *      Director, National Security Agency.
 *
 *      This software may be used and distributed according to the terms
 *      of the GNU General Public License, incorporated herein by reference.
 *
 *	Changes:
 *	19970608	Alan Cox	Allowed dual card type support
 *					Can set board type in insmod
 *					Hooks for cops_setup routine
 *					(not yet implemented).
 *	19971101	Jay Schulist	Fixes for multiple lt* devices.
 *	19980607	Steven Hirsch	Fixed the badly broken support
 *					for Tangent type cards. Only
 *                                      tested on Daystar LT200. Some
 *                                      cleanup of formatting and program
 *                                      logic.  Added emacs 'local-vars'
 *                                      setup for Jay's brace style.
 *	20000211	Alan Cox	Cleaned up for softnet
 */

static const char *version =
"cops.c:v0.04 6/7/98 Jay Schulist <jschlst@samba.org>\n";
/*
 *  Sources:
 *      COPS Localtalk SDK. This provides almost all of the information
 *      needed.
 */

/*
 * insmod/modprobe configurable stuff.
 *	- IO Port, choose one your card supports or 0 if you dare.
 *	- IRQ, also choose one your card supports or nothing and let
 *	  the driver figure it out.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/if_ltalk.h>
#include <linux/delay.h>	/* For udelay() */
#include <linux/atalk.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>

#include <asm/io.h>
#include <asm/dma.h>

#include "cops.h"		/* Our Stuff */
#include "cops_ltdrv.h"		/* Firmware code for Tangent type cards. */
#include "cops_ffdrv.h"		/* Firmware code for Dayna type cards. */

/*
 *      The name of the card. Is used for messages and in the requests for
 *      io regions, irqs and dma channels
 */

static const char *cardname = "cops";

#ifdef CONFIG_COPS_DAYNA
static int board_type = DAYNA;	/* Module exported */
#else
static int board_type = TANGENT;
#endif

static int io = 0x240;		/* Default IO for Dayna */
static int irq = 5;		/* Default IRQ */

/*
 *	COPS Autoprobe information.
 *	Right now if port address is right but IRQ is not 5 this will
 *      return a 5 no matter what since we will still get a status response.
 *      Need one more additional check to narrow down after we have gotten
 *      the ioaddr. But since only other possible IRQs is 3 and 4 so no real
 *	hurry on this. I *STRONGLY* recommend using IRQ 5 for your card with
 *	this driver.
 * 
 *	This driver has 2 modes and they are: Dayna mode and Tangent mode.
 *	Each mode corresponds with the type of card. It has been found
 *	that there are 2 main types of cards and all other cards are
 *	the same and just have different names or only have minor differences
 *	such as more IO ports. As this driver is tested it will
 *	become more clear on exactly what cards are supported. The driver
 *	defaults to using Dayna mode. To change the drivers mode, simply
 *	select Dayna or Tangent mode when configuring the kernel.
 *
 *      This driver should support:
 *      TANGENT driver mode:
 *              Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200,
 *		COPS LT-1
 *      DAYNA driver mode:
 *              Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, 
 *		Farallon PhoneNET PC III, Farallon PhoneNET PC II
 *	Other cards possibly supported mode unknown though:
 *		Dayna DL2000 (Full length), COPS LT/M (Micro-Channel)
 *
 *	Cards NOT supported by this driver but supported by the ltpc.c
 *	driver written by Bradford W. Johnson <johns393@maroon.tc.umn.edu>
 *		Farallon PhoneNET PC
 *		Original Apple LocalTalk PC card
 * 
 *      N.B.
 *
 *      The Daystar Digital LT200 boards do not support interrupt-driven
 *      IO.  You must specify 'irq=0xff' as a module parameter to invoke
 *      polled mode.  I also believe that the port probing logic is quite
 *      dangerous at best and certainly hopeless for a polled card.  Best to 
 *      specify both. - Steve H.
 *
 */

/*
 * Zero terminated list of IO ports to probe.
 */

static unsigned int ports[] = { 
	0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260, 
	0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360,
	0
};

/*
 * Zero terminated list of IRQ ports to probe.
 */

static int cops_irqlist[] = {
	5, 4, 3, 0 
};

static struct timer_list cops_timer;
static struct net_device *cops_timer_dev;

/* use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */
#ifndef COPS_DEBUG
#define COPS_DEBUG 1 
#endif
static unsigned int cops_debug = COPS_DEBUG;

/* The number of low I/O ports used by the card. */
#define COPS_IO_EXTENT       8

/* Information that needs to be kept for each board. */

struct cops_local
{
        int board;			/* Holds what board type is. */
	int nodeid;			/* Set to 1 once have nodeid. */
        unsigned char node_acquire;	/* Node ID when acquired. */
        struct atalk_addr node_addr;	/* Full node address */
	spinlock_t lock;		/* RX/TX lock */
};

/* Index to functions, as function prototypes. */
static int  cops_probe1 (struct net_device *dev, int ioaddr);
static int  cops_irq (int ioaddr, int board);

static int  cops_open (struct net_device *dev);
static int  cops_jumpstart (struct net_device *dev);
static void cops_reset (struct net_device *dev, int sleep);
static void cops_load (struct net_device *dev);
static int  cops_nodeid (struct net_device *dev, int nodeid);

static irqreturn_t cops_interrupt (int irq, void *dev_id);
static void cops_poll(struct timer_list *t);
static void cops_timeout(struct net_device *dev);
static void cops_rx (struct net_device *dev);
static netdev_tx_t  cops_send_packet (struct sk_buff *skb,
					    struct net_device *dev);
static void set_multicast_list (struct net_device *dev);
static int  cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int  cops_close (struct net_device *dev);

static void cleanup_card(struct net_device *dev)
{
	if (dev->irq)
		free_irq(dev->irq, dev);
	release_region(dev->base_addr, COPS_IO_EXTENT);
}

/*
 *      Check for a network adaptor of this type, and return '0' iff one exists.
 *      If dev->base_addr == 0, probe all likely locations.
 *      If dev->base_addr in [1..0x1ff], always return failure.
 *        otherwise go with what we pass in.
 */
struct net_device * __init cops_probe(int unit)
{
	struct net_device *dev;
	unsigned *port;
	int base_addr;
	int err = 0;

	dev = alloc_ltalkdev(sizeof(struct cops_local));
	if (!dev)
		return ERR_PTR(-ENOMEM);

	if (unit >= 0) {
		sprintf(dev->name, "lt%d", unit);
		netdev_boot_setup_check(dev);
		irq = dev->irq;
		base_addr = dev->base_addr;
	} else {
		base_addr = dev->base_addr = io;
	}

	if (base_addr > 0x1ff) {    /* Check a single specified location. */
		err = cops_probe1(dev, base_addr);
	} else if (base_addr != 0) { /* Don't probe at all. */
		err = -ENXIO;
	} else {
		/* FIXME  Does this really work for cards which generate irq?
		 * It's definitely N.G. for polled Tangent. sh
		 * Dayna cards don't autoprobe well at all, but if your card is
		 * at IRQ 5 & IO 0x240 we find it every time. ;) JS
		 */
		for (port = ports; *port && cops_probe1(dev, *port) < 0; port++)
			;
		if (!*port)
			err = -ENODEV;
	}
	if (err)
		goto out;
	err = register_netdev(dev);
	if (err)
		goto out1;
	return dev;
out1:
	cleanup_card(dev);
out:
	free_netdev(dev);
	return ERR_PTR(err);
}

static const struct net_device_ops cops_netdev_ops = {
	.ndo_open               = cops_open,
        .ndo_stop               = cops_close,
	.ndo_start_xmit   	= cops_send_packet,
	.ndo_tx_timeout		= cops_timeout,
        .ndo_do_ioctl           = cops_ioctl,
	.ndo_set_rx_mode	= set_multicast_list,
};

/*
 *      This is the real probe routine. Linux has a history of friendly device
 *      probes on the ISA bus. A good device probes avoids doing writes, and
 *      verifies that the correct device exists and functions.
 */
static int __init cops_probe1(struct net_device *dev, int ioaddr)
{
        struct cops_local *lp;
	static unsigned version_printed;
	int board = board_type;
	int retval;
	
        if(cops_debug && version_printed++ == 0)
		printk("%s", version);

	/* Grab the region so no one else tries to probe our ioports. */
	if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name))
		return -EBUSY;

        /*
         * Since this board has jumpered interrupts, allocate the interrupt
         * vector now. There is no point in waiting since no other device
         * can use the interrupt, and this marks the irq as busy. Jumpered
         * interrupts are typically not reported by the boards, and we must
         * used AutoIRQ to find them.
	 */
	dev->irq = irq;
	switch (dev->irq)
	{
		case 0:
			/* COPS AutoIRQ routine */
			dev->irq = cops_irq(ioaddr, board);
			if (dev->irq)
				break;
			/* fall through - Once no IRQ found on this port. */
		case 1:
			retval = -EINVAL;
			goto err_out;

		/* Fixup for users that don't know that IRQ 2 is really
		 * IRQ 9, or don't know which one to set.
		 */
		case 2:
			dev->irq = 9;
			break;

		/* Polled operation requested. Although irq of zero passed as
		 * a parameter tells the init routines to probe, we'll
		 * overload it to denote polled operation at runtime.
		 */
		case 0xff:
			dev->irq = 0;
			break;

		default:
			break;
	}

	/* Reserve any actual interrupt. */
	if (dev->irq) {
		retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev);
		if (retval)
			goto err_out;
	}

	dev->base_addr = ioaddr;

        lp = netdev_priv(dev);
        spin_lock_init(&lp->lock);

	/* Copy local board variable to lp struct. */
	lp->board               = board;

	dev->netdev_ops 	= &cops_netdev_ops;
	dev->watchdog_timeo	= HZ * 2;


	/* Tell the user where the card is and what mode we're in. */
	if(board==DAYNA)
		printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n", 
			dev->name, cardname, ioaddr, dev->irq);
	if(board==TANGENT) {
		if(dev->irq)
			printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n", 
				dev->name, cardname, ioaddr, dev->irq);
		else
			printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n", 
				dev->name, cardname, ioaddr);

	}
        return 0;

err_out:
	release_region(ioaddr, COPS_IO_EXTENT);
	return retval;
}

static int __init cops_irq (int ioaddr, int board)
{       /*
         * This does not use the IRQ to determine where the IRQ is. We just
         * assume that when we get a correct status response that it's the IRQ.
         * This really just verifies the IO port but since we only have access
         * to such a small number of IRQs (5, 4, 3) this is not bad.
         * This will probably not work for more than one card.
         */
        int irqaddr=0;
        int i, x, status;

        if(board==DAYNA)
        {
                outb(0, ioaddr+DAYNA_RESET);
                inb(ioaddr+DAYNA_RESET);
                mdelay(333);
        }
        if(board==TANGENT)
        {
                inb(ioaddr);
                outb(0, ioaddr);
                outb(0, ioaddr+TANG_RESET);
        }

        for(i=0; cops_irqlist[i] !=0; i++)
        {
                irqaddr = cops_irqlist[i];
                for(x = 0xFFFF; x>0; x --)    /* wait for response */
                {
                        if(board==DAYNA)
                        {
                                status = (inb(ioaddr+DAYNA_CARD_STATUS)&3);
                                if(status == 1)
                                        return irqaddr;
                        }
                        if(board==TANGENT)
                        {
                                if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0)
                                        return irqaddr;
                        }
                }
        }
        return 0;       /* no IRQ found */
}

/*
 * Open/initialize the board. This is called (in the current kernel)
 * sometime after booting when the 'ifconfig' program is run.
 */
static int cops_open(struct net_device *dev)
{
    struct cops_local *lp = netdev_priv(dev);

	if(dev->irq==0)
	{
		/*
		 * I don't know if the Dayna-style boards support polled 
		 * operation.  For now, only allow it for Tangent.
		 */
		if(lp->board==TANGENT)	/* Poll 20 times per second */
		{
		    cops_timer_dev = dev;
		    timer_setup(&cops_timer, cops_poll, 0);
		    cops_timer.expires 	= jiffies + HZ/20;
		    add_timer(&cops_timer);
		} 
		else 
		{
			printk(KERN_WARNING "%s: No irq line set\n", dev->name);
			return -EAGAIN;
		}
	}

	cops_jumpstart(dev);	/* Start the card up. */

	netif_start_queue(dev);
        return 0;
}

/*
 *	This allows for a dynamic start/restart of the entire card.
 */
static int cops_jumpstart(struct net_device *dev)
{
	struct cops_local *lp = netdev_priv(dev);

	/*
         *      Once the card has the firmware loaded and has acquired
         *      the nodeid, if it is reset it will lose it all.
         */
        cops_reset(dev,1);	/* Need to reset card before load firmware. */
        cops_load(dev);		/* Load the firmware. */

	/*
	 *	If atalkd already gave us a nodeid we will use that
	 *	one again, else we wait for atalkd to give us a nodeid
	 *	in cops_ioctl. This may cause a problem if someone steals
	 *	our nodeid while we are resetting.
	 */	
	if(lp->nodeid == 1)
		cops_nodeid(dev,lp->node_acquire);

	return 0;
}

static void tangent_wait_reset(int ioaddr)
{
	int timeout=0;

	while(timeout++ < 5 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
		mdelay(1);   /* Wait 1 second */
}

/*
 *      Reset the LocalTalk board.
 */
static void cops_reset(struct net_device *dev, int sleep)
{
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr=dev->base_addr;

        if(lp->board==TANGENT)
        {
                inb(ioaddr);		/* Clear request latch. */
                outb(0,ioaddr);		/* Clear the TANG_TX_READY flop. */
                outb(0, ioaddr+TANG_RESET);	/* Reset the adapter. */

		tangent_wait_reset(ioaddr);
                outb(0, ioaddr+TANG_CLEAR_INT);
        }
        if(lp->board==DAYNA)
        {
                outb(0, ioaddr+DAYNA_RESET);	/* Assert the reset port */
                inb(ioaddr+DAYNA_RESET);	/* Clear the reset */
		if (sleep)
			msleep(333);
		else
			mdelay(333);
        }

	netif_wake_queue(dev);
}

static void cops_load (struct net_device *dev)
{
        struct ifreq ifr;
        struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru;
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr=dev->base_addr;
	int length, i = 0;

        strcpy(ifr.ifr_name,"lt0");

        /* Get card's firmware code and do some checks on it. */
#ifdef CONFIG_COPS_DAYNA        
        if(lp->board==DAYNA)
        {
                ltf->length=sizeof(ffdrv_code);
                ltf->data=ffdrv_code;
        }
        else
#endif        
#ifdef CONFIG_COPS_TANGENT
        if(lp->board==TANGENT)
        {
                ltf->length=sizeof(ltdrv_code);
                ltf->data=ltdrv_code;
        }
        else
#endif
	{
		printk(KERN_INFO "%s; unsupported board type.\n", dev->name);
		return;
	}
	
        /* Check to make sure firmware is correct length. */
        if(lp->board==DAYNA && ltf->length!=5983)
        {
                printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name);
                return;
        }
        if(lp->board==TANGENT && ltf->length!=2501)
        {
                printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name);
                return;
        }

        if(lp->board==DAYNA)
        {
                /*
                 *      We must wait for a status response
                 *      with the DAYNA board.
                 */
                while(++i<65536)
                {
                       if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1)
                                break;
                }

                if(i==65536)
                        return;
        }

        /*
         *      Upload the firmware and kick. Byte-by-byte works nicely here.
         */
	i=0;
        length = ltf->length;
        while(length--)
        {
                outb(ltf->data[i], ioaddr);
                i++;
        }

	if(cops_debug > 1)
		printk("%s: Uploaded firmware - %d bytes of %d bytes.\n", 
			dev->name, i, ltf->length);

        if(lp->board==DAYNA) 	/* Tell Dayna to run the firmware code. */
                outb(1, ioaddr+DAYNA_INT_CARD);
	else			/* Tell Tang to run the firmware code. */
		inb(ioaddr);

        if(lp->board==TANGENT)
        {
                tangent_wait_reset(ioaddr);
                inb(ioaddr);	/* Clear initial ready signal. */
        }
}

/*
 * 	Get the LocalTalk Nodeid from the card. We can suggest
 *	any nodeid 1-254. The card will try and get that exact
 *	address else we can specify 0 as the nodeid and the card
 *	will autoprobe for a nodeid.
 */
static int cops_nodeid (struct net_device *dev, int nodeid)
{
	struct cops_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;

	if(lp->board == DAYNA)
        {
        	/* Empty any pending adapter responses. */
                while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
                {
			outb(0, ioaddr+COPS_CLEAR_INT);	/* Clear interrupts. */
        		if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
                		cops_rx(dev);	/* Kick any packets waiting. */
			schedule();
                }

                outb(2, ioaddr);       	/* Output command packet length as 2. */
                outb(0, ioaddr);
                outb(LAP_INIT, ioaddr);	/* Send LAP_INIT command byte. */
                outb(nodeid, ioaddr);  	/* Suggest node address. */
        }

	if(lp->board == TANGENT)
        {
                /* Empty any pending adapter responses. */
                while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
                {
			outb(0, ioaddr+COPS_CLEAR_INT);	/* Clear interrupt. */
                	cops_rx(dev);          	/* Kick out packets waiting. */
			schedule();
                }

		/* Not sure what Tangent does if nodeid picked is used. */
                if(nodeid == 0)	         		/* Seed. */
                	nodeid = jiffies&0xFF;		/* Get a random try */
                outb(2, ioaddr);        		/* Command length LSB */
                outb(0, ioaddr);       			/* Command length MSB */
                outb(LAP_INIT, ioaddr); 		/* Send LAP_INIT byte */
                outb(nodeid, ioaddr); 		  	/* LAP address hint. */
                outb(0xFF, ioaddr);     		/* Int. level to use */
        }

	lp->node_acquire=0;		/* Set nodeid holder to 0. */
        while(lp->node_acquire==0)	/* Get *True* nodeid finally. */
	{
		outb(0, ioaddr+COPS_CLEAR_INT);	/* Clear any interrupt. */

		if(lp->board == DAYNA)
		{
                	if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
                		cops_rx(dev);	/* Grab the nodeid put in lp->node_acquire. */
		}
		if(lp->board == TANGENT)
		{	
			if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
                                cops_rx(dev);   /* Grab the nodeid put in lp->node_acquire. */
		}
		schedule();
	}

	if(cops_debug > 1)
		printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n", 
			dev->name, lp->node_acquire);

	lp->nodeid=1;	/* Set got nodeid to 1. */

        return 0;
}

/*
 *	Poll the Tangent type cards to see if we have work.
 */
 
static void cops_poll(struct timer_list *unused)
{
	int ioaddr, status;
	int boguscount = 0;
	struct net_device *dev = cops_timer_dev;

	del_timer(&cops_timer);

	if(dev == NULL)
		return;	/* We've been downed */

	ioaddr = dev->base_addr;
	do {
		status=inb(ioaddr+TANG_CARD_STATUS);
		if(status & TANG_RX_READY)
			cops_rx(dev);
		if(status & TANG_TX_READY)
			netif_wake_queue(dev);
		status = inb(ioaddr+TANG_CARD_STATUS);
	} while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY)));

	/* poll 20 times per second */
	cops_timer.expires = jiffies + HZ/20;
	add_timer(&cops_timer);
}

/*
 *      The typical workload of the driver:
 *      Handle the network interface interrupts.
 */
static irqreturn_t cops_interrupt(int irq, void *dev_id)
{
        struct net_device *dev = dev_id;
        struct cops_local *lp;
        int ioaddr, status;
        int boguscount = 0;

        ioaddr = dev->base_addr;
        lp = netdev_priv(dev);

	if(lp->board==DAYNA)
	{
		do {
			outb(0, ioaddr + COPS_CLEAR_INT);
                       	status=inb(ioaddr+DAYNA_CARD_STATUS);
                       	if((status&0x03)==DAYNA_RX_REQUEST)
                       	        cops_rx(dev);
                	netif_wake_queue(dev);
		} while(++boguscount < 20);
	}
	else
	{
		do {
                       	status=inb(ioaddr+TANG_CARD_STATUS);
			if(status & TANG_RX_READY)
				cops_rx(dev);
			if(status & TANG_TX_READY)
				netif_wake_queue(dev);
			status=inb(ioaddr+TANG_CARD_STATUS);
		} while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY)));
	}

        return IRQ_HANDLED;
}

/*
 *      We have a good packet(s), get it/them out of the buffers.
 */
static void cops_rx(struct net_device *dev)
{
        int pkt_len = 0;
        int rsp_type = 0;
        struct sk_buff *skb = NULL;
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        int boguscount = 0;
        unsigned long flags;


	spin_lock_irqsave(&lp->lock, flags);
	
        if(lp->board==DAYNA)
        {
                outb(0, ioaddr);                /* Send out Zero length. */
                outb(0, ioaddr);
                outb(DATA_READ, ioaddr);        /* Send read command out. */

                /* Wait for DMA to turn around. */
                while(++boguscount<1000000)
                {
			barrier();
                        if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY)
                                break;
                }

                if(boguscount==1000000)
                {
                        printk(KERN_WARNING "%s: DMA timed out.\n",dev->name);
			spin_unlock_irqrestore(&lp->lock, flags);
                        return;
                }
        }

        /* Get response length. */
	pkt_len = inb(ioaddr);
        pkt_len |= (inb(ioaddr) << 8);
        /* Input IO code. */
        rsp_type=inb(ioaddr);

        /* Malloc up new buffer. */
        skb = dev_alloc_skb(pkt_len);
        if(skb == NULL)
        {
                printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n",
			dev->name);
                dev->stats.rx_dropped++;
                while(pkt_len--)        /* Discard packet */
                        inb(ioaddr);
                spin_unlock_irqrestore(&lp->lock, flags);
                return;
        }
        skb->dev = dev;
        skb_put(skb, pkt_len);
        skb->protocol = htons(ETH_P_LOCALTALK);

        insb(ioaddr, skb->data, pkt_len);               /* Eat the Data */

        if(lp->board==DAYNA)
                outb(1, ioaddr+DAYNA_INT_CARD);         /* Interrupt the card */

        spin_unlock_irqrestore(&lp->lock, flags);  /* Restore interrupts. */

        /* Check for bad response length */
        if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE)
        {
		printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n", 
			dev->name, pkt_len);
                dev->stats.tx_errors++;
                dev_kfree_skb_any(skb);
                return;
        }

        /* Set nodeid and then get out. */
        if(rsp_type == LAP_INIT_RSP)
        {	/* Nodeid taken from received packet. */
                lp->node_acquire = skb->data[0];
                dev_kfree_skb_any(skb);
                return;
        }

        /* One last check to make sure we have a good packet. */
        if(rsp_type != LAP_RESPONSE)
        {
                printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type);
                dev->stats.tx_errors++;
                dev_kfree_skb_any(skb);
                return;
        }

        skb_reset_mac_header(skb);    /* Point to entire packet. */
        skb_pull(skb,3);
        skb_reset_transport_header(skb);    /* Point to data (Skip header). */

        /* Update the counters. */
        dev->stats.rx_packets++;
        dev->stats.rx_bytes += skb->len;

        /* Send packet to a higher place. */
        netif_rx(skb);
}

static void cops_timeout(struct net_device *dev)
{
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;

	dev->stats.tx_errors++;
        if(lp->board==TANGENT)
        {
		if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
               		printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name);
	}
	printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
	cops_jumpstart(dev);	/* Restart the card. */
	netif_trans_update(dev); /* prevent tx timeout */
	netif_wake_queue(dev);
}


/*
 *	Make the card transmit a LocalTalk packet.
 */

static netdev_tx_t cops_send_packet(struct sk_buff *skb,
					  struct net_device *dev)
{
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        unsigned long flags;

        /*
         * Block a timer-based transmit from overlapping. 
	 */
	 
	netif_stop_queue(dev);

	spin_lock_irqsave(&lp->lock, flags);
	if(lp->board == DAYNA)	 /* Wait for adapter transmit buffer. */
		while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
			cpu_relax();
	if(lp->board == TANGENT) /* Wait for adapter transmit buffer. */
		while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
			cpu_relax();

	/* Output IO length. */
	outb(skb->len, ioaddr);
	outb(skb->len >> 8, ioaddr);

	/* Output IO code. */
	outb(LAP_WRITE, ioaddr);

	if(lp->board == DAYNA)	/* Check the transmit buffer again. */
        	while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0);

	outsb(ioaddr, skb->data, skb->len);	/* Send out the data. */

	if(lp->board==DAYNA)	/* Dayna requires you kick the card */
		outb(1, ioaddr+DAYNA_INT_CARD);

	spin_unlock_irqrestore(&lp->lock, flags);	/* Restore interrupts. */

	/* Done sending packet, update counters and cleanup. */
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += skb->len;
	dev_kfree_skb (skb);
	return NETDEV_TX_OK;
}

/*
 *	Dummy function to keep the Appletalk layer happy.
 */
 
static void set_multicast_list(struct net_device *dev)
{
        if(cops_debug >= 3)
		printk("%s: set_multicast_list executed\n", dev->name);
}

/*
 *      System ioctls for the COPS LocalTalk card.
 */
 
static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
        struct cops_local *lp = netdev_priv(dev);
        struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr;
        struct atalk_addr *aa = &lp->node_addr;

        switch(cmd)
        {
                case SIOCSIFADDR:
			/* Get and set the nodeid and network # atalkd wants. */
			cops_nodeid(dev, sa->sat_addr.s_node);
			aa->s_net               = sa->sat_addr.s_net;
                        aa->s_node              = lp->node_acquire;

			/* Set broardcast address. */
                        dev->broadcast[0]       = 0xFF;
			
			/* Set hardware address. */
                        dev->dev_addr[0]        = aa->s_node;
                        dev->addr_len           = 1;
                        return 0;

                case SIOCGIFADDR:
                        sa->sat_addr.s_net      = aa->s_net;
                        sa->sat_addr.s_node     = aa->s_node;
                        return 0;

                default:
                        return -EOPNOTSUPP;
        }
}

/*
 *	The inverse routine to cops_open().
 */
 
static int cops_close(struct net_device *dev)
{
	struct cops_local *lp = netdev_priv(dev);

	/* If we were running polled, yank the timer.
	 */
	if(lp->board==TANGENT && dev->irq==0)
		del_timer(&cops_timer);

	netif_stop_queue(dev);
        return 0;
}


#ifdef MODULE
static struct net_device *cops_dev;

MODULE_LICENSE("GPL");
module_param_hw(io, int, ioport, 0);
module_param_hw(irq, int, irq, 0);
module_param_hw(board_type, int, other, 0);

static int __init cops_module_init(void)
{
	if (io == 0)
		printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
			cardname);
	cops_dev = cops_probe(-1);
	return PTR_ERR_OR_ZERO(cops_dev);
}

static void __exit cops_module_exit(void)
{
	unregister_netdev(cops_dev);
	cleanup_card(cops_dev);
	free_netdev(cops_dev);
}
module_init(cops_module_init);
module_exit(cops_module_exit);
#endif /* MODULE */
