/*
 * SDL Inc. RISCom/N2 synchronous serial card driver for Linux
 *
 * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/>
 *
 * Note: integrated CSU/DSU/DDS are not supported by this driver
 *
 * Sources of information:
 *    Hitachi HD64570 SCA User's Manual
 *    SDL Inc. PPP/HDLC/CISCO driver
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/moduleparam.h>
#include <linux/netdevice.h>
#include <linux/hdlc.h>
#include <asm/io.h>
#include "hd64570.h"


static const char* version = "SDL RISCom/N2 driver version: 1.15";
static const char* devname = "RISCom/N2";

#undef DEBUG_PKT
#define DEBUG_RINGS

#define USE_WINDOWSIZE 16384
#define USE_BUS16BITS 1
#define CLOCK_BASE 9830400	/* 9.8304 MHz */
#define MAX_PAGES      16	/* 16 RAM pages at max */
#define MAX_RAM_SIZE 0x80000	/* 512 KB */
#if MAX_RAM_SIZE > MAX_PAGES * USE_WINDOWSIZE
#undef MAX_RAM_SIZE
#define MAX_RAM_SIZE (MAX_PAGES * USE_WINDOWSIZE)
#endif
#define N2_IOPORTS 0x10
#define NEED_DETECT_RAM
#define NEED_SCA_MSCI_INTR
#define MAX_TX_BUFFERS 10

static char *hw = NULL;	/* pointer to hw=xxx command line string */

/* RISCom/N2 Board Registers */

/* PC Control Register */
#define N2_PCR 0
#define PCR_RUNSCA 1     /* Run 64570 */
#define PCR_VPM    2     /* Enable VPM - needed if using RAM above 1 MB */
#define PCR_ENWIN  4     /* Open window */
#define PCR_BUS16  8     /* 16-bit bus */


/* Memory Base Address Register */
#define N2_BAR 2


/* Page Scan Register  */
#define N2_PSR 4
#define WIN16K       0x00
#define WIN32K       0x20
#define WIN64K       0x40
#define PSR_WINBITS  0x60
#define PSR_DMAEN    0x80
#define PSR_PAGEBITS 0x0F


/* Modem Control Reg */
#define N2_MCR 6
#define CLOCK_OUT_PORT1 0x80
#define CLOCK_OUT_PORT0 0x40
#define TX422_PORT1     0x20
#define TX422_PORT0     0x10
#define DSR_PORT1       0x08
#define DSR_PORT0       0x04
#define DTR_PORT1       0x02
#define DTR_PORT0       0x01


typedef struct port_s {
	struct net_device *dev;
	struct card_s *card;
	spinlock_t lock;	/* TX lock */
	sync_serial_settings settings;
	int valid;		/* port enabled */
	int rxpart;		/* partial frame received, next frame invalid*/
	unsigned short encoding;
	unsigned short parity;
	u16 rxin;		/* rx ring buffer 'in' pointer */
	u16 txin;		/* tx ring buffer 'in' and 'last' pointers */
	u16 txlast;
	u8 rxs, txs, tmc;	/* SCA registers */
	u8 phy_node;		/* physical port # - 0 or 1 */
	u8 log_node;		/* logical port # */
}port_t;



typedef struct card_s {
	u8 __iomem *winbase;		/* ISA window base address */
	u32 phy_winbase;	/* ISA physical base address */
	u32 ram_size;		/* number of bytes */
	u16 io;			/* IO Base address */
	u16 buff_offset;	/* offset of first buffer of first channel */
	u16 rx_ring_buffers;	/* number of buffers in a ring */
	u16 tx_ring_buffers;
	u8 irq;			/* IRQ (3-15) */

	port_t ports[2];
	struct card_s *next_card;
}card_t;


static card_t *first_card;
static card_t **new_card = &first_card;


#define sca_reg(reg, card) (0x8000 | (card)->io | \
			    ((reg) & 0x0F) | (((reg) & 0xF0) << 6))
#define sca_in(reg, card)		inb(sca_reg(reg, card))
#define sca_out(value, reg, card)	outb(value, sca_reg(reg, card))
#define sca_inw(reg, card)		inw(sca_reg(reg, card))
#define sca_outw(value, reg, card)	outw(value, sca_reg(reg, card))

#define port_to_card(port)		((port)->card)
#define log_node(port)			((port)->log_node)
#define phy_node(port)			((port)->phy_node)
#define winsize(card)			(USE_WINDOWSIZE)
#define winbase(card)      	     	((card)->winbase)
#define get_port(card, port)		((card)->ports[port].valid ? \
					 &(card)->ports[port] : NULL)



