/*
 * PCBIT-D low-layer interface
 *
 * Copyright (C) 1996 Universidade de Lisboa
 *
 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
 *
 * This software may be used and distributed according to the terms of
 * the GNU General Public License, incorporated herein by reference.
 */

/*
 * 19991203 - Fernando Carvalho - takion@superbofh.org
 * Hacked to compile with egcs and run with current version of isdn modules
 */

/*
 *        Based on documentation provided by Inesc:
 *        - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93
 */

/*
 *        TODO: better handling of errors
 *              re-write/remove debug printks
 */

#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/mm.h>
#include <linux/skbuff.h>

#include <linux/isdnif.h>

#include <asm/io.h>


#include "pcbit.h"
#include "layer2.h"
#include "edss1.h"

#undef DEBUG_FRAG


/*
 *  Prototypes
 */

static void pcbit_transmit(struct pcbit_dev *dev);

static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack);

static void pcbit_l2_error(struct pcbit_dev *dev);
static void pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info);
static void pcbit_l2_err_recover(unsigned long data);

static void pcbit_firmware_bug(struct pcbit_dev *dev);

static __inline__ void
pcbit_sched_delivery(struct pcbit_dev *dev)
{
	schedule_work(&dev->qdelivery);
}


/*
 *  Called from layer3
 */

int
pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
	       struct sk_buff *skb, unsigned short hdr_len)
{
	struct frame_buf *frame,
		*ptr;
	unsigned long flags;

	if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
		dev_kfree_skb(skb);
		return -1;
	}
	if ((frame = kmalloc(sizeof(struct frame_buf),
			     GFP_ATOMIC)) == NULL) {
		dev_kfree_skb(skb);
		return -1;
	}
	frame->msg = msg;
	frame->refnum = refnum;
	frame->copied = 0;
	frame->hdr_len = hdr_len;

	if (skb)
		frame->dt_len = skb->len - hdr_len;
	else
		frame->dt_len = 0;

	frame->skb = skb;

	frame->next = NULL;

	spin_lock_irqsave(&dev->lock, flags);

	if (dev->write_queue == NULL) {
		dev->write_queue = frame;
		spin_unlock_irqrestore(&dev->lock, flags);
		pcbit_transmit(dev);
	} else {
		for (ptr = dev->write_queue; ptr->next; ptr = ptr->next);
		ptr->next = frame;

		spin_unlock_irqrestore(&dev->lock, flags);
	}
	return 0;
}

static __inline__ void
pcbit_tx_update(struct pcbit_dev *dev, ushort len)
{
	u_char info;

	dev->send_seq = (dev->send_seq + 1) % 8;

	dev->fsize[dev->send_seq] = len;
	info = 0;
	info |= dev->rcv_seq << 3;
	info |= dev->send_seq;

	writeb(info, dev->sh_mem + BANK4);

}

/*
 * called by interrupt service routine or by write_2
 */

