/*
 *	Sealevel Systems 4021 driver.
 *
 *	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.
 *
 *	(c) Copyright 1999, 2001 Alan Cox
 *	(c) Copyright 2001 Red Hat Inc.
 *	Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/delay.h>
#include <linux/hdlc.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <net/arp.h>

#include <asm/irq.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/byteorder.h>
#include "z85230.h"


struct slvl_device
{
	struct z8530_channel *chan;
	int channel;
};


struct slvl_board
{
	struct slvl_device dev[2];
	struct z8530_dev board;
	int iobase;
};

/*
 *	Network driver support routines
 */

static inline struct slvl_device* dev_to_chan(struct net_device *dev)
{
	return (struct slvl_device *)dev_to_hdlc(dev)->priv;
}

/*
 *	Frame receive. Simple for our card as we do HDLC and there
 *	is no funny garbage involved
 */

static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb)
{
	/* Drop the CRC - it's not a good idea to try and negotiate it ;) */
	skb_trim(skb, skb->len - 2);
	skb->protocol = hdlc_type_trans(skb, c->netdevice);
	skb_reset_mac_header(skb);
	skb->dev = c->netdevice;
	netif_rx(skb);
	c->netdevice->last_rx = jiffies;
}

/*
 *	We've been placed in the UP state
 */

static int sealevel_open(struct net_device *d)
{
	struct slvl_device *slvl = dev_to_chan(d);
	int err = -1;
	int unit = slvl->channel;

	/*
	 *	Link layer up.
	 */

	switch (unit)
	{
		case 0:
			err = z8530_sync_dma_open(d, slvl->chan);
			break;
		case 1:
			err = z8530_sync_open(d, slvl->chan);
			break;
	}

	if (err)
		return err;

	err = hdlc_open(d);
	if (err) {
		switch (unit) {
			case 0:
				z8530_sync_dma_close(d, slvl->chan);
				break;
			case 1:
				z8530_sync_close(d, slvl->chan);
				break;
		}
		return err;
	}

	slvl->chan->rx_function = sealevel_input;

	/*
	 *	Go go go
	 */
	netif_start_queue(d);
	return 0;
}

static int sealevel_close(struct net_device *d)
{
	struct slvl_device *slvl = dev_to_chan(d);
	int unit = slvl->channel;

	/*
	 *	Discard new frames
	 */

	slvl->chan->rx_function = z8530_null_rx;

	hdlc_close(d);
	netif_stop_queue(d);

	switch (unit)
	{
		case 0:
			z8530_sync_dma_close(d, slvl->chan);
			break;
		case 1:
			z8530_sync_close(d, slvl->chan);
			break;
	}
	return 0;
}

static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
{
	/* struct slvl_device *slvl=dev_to_chan(d);
	   z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd) */
	return hdlc_ioctl(d, ifr, cmd);
}

/*
 *	Passed network frames, fire them downwind.
 */

static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d)
{
	return z8530_queue_xmit(dev_to_chan(d)->chan, skb);
}

static int sealevel_attach(struct net_device *dev, unsigned short encoding,
			   unsigned short parity)
{
	if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
		return 0;
	return -EINVAL;
}

static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
{
	struct net_device *dev = alloc_hdlcdev(sv);
	if (!dev)
		return -1;

	dev_to_hdlc(dev)->attach = sealevel_attach;
	dev_to_hdlc(dev)->xmit = sealevel_queue_xmit;
	dev->open = sealevel_open;
	dev->stop = sealevel_close;
	dev->do_ioctl = sealevel_ioctl;
	dev->base_addr = iobase;
	dev->irq = irq;

	if (register_hdlc_device(dev)) {
		printk(KERN_ERR "sealevel: unable to register HDLC device\n");
		free_netdev(dev);
		return -1;
	}

	sv->chan->netdevice = dev;
	return 0;
}


/*
 *	Allocate and setup Sealevel board.
 */