static __inline__ u8 sca_get_page(card_t *card)
{
	return inb(card->io + N2_PSR) & PSR_PAGEBITS;
}


static __inline__ void openwin(card_t *card, u8 page)
{
	u8 psr = inb(card->io + N2_PSR);
	outb((psr & ~PSR_PAGEBITS) | page, card->io + N2_PSR);
}



#include "hd6457x.c"



static void n2_set_iface(port_t *port)
{
	card_t *card = port->card;
	int io = card->io;
	u8 mcr = inb(io + N2_MCR);
	u8 msci = get_msci(port);
	u8 rxs = port->rxs & CLK_BRG_MASK;
	u8 txs = port->txs & CLK_BRG_MASK;

	switch(port->settings.clock_type) {
	case CLOCK_INT:
		mcr |= port->phy_node ? CLOCK_OUT_PORT1 : CLOCK_OUT_PORT0;
		rxs |= CLK_BRG_RX; /* BRG output */
		txs |= CLK_RXCLK_TX; /* RX clock */
		break;

	case CLOCK_TXINT:
		mcr |= port->phy_node ? CLOCK_OUT_PORT1 : CLOCK_OUT_PORT0;
		rxs |= CLK_LINE_RX; /* RXC input */
		txs |= CLK_BRG_TX; /* BRG output */
		break;

	case CLOCK_TXFROMRX:
		mcr |= port->phy_node ? CLOCK_OUT_PORT1 : CLOCK_OUT_PORT0;
		rxs |= CLK_LINE_RX; /* RXC input */
		txs |= CLK_RXCLK_TX; /* RX clock */
		break;

	default:		/* Clock EXTernal */
		mcr &= port->phy_node ? ~CLOCK_OUT_PORT1 : ~CLOCK_OUT_PORT0;
		rxs |= CLK_LINE_RX; /* RXC input */
		txs |= CLK_LINE_TX; /* TXC input */
	}

	outb(mcr, io + N2_MCR);
	port->rxs = rxs;
	port->txs = txs;
	sca_out(rxs, msci + RXS, card);
	sca_out(txs, msci + TXS, card);
	sca_set_port(port);
}



static int n2_open(struct net_device *dev)
{
	port_t *port = dev_to_port(dev);
	int io = port->card->io;
	u8 mcr = inb(io + N2_MCR) | (port->phy_node ? TX422_PORT1:TX422_PORT0);
	int result;

	result = hdlc_open(dev);
	if (result)
		return result;

	mcr &= port->phy_node ? ~DTR_PORT1 : ~DTR_PORT0; /* set DTR ON */
	outb(mcr, io + N2_MCR);

	outb(inb(io + N2_PCR) | PCR_ENWIN, io + N2_PCR); /* open window */
	outb(inb(io + N2_PSR) | PSR_DMAEN, io + N2_PSR); /* enable dma */
	sca_open(dev);
	n2_set_iface(port);
	return 0;
}



static int n2_close(struct net_device *dev)
{
	port_t *port = dev_to_port(dev);
	int io = port->card->io;
	u8 mcr = inb(io+N2_MCR) | (port->phy_node ? TX422_PORT1 : TX422_PORT0);

	sca_close(dev);
	mcr |= port->phy_node ? DTR_PORT1 : DTR_PORT0; /* set DTR OFF */
	outb(mcr, io + N2_MCR);
	hdlc_close(dev);
	return 0;
}



static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	const size_t size = sizeof(sync_serial_settings);
	sync_serial_settings new_line;
	sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
	port_t *port = dev_to_port(dev);

#ifdef DEBUG_RINGS
	if (cmd == SIOCDEVPRIVATE) {
		sca_dump_rings(dev);
		return 0;
	}