static void
pcbit_transmit(struct pcbit_dev *dev)
{
	struct frame_buf *frame = NULL;
	unsigned char unacked;
	int flen;               /* fragment frame length including all headers */
	int free;
	int count,
		cp_len;
	unsigned long flags;
	unsigned short tt;

	if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
		return;

	unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;

	spin_lock_irqsave(&dev->lock, flags);

	if (dev->free > 16 && dev->write_queue && unacked < 7) {

		if (!dev->w_busy)
			dev->w_busy = 1;
		else {
			spin_unlock_irqrestore(&dev->lock, flags);
			return;
		}


		frame = dev->write_queue;
		free = dev->free;

		spin_unlock_irqrestore(&dev->lock, flags);

		if (frame->copied == 0) {

			/* Type 0 frame */

			ulong	msg;

			if (frame->skb)
				flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
			else
				flen = FRAME_HDR_LEN + PREHDR_LEN;

			if (flen > free)
				flen = free;

			msg = frame->msg;

			/*
			 *  Board level 2 header
			 */

			pcbit_writew(dev, flen - FRAME_HDR_LEN);

			pcbit_writeb(dev, GET_MSG_CPU(msg));

			pcbit_writeb(dev, GET_MSG_PROC(msg));

			/* TH */
			pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);

			/* TD */
			pcbit_writew(dev, frame->dt_len);


			/*
			 *  Board level 3 fixed-header
			 */

			/* LEN = TH */
			pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);

			/* XX */
			pcbit_writew(dev, 0);

			/* C + S */
			pcbit_writeb(dev, GET_MSG_CMD(msg));
			pcbit_writeb(dev, GET_MSG_SCMD(msg));

			/* NUM */
			pcbit_writew(dev, frame->refnum);

			count = FRAME_HDR_LEN + PREHDR_LEN;
		} else {
			/* Type 1 frame */

			flen = 2 + (frame->skb->len - frame->copied);

			if (flen > free)
				flen = free;

			/* TT */
			tt = ((ushort) (flen - 2)) | 0x8000U;	/* Type 1 */
			pcbit_writew(dev, tt);

			count = 2;
		}

		if (frame->skb) {
			cp_len = frame->skb->len - frame->copied;
			if (cp_len > flen - count)
				cp_len = flen - count;

			memcpy_topcbit(dev, frame->skb->data + frame->copied,
				       cp_len);
			frame->copied += cp_len;
		}
		/* bookkeeping */
		dev->free -= flen;
		pcbit_tx_update(dev, flen);

		spin_lock_irqsave(&dev->lock, flags);

		if (frame->skb == NULL || frame->copied == frame->skb->len) {

			dev->write_queue = frame->next;

			if (frame->skb != NULL) {
				/* free frame */
				dev_kfree_skb(frame->skb);
			}
			kfree(frame);
		}
		dev->w_busy = 0;
		spin_unlock_irqrestore(&dev->lock, flags);
	} else {
		spin_unlock_irqrestore(&dev->lock, flags);
#ifdef DEBUG
		printk(KERN_DEBUG "unacked %d free %d write_queue %s\n",
		       unacked, dev->free, dev->write_queue ? "not empty" :
		       "empty");
#endif
	}
}


/*
 *  deliver a queued frame to the upper layer
 */

void
pcbit_deliver(struct work_struct *work)
{
	struct frame_buf *frame;
	unsigned long flags, msg;
	struct pcbit_dev *dev =
		container_of(work, struct pcbit_dev, qdelivery);

	spin_lock_irqsave(&dev->lock, flags);

	while ((frame = dev->read_queue)) {
		dev->read_queue = frame->next;
		spin_unlock_irqrestore(&dev->lock, flags);

		msg = 0;
		SET_MSG_CPU(msg, 0);
		SET_MSG_PROC(msg, 0);
		SET_MSG_CMD(msg, frame->skb->data[2]);
		SET_MSG_SCMD(msg, frame->skb->data[3]);

		frame->refnum = *((ushort *)frame->skb->data + 4);
		frame->msg = *((ulong *)&msg);

		skb_pull(frame->skb, 6);

		pcbit_l3_receive(dev, frame->msg, frame->skb, frame->hdr_len,
				 frame->refnum);

		kfree(frame);

		spin_lock_irqsave(&dev->lock, flags);
	}

	spin_unlock_irqrestore(&dev->lock, flags);
}

/*
 * Reads BANK 2 & Reassembles
 */