static __init struct slvl_board *slvl_init(int iobase, int irq,
					   int txdma, int rxdma, int slow)
{
	struct z8530_dev *dev;
	struct slvl_board *b;

	/*
	 *	Get the needed I/O space
	 */

	if (!request_region(iobase, 8, "Sealevel 4021")) {
		printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n",
		       iobase);
		return NULL;
	}

	b = kzalloc(sizeof(struct slvl_board), GFP_KERNEL);
	if (!b)
		goto err_kzalloc;

	b->dev[0].chan = &b->board.chanA;
	b->dev[0].channel = 0;

	b->dev[1].chan = &b->board.chanB;
	b->dev[1].channel = 1;

	dev = &b->board;

	/*
	 *	Stuff in the I/O addressing
	 */

	dev->active = 0;

	b->iobase = iobase;

	/*
	 *	Select 8530 delays for the old board
	 */

	if (slow)
		iobase |= Z8530_PORT_SLEEP;

	dev->chanA.ctrlio = iobase + 1;
	dev->chanA.dataio = iobase;
	dev->chanB.ctrlio = iobase + 3;
	dev->chanB.dataio = iobase + 2;

	dev->chanA.irqs = &z8530_nop;
	dev->chanB.irqs = &z8530_nop;

	/*
	 *	Assert DTR enable DMA
	 */

	outb(3 | (1 << 7), b->iobase + 4);


	/* We want a fast IRQ for this device. Actually we'd like an even faster
	   IRQ ;) - This is one driver RtLinux is made for */

	if (request_irq(irq, &z8530_interrupt, IRQF_DISABLED,
			"SeaLevel", dev) < 0) {
		printk(KERN_WARNING "sealevel: IRQ %d already in use.\n", irq);
		goto err_request_irq;
	}

	dev->irq = irq;
	dev->chanA.private = &b->dev[0];
	dev->chanB.private = &b->dev[1];
	dev->chanA.dev = dev;
	dev->chanB.dev = dev;

	dev->chanA.txdma = 3;
	dev->chanA.rxdma = 1;
	if (request_dma(dev->chanA.txdma, "SeaLevel (TX)"))
		goto err_dma_tx;

	if (request_dma(dev->chanA.rxdma, "SeaLevel (RX)"))
		goto err_dma_rx;

	disable_irq(irq);

	/*
	 *	Begin normal initialise
	 */

	if (z8530_init(dev) != 0) {
		printk(KERN_ERR "Z8530 series device not found.\n");
		enable_irq(irq);
		goto free_hw;
	}
	if (dev->type == Z85C30) {
		z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream);
		z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream);
	} else {
		z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230);
		z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream_85230);
	}

	/*
	 *	Now we can take the IRQ
	 */

	enable_irq(irq);

	if (slvl_setup(&b->dev[0], iobase, irq))
		goto free_hw;
	if (slvl_setup(&b->dev[1], iobase, irq))
		goto free_netdev0;

	z8530_describe(dev, "I/O", iobase);
	dev->active = 1;
	return b;

free_netdev0:
	unregister_hdlc_device(b->dev[0].chan->netdevice);
	free_netdev(b->dev[0].chan->netdevice);
free_hw:
	free_dma(dev->chanA.rxdma);
err_dma_rx:
	free_dma(dev->chanA.txdma);
err_dma_tx:
	free_irq(irq, dev);
err_request_irq:
	kfree(b);
err_kzalloc:
	release_region(iobase, 8);
	return NULL;
}

static void __exit slvl_shutdown(struct slvl_board *b)
{
	int u;

	z8530_shutdown(&b->board);

	for (u = 0; u < 2; u++)
	{
		struct net_device *d = b->dev[u].chan->netdevice;
		unregister_hdlc_device(d);
		free_netdev(d);
	}

	free_irq(b->board.irq, &b->board);
	free_dma(b->board.chanA.rxdma);
	free_dma(b->board.chanA.txdma);
	/* DMA off on the card, drop DTR */
	outb(0, b->iobase);
	release_region(b->iobase, 8);
	kfree(b);
}


static int io=0x238;
static int txdma=1;
static int rxdma=3;
static int irq=5;
static int slow=0;

module_param(io, int, 0);
MODULE_PARM_DESC(io, "The I/O base of the Sealevel card");
module_param(txdma, int, 0);
MODULE_PARM_DESC(txdma, "Transmit DMA channel");
module_param(rxdma, int, 0);
MODULE_PARM_DESC(rxdma, "Receive DMA channel");
module_param(irq, int, 0);
MODULE_PARM_DESC(irq, "The interrupt line setting for the SeaLevel card");
module_param(slow, bool, 0);
MODULE_PARM_DESC(slow, "Set this for an older Sealevel card such as the 4012");

MODULE_AUTHOR("Alan Cox");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Modular driver for the SeaLevel 4021");

static struct slvl_board *slvl_unit;

static int __init slvl_init_module(void)
{
	slvl_unit = slvl_init(io, irq, txdma, rxdma, slow);

	return slvl_unit ? 0 : -ENODEV;
}

static void __exit slvl_cleanup_module(void)
{
	if(slvl_unit)
		slvl_shutdown(slvl_unit);
}

module_init(slvl_init_module);
module_exit(slvl_cleanup_module);