#endif
	if (cmd != SIOCWANDEV)
		return hdlc_ioctl(dev, ifr, cmd);

	switch(ifr->ifr_settings.type) {
	case IF_GET_IFACE:
		ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
		if (ifr->ifr_settings.size < size) {
			ifr->ifr_settings.size = size; /* data size wanted */
			return -ENOBUFS;
		}
		if (copy_to_user(line, &port->settings, size))
			return -EFAULT;
		return 0;

	case IF_IFACE_SYNC_SERIAL:
		if(!capable(CAP_NET_ADMIN))
			return -EPERM;

		if (copy_from_user(&new_line, line, size))
			return -EFAULT;

		if (new_line.clock_type != CLOCK_EXT &&
		    new_line.clock_type != CLOCK_TXFROMRX &&
		    new_line.clock_type != CLOCK_INT &&
		    new_line.clock_type != CLOCK_TXINT)
		return -EINVAL;	/* No such clock setting */

		if (new_line.loopback != 0 && new_line.loopback != 1)
			return -EINVAL;

		memcpy(&port->settings, &new_line, size); /* Update settings */
		n2_set_iface(port);
		return 0;

	default:
		return hdlc_ioctl(dev, ifr, cmd);
	}
}



static void n2_destroy_card(card_t *card)
{
	int cnt;

	for (cnt = 0; cnt < 2; cnt++)
		if (card->ports[cnt].card) {
			struct net_device *dev = port_to_dev(&card->ports[cnt]);
			unregister_hdlc_device(dev);
		}

	if (card->irq)
		free_irq(card->irq, card);

	if (card->winbase) {
		iounmap(card->winbase);
		release_mem_region(card->phy_winbase, USE_WINDOWSIZE);
	}

	if (card->io)
		release_region(card->io, N2_IOPORTS);
	if (card->ports[0].dev)
		free_netdev(card->ports[0].dev);
	if (card->ports[1].dev)
		free_netdev(card->ports[1].dev);
	kfree(card);
}



static int __init n2_run(unsigned long io, unsigned long irq,
			 unsigned long winbase, long valid0, long valid1)
{
	card_t *card;
	u8 cnt, pcr;
	int i;

	if (io < 0x200 || io > 0x3FF || (io % N2_IOPORTS) != 0) {
		printk(KERN_ERR "n2: invalid I/O port value\n");
		return -ENODEV;
	}

	if (irq < 3 || irq > 15 || irq == 6) /* FIXME */ {
		printk(KERN_ERR "n2: invalid IRQ value\n");
		return -ENODEV;
	}

	if (winbase < 0xA0000 || winbase > 0xFFFFF || (winbase & 0xFFF) != 0) {
		printk(KERN_ERR "n2: invalid RAM value\n");
		return -ENODEV;
	}

	card = kzalloc(sizeof(card_t), GFP_KERNEL);
	if (card == NULL) {
		printk(KERN_ERR "n2: unable to allocate memory\n");
		return -ENOBUFS;
	}

	card->ports[0].dev = alloc_hdlcdev(&card->ports[0]);
	card->ports[1].dev = alloc_hdlcdev(&card->ports[1]);
	if (!card->ports[0].dev || !card->ports[1].dev) {
		printk(KERN_ERR "n2: unable to allocate memory\n");
		n2_destroy_card(card);
		return -ENOMEM;
	}

	if (!request_region(io, N2_IOPORTS, devname)) {
		printk(KERN_ERR "n2: I/O port region in use\n");
		n2_destroy_card(card);
		return -EBUSY;
	}
	card->io = io;

	if (request_irq(irq, &sca_intr, 0, devname, card)) {
		printk(KERN_ERR "n2: could not allocate IRQ\n");
		n2_destroy_card(card);
		return(-EBUSY);
	}
	card->irq = irq;

	if (!request_mem_region(winbase, USE_WINDOWSIZE, devname)) {
		printk(KERN_ERR "n2: could not request RAM window\n");
		n2_destroy_card(card);
		return(-EBUSY);
	}
	card->phy_winbase = winbase;
	card->winbase = ioremap(winbase, USE_WINDOWSIZE);
	if (!card->winbase) {
		printk(KERN_ERR "n2: ioremap() failed\n");
		n2_destroy_card(card);
		return -EFAULT;
	}

	outb(0, io + N2_PCR);
	outb(winbase >> 12, io + N2_BAR);

	switch (USE_WINDOWSIZE) {
	case 16384:
		outb(WIN16K, io + N2_PSR);
		break;

	case 32768:
		outb(WIN32K, io + N2_PSR);
		break;

	case 65536:
		outb(WIN64K, io + N2_PSR);
		break;

	default:
		printk(KERN_ERR "n2: invalid window size\n");
		n2_destroy_card(card);
		return -ENODEV;
	}

	pcr = PCR_ENWIN | PCR_VPM | (USE_BUS16BITS ? PCR_BUS16 : 0);
	outb(pcr, io + N2_PCR);

	card->ram_size = sca_detect_ram(card, card->winbase, MAX_RAM_SIZE);

	/* number of TX + RX buffers for one port */
	i = card->ram_size / ((valid0 + valid1) * (sizeof(pkt_desc) +
						   HDLC_MAX_MRU));

	card->tx_ring_buffers = min(i / 2, MAX_TX_BUFFERS);
	card->rx_ring_buffers = i - card->tx_ring_buffers;

	card->buff_offset = (valid0 + valid1) * sizeof(pkt_desc) *
		(card->tx_ring_buffers + card->rx_ring_buffers);

	printk(KERN_INFO "n2: RISCom/N2 %u KB RAM, IRQ%u, "
	       "using %u TX + %u RX packets rings\n", card->ram_size / 1024,
	       card->irq, card->tx_ring_buffers, card->rx_ring_buffers);

	if (card->tx_ring_buffers < 1) {
		printk(KERN_ERR "n2: RAM test failed\n");
		n2_destroy_card(card);
		return -EIO;
	}

	pcr |= PCR_RUNSCA;		/* run SCA */
	outb(pcr, io + N2_PCR);
	outb(0, io + N2_MCR);

	sca_init(card, 0);
	for (cnt = 0; cnt < 2; cnt++) {
		port_t *port = &card->ports[cnt];
		struct net_device *dev = port_to_dev(port);
		hdlc_device *hdlc = dev_to_hdlc(dev);

		if ((cnt == 0 && !valid0) || (cnt == 1 && !valid1))
			continue;

		port->phy_node = cnt;
		port->valid = 1;

		if ((cnt == 1) && valid0)
			port->log_node = 1;

		spin_lock_init(&port->lock);
		dev->irq = irq;
		dev->mem_start = winbase;
		dev->mem_end = winbase + USE_WINDOWSIZE - 1;
		dev->tx_queue_len = 50;
		dev->do_ioctl = n2_ioctl;
		dev->open = n2_open;
		dev->stop = n2_close;
		hdlc->attach = sca_attach;
		hdlc->xmit = sca_xmit;
		port->settings.clock_type = CLOCK_EXT;
		port->card = card;

		if (register_hdlc_device(dev)) {
			printk(KERN_WARNING "n2: unable to register hdlc "
			       "device\n");
			port->card = NULL;
			n2_destroy_card(card);
			return -ENOBUFS;
		}
		sca_init_sync_port(port); /* Set up SCA memory */

		printk(KERN_INFO "%s: RISCom/N2 node %d\n",
		       dev->name, port->phy_node);
	}

	*new_card = card;
	new_card = &card->next_card;

	return 0;
}