static void
pcbit_receive(struct pcbit_dev *dev)
{
	unsigned short tt;
	u_char cpu,
		proc;
	struct frame_buf *frame = NULL;
	unsigned long flags;
	u_char type1;

	if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
		return;

	tt = pcbit_readw(dev);

	if ((tt & 0x7fffU) > 511) {
		printk(KERN_INFO "pcbit: invalid frame length -> TT=%04x\n",
		       tt);
		pcbit_l2_error(dev);
		return;
	}
	if (!(tt & 0x8000U)) {  /* Type 0 */
		type1 = 0;

		if (dev->read_frame) {
			printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
			/* discard previous queued frame */
			kfree_skb(dev->read_frame->skb);
			kfree(dev->read_frame);
			dev->read_frame = NULL;
		}
		frame = kzalloc(sizeof(struct frame_buf), GFP_ATOMIC);

		if (frame == NULL) {
			printk(KERN_WARNING "kmalloc failed\n");
			return;
		}

		cpu = pcbit_readb(dev);
		proc = pcbit_readb(dev);


		if (cpu != 0x06 && cpu != 0x02) {
			printk(KERN_DEBUG "pcbit: invalid cpu value\n");
			kfree(frame);
			pcbit_l2_error(dev);
			return;
		}
		/*
		 * we discard cpu & proc on receiving
		 * but we read it to update the pointer
		 */

		frame->hdr_len = pcbit_readw(dev);
		frame->dt_len = pcbit_readw(dev);

		/*
		 * 0 sized packet
		 * I don't know if they are an error or not...
		 * But they are very frequent
		 * Not documented
		 */

		if (frame->hdr_len == 0) {
			kfree(frame);
#ifdef DEBUG
			printk(KERN_DEBUG "0 sized frame\n");
#endif
			pcbit_firmware_bug(dev);
			return;
		}
		/* sanity check the length values */
		if (frame->hdr_len > 1024 || frame->dt_len > 2048) {
#ifdef DEBUG
			printk(KERN_DEBUG "length problem: ");
			printk(KERN_DEBUG "TH=%04x TD=%04x\n",
			       frame->hdr_len,
			       frame->dt_len);
#endif
			pcbit_l2_error(dev);
			kfree(frame);
			return;
		}
		/* minimum frame read */

		frame->skb = dev_alloc_skb(frame->hdr_len + frame->dt_len +
					   ((frame->hdr_len + 15) & ~15));

		if (!frame->skb) {
			printk(KERN_DEBUG "pcbit_receive: out of memory\n");
			kfree(frame);
			return;
		}
		/* 16 byte alignment for IP */
		if (frame->dt_len)
			skb_reserve(frame->skb, (frame->hdr_len + 15) & ~15);

	} else {
		/* Type 1 */
		type1 = 1;
		tt &= 0x7fffU;

		if (!(frame = dev->read_frame)) {
			printk("Type 1 frame and no frame queued\n");
			/* usually after an error: toss frame */
			dev->readptr += tt;
			if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN)
				dev->readptr -= BANKLEN;
			return;

		}
	}

	memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt);

	frame->copied += tt;
	spin_lock_irqsave(&dev->lock, flags);
	if (frame->copied == frame->hdr_len + frame->dt_len) {

		if (type1) {
			dev->read_frame = NULL;
		}
		if (dev->read_queue) {
			struct frame_buf *ptr;
			for (ptr = dev->read_queue; ptr->next; ptr = ptr->next);
			ptr->next = frame;
		} else
			dev->read_queue = frame;

	} else {
		dev->read_frame = frame;
	}
	spin_unlock_irqrestore(&dev->lock, flags);
}

/*
 *  The board sends 0 sized frames
 *  They are TDATA_CONFs that get messed up somehow
 *  gotta send a fake acknowledgment to the upper layer somehow
 */

static __inline__ void
pcbit_fake_conf(struct pcbit_dev *dev, struct pcbit_chan *chan)
{
	isdn_ctrl ictl;

	if (chan->queued) {
		chan->queued--;

		ictl.driver = dev->id;
		ictl.command = ISDN_STAT_BSENT;
		ictl.arg = chan->id;
		dev->dev_if->statcallb(&ictl);
	}
}

static void
pcbit_firmware_bug(struct pcbit_dev *dev)
{
	struct pcbit_chan *chan;

	chan = dev->b1;

	if (chan->fsm_state == ST_ACTIVE) {
		pcbit_fake_conf(dev, chan);
	}
	chan = dev->b2;

	if (chan->fsm_state == ST_ACTIVE) {
		pcbit_fake_conf(dev, chan);
	}
}

irqreturn_t
pcbit_irq_handler(int interrupt, void *devptr)
{
	struct pcbit_dev *dev;
	u_char info,
		ack_seq,
		read_seq;

	dev = (struct pcbit_dev *) devptr;

	if (!dev) {
		printk(KERN_WARNING "pcbit_irq_handler: wrong device\n");
		return IRQ_NONE;
	}
	if (dev->interrupt) {
		printk(KERN_DEBUG "pcbit: reentering interrupt handler\n");
		return IRQ_HANDLED;
	}
	dev->interrupt = 1;

	info = readb(dev->sh_mem + BANK3);

	if (dev->l2_state == L2_STARTING || dev->l2_state == L2_ERROR) {
		pcbit_l2_active_conf(dev, info);
		dev->interrupt = 0;
		return IRQ_HANDLED;
	}
	if (info & 0x40U) {     /* E bit set */
#ifdef DEBUG
		printk(KERN_DEBUG "pcbit_irq_handler: E bit on\n");
#endif
		pcbit_l2_error(dev);
		dev->interrupt = 0;
		return IRQ_HANDLED;
	}
	if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
		dev->interrupt = 0;
		return IRQ_HANDLED;
	}
	ack_seq = (info >> 3) & 0x07U;
	read_seq = (info & 0x07U);

	dev->interrupt = 0;

	if (read_seq != dev->rcv_seq) {
		while (read_seq != dev->rcv_seq) {
			pcbit_receive(dev);
			dev->rcv_seq = (dev->rcv_seq + 1) % 8;
		}
		pcbit_sched_delivery(dev);
	}
	if (ack_seq != dev->unack_seq) {
		pcbit_recv_ack(dev, ack_seq);
	}
	info = dev->rcv_seq << 3;
	info |= dev->send_seq;

	writeb(info, dev->sh_mem + BANK4);
	return IRQ_HANDLED;
}