static int __init n2_init(void)
{
	if (hw==NULL) {
#ifdef MODULE
		printk(KERN_INFO "n2: no card initialized\n");
#endif
		return -EINVAL;	/* no parameters specified, abort */
	}

	printk(KERN_INFO "%s\n", version);

	do {
		unsigned long io, irq, ram;
		long valid[2] = { 0, 0 }; /* Default = both ports disabled */

		io = simple_strtoul(hw, &hw, 0);

		if (*hw++ != ',')
			break;
		irq = simple_strtoul(hw, &hw, 0);

		if (*hw++ != ',')
			break;
		ram = simple_strtoul(hw, &hw, 0);

		if (*hw++ != ',')
			break;
		while(1) {
			if (*hw == '0' && !valid[0])
				valid[0] = 1; /* Port 0 enabled */
			else if (*hw == '1' && !valid[1])
				valid[1] = 1; /* Port 1 enabled */
			else
				break;
			hw++;
		}

		if (!valid[0] && !valid[1])
			break;	/* at least one port must be used */

		if (*hw == ':' || *hw == '\x0')
			n2_run(io, irq, ram, valid[0], valid[1]);

		if (*hw == '\x0')
			return first_card ? 0 : -EINVAL;
	}while(*hw++ == ':');

	printk(KERN_ERR "n2: invalid hardware parameters\n");
	return first_card ? 0 : -EINVAL;
}


static void __exit n2_cleanup(void)
{
	card_t *card = first_card;

	while (card) {
		card_t *ptr = card;
		card = card->next_card;
		n2_destroy_card(ptr);
	}
}


module_init(n2_init);
module_exit(n2_cleanup);

MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
MODULE_DESCRIPTION("RISCom/N2 serial port driver");
MODULE_LICENSE("GPL v2");
module_param(hw, charp, 0444);
MODULE_PARM_DESC(hw, "io,irq,ram,ports:io,irq,...");