static void
pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info)
{
	u_char state;

	state = dev->l2_state;

#ifdef DEBUG
	printk(KERN_DEBUG "layer2_active_confirm\n");
#endif


	if (info & 0x80U) {
		dev->rcv_seq = info & 0x07U;
		dev->l2_state = L2_RUNNING;
	} else
		dev->l2_state = L2_DOWN;

	if (state == L2_STARTING)
		wake_up_interruptible(&dev->set_running_wq);

	if (state == L2_ERROR && dev->l2_state == L2_RUNNING) {
		pcbit_transmit(dev);
	}
}

static void
pcbit_l2_err_recover(unsigned long data)
{

	struct pcbit_dev *dev;
	struct frame_buf *frame;

	dev = (struct pcbit_dev *) data;

	del_timer(&dev->error_recover_timer);
	if (dev->w_busy || dev->r_busy) {
		init_timer(&dev->error_recover_timer);
		dev->error_recover_timer.expires = jiffies + ERRTIME;
		add_timer(&dev->error_recover_timer);
		return;
	}
	dev->w_busy = dev->r_busy = 1;

	if (dev->read_frame) {
		kfree_skb(dev->read_frame->skb);
		kfree(dev->read_frame);
		dev->read_frame = NULL;
	}
	if (dev->write_queue) {
		frame = dev->write_queue;
#ifdef FREE_ON_ERROR
		dev->write_queue = dev->write_queue->next;

		if (frame->skb) {
			dev_kfree_skb(frame->skb);
		}
		kfree(frame);
#else
		frame->copied = 0;
#endif
	}
	dev->rcv_seq = dev->send_seq = dev->unack_seq = 0;
	dev->free = 511;
	dev->l2_state = L2_ERROR;

	/* this is an hack... */
	pcbit_firmware_bug(dev);

	dev->writeptr = dev->sh_mem;
	dev->readptr = dev->sh_mem + BANK2;

	writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
	       dev->sh_mem + BANK4);
	dev->w_busy = dev->r_busy = 0;

}

static void
pcbit_l2_error(struct pcbit_dev *dev)
{
	if (dev->l2_state == L2_RUNNING) {

		printk(KERN_INFO "pcbit: layer 2 error\n");

#ifdef DEBUG
		log_state(dev);
#endif

		dev->l2_state = L2_DOWN;

		init_timer(&dev->error_recover_timer);
		dev->error_recover_timer.function = &pcbit_l2_err_recover;
		dev->error_recover_timer.data = (ulong) dev;
		dev->error_recover_timer.expires = jiffies + ERRTIME;
		add_timer(&dev->error_recover_timer);
	}
}

/*
 * Description:
 * if board acks frames
 *   update dev->free
 *   call pcbit_transmit to write possible queued frames
 */

static void
pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack)
{
	int i,
		count;
	int unacked;

	unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;

	/* dev->unack_seq < ack <= dev->send_seq; */

	if (unacked) {

		if (dev->send_seq > dev->unack_seq) {
			if (ack <= dev->unack_seq || ack > dev->send_seq) {
				printk(KERN_DEBUG
				       "layer 2 ack unacceptable - dev %d",
				       dev->id);

				pcbit_l2_error(dev);
			} else if (ack > dev->send_seq && ack <= dev->unack_seq) {
				printk(KERN_DEBUG
				       "layer 2 ack unacceptable - dev %d",
				       dev->id);
				pcbit_l2_error(dev);
			}
		}
		/* ack is acceptable */


		i = dev->unack_seq;

		do {
			dev->unack_seq = i = (i + 1) % 8;
			dev->free += dev->fsize[i];
		} while (i != ack);

		count = 0;
		while (count < 7 && dev->write_queue) {
			u8 lsend_seq = dev->send_seq;

			pcbit_transmit(dev);

			if (dev->send_seq == lsend_seq)
				break;
			count++;
		}
	} else
		printk(KERN_DEBUG "recv_ack: unacked = 0\n");
}
