/* gerdes_amd7930.c,v 0.99 2001/10/02
 *
 * gerdes_amd7930.c     Amd 79C30A and 79C32A specific routines
 *                      (based on HiSax driver by Karsten Keil)
 *
 * Author               Christoph Ersfeld <info@formula-n.de>
 *                      Formula-n Europe AG (www.formula-n.com)
 *                      previously Gerdes AG
 *
 *
 *                      This file is (c) under GNU PUBLIC LICENSE
 *
 *
 * Notes:
 * Version 0.99 is the first release of this driver and there are
 * certainly a few bugs.
 *
 * Please don't report any malfunction to me without sending
 * (compressed) debug-logs.
 * It would be nearly impossible to retrace it.
 *
 * Log D-channel-processing as follows:
 *
 * 1. Load hisax with card-specific parameters, this example ist for
 *    Formula-n enter:now ISDN PCI and compatible
 *    (f.e. Gerdes Power ISDN PCI)
 *
 *    modprobe hisax type=41 protocol=2 id=gerdes
 *
 *    if you chose an other value for id, you need to modify the
 *    code below, too.
 *
 * 2. set debug-level
 *
 *    hisaxctrl gerdes 1 0x3ff
 *    hisaxctrl gerdes 11 0x4f
 *    cat /dev/isdnctrl >> ~/log &
 *
 * Please take also a look into /var/log/messages if there is
 * anything importand concerning HISAX.
 *
 *
 * Credits:
 * Programming the driver for Formula-n enter:now ISDN PCI and
 * necessary this driver for the used Amd 7930 D-channel-controller
 * was spnsored by Formula-n Europe AG.
 * Thanks to Karsten Keil and Petr Novak, who gave me support in
 * Hisax-specific questions.
 * I want so say special thanks to Carl-Friedrich Braun, who had to
 * answer a lot of questions about generally ISDN and about handling
 * of the Amd-Chip.
 *
 */


#include "hisax.h"
#include "isdnl1.h"
#include "isac.h"
#include "amd7930_fn.h"
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/gfp.h>

static void Amd7930_new_ph(struct IsdnCardState *cs);

static WORD initAMD[] = {
	0x0100,

	0x00A5, 3, 0x01, 0x40, 0x58,				// LPR, LMR1, LMR2
	0x0086, 1, 0x0B,					// DMR1 (D-Buffer TH-Interrupts on)
	0x0087, 1, 0xFF,					// DMR2
	0x0092, 1, 0x03,					// EFCR (extended mode d-channel-fifo on)
	0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F,			// FRAR4, SRAR4, DMR3, DMR4 (address recognition )
	0x0084, 2, 0x80, 0x00,					// DRLR
	0x00C0, 1, 0x47,					// PPCR1
	0x00C8, 1, 0x01,					// PPCR2

	0x0102,
	0x0107,
	0x01A1, 1,
	0x0121, 1,
	0x0189, 2,

	0x0045, 4, 0x61, 0x72, 0x00, 0x00,			// MCR1, MCR2, MCR3, MCR4
	0x0063, 2, 0x08, 0x08,					// GX
	0x0064, 2, 0x08, 0x08,					// GR
	0x0065, 2, 0x99, 0x00,					// GER
	0x0066, 2, 0x7C, 0x8B,					// STG
	0x0067, 2, 0x00, 0x00,					// FTGR1, FTGR2
	0x0068, 2, 0x20, 0x20,					// ATGR1, ATGR2
	0x0069, 1, 0x4F,					// MMR1
	0x006A, 1, 0x00,					// MMR2
	0x006C, 1, 0x40,					// MMR3
	0x0021, 1, 0x02,					// INIT
	0x00A3, 1, 0x40,					// LMR1

	0xFFFF
};


static void /* macro wWordAMD */
WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
{
	wByteAMD(cs, 0x00, reg);
	wByteAMD(cs, 0x01, LOBYTE(val));
	wByteAMD(cs, 0x01, HIBYTE(val));
}

static WORD /* macro rWordAMD */
ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg)
{
	WORD res;
	/* direct access register */
	if (reg < 8) {
		res = rByteAMD(cs, reg);
		res += 256 * rByteAMD(cs, reg);
	}
	/* indirect access register */
	else {
		wByteAMD(cs, 0x00, reg);
		res = rByteAMD(cs, 0x01);
		res += 256 * rByteAMD(cs, 0x01);
	}
	return (res);
}


static void
Amd7930_ph_command(struct IsdnCardState *cs, u_char command, char *s)
{
	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "AMD7930: %s: ph_command 0x%02X", s, command);

	cs->dc.amd7930.lmr1 = command;
	wByteAMD(cs, 0xA3, command);
}



static BYTE i430States[] = {
// to   reset  F3    F4    F5    F6    F7    F8    AR     from
	0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,   // init
	0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,   // reset
	0x01, 0x02, 0x00, 0x00, 0x00, 0x09, 0x05, 0x04,   // F3
	0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,   // F4
	0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,   // F5
	0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00,   // F6
	0x11, 0x13, 0x00, 0x00, 0x1B, 0x00, 0x15, 0x00,   // F7
	0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,   // F8
	0x01, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0A};  // AR


/*                    Row     init    -   reset  F3    F4    F5    F6    F7    F8    AR */
static BYTE stateHelper[] = { 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };




static void
Amd7930_get_state(struct IsdnCardState *cs) {
	BYTE lsr = rByteAMD(cs, 0xA1);
	cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
	Amd7930_new_ph(cs);
}



static void
Amd7930_new_ph(struct IsdnCardState *cs)
{
	u_char index = stateHelper[cs->dc.amd7930.old_state] * 8 + stateHelper[cs->dc.amd7930.ph_state] - 1;
	u_char message = i430States[index];

	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "AMD7930: new_ph %d, old_ph %d, message %d, index %d",
			cs->dc.amd7930.ph_state, cs->dc.amd7930.old_state, message & 0x0f, index);

	cs->dc.amd7930.old_state = cs->dc.amd7930.ph_state;

	/* abort transmit if nessesary */
	if ((message & 0xf0) && (cs->tx_skb)) {
		wByteAMD(cs, 0x21, 0xC2);
		wByteAMD(cs, 0x21, 0x02);
	}

	switch (message & 0x0f) {

	case (1):
		l1_msg(cs, HW_RESET | INDICATION, NULL);
		Amd7930_get_state(cs);
		break;
	case (2): /* init, Card starts in F3 */
		l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
		break;
	case (3):
		l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
		break;
	case (4):
		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
		Amd7930_ph_command(cs, 0x50, "HW_ENABLE REQUEST");
		break;
	case (5):
		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
		break;
	case (6):
		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
		break;
	case (7): /* init, Card starts in F7 */
		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
		break;
	case (8):
		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
		/* fall through */
	case (9):
		Amd7930_ph_command(cs, 0x40, "HW_ENABLE REQ cleared if set");
		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
		l1_msg(cs, HW_INFO2 | INDICATION, NULL);
		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
		break;
	case (10):
		Amd7930_ph_command(cs, 0x40, "T3 expired, HW_ENABLE REQ cleared");
		cs->dc.amd7930.old_state = 3;
		break;
	case (11):
		l1_msg(cs, HW_INFO2 | INDICATION, NULL);
		break;
	default:
		break;
	}
}



static void
Amd7930_bh(struct work_struct *work)
{
	struct IsdnCardState *cs =
		container_of(work, struct IsdnCardState, tqueue);
	struct PStack *stptr;

	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
		if (cs->debug)
			debugl1(cs, "Amd7930: bh, D-Channel Busy cleared");
		stptr = cs->stlist;
		while (stptr != NULL) {
			stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
			stptr = stptr->next;
		}
	}
	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "AMD7930: bh, D_L1STATECHANGE");
		Amd7930_new_ph(cs);
	}

	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "AMD7930: bh, D_RCVBUFREADY");
		DChannel_proc_rcv(cs);
	}

	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "AMD7930: bh, D_XMTBUFREADY");
		DChannel_proc_xmt(cs);
	}
}

static void
Amd7930_empty_Dfifo(struct IsdnCardState *cs, int flag)
{

	BYTE stat, der;
	BYTE *ptr;
	struct sk_buff *skb;


	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
		debugl1(cs, "Amd7930: empty_Dfifo");


	ptr = cs->rcvbuf + cs->rcvidx;

	/* AMD interrupts off */
	AmdIrqOff(cs);

	/* read D-Channel-Fifo*/
	stat = rByteAMD(cs, 0x07); // DSR2

	/* while Data in Fifo ... */
	while ((stat & 2) && ((ptr-cs->rcvbuf) < MAX_DFRAME_LEN_L1)) {
		*ptr = rByteAMD(cs, 0x04); // DCRB
		ptr++;
		stat = rByteAMD(cs, 0x07); // DSR2
		cs->rcvidx = ptr - cs->rcvbuf;

		/* Paket ready? */
		if (stat & 1) {

			der = rWordAMD(cs, 0x03);

			/* no errors, packet ok */
			if (!der && !flag) {
				rWordAMD(cs, 0x89); // clear DRCR

				if ((cs->rcvidx) > 0) {
					if (!(skb = alloc_skb(cs->rcvidx, GFP_ATOMIC)))
						printk(KERN_WARNING "HiSax: Amd7930: empty_Dfifo, D receive out of memory!\n");
					else {
						/* Debugging */
						if (cs->debug & L1_DEB_ISAC_FIFO) {
							char *t = cs->dlog;

							t += sprintf(t, "Amd7930: empty_Dfifo cnt: %d |", cs->rcvidx);
							QuickHex(t, cs->rcvbuf, cs->rcvidx);
							debugl1(cs, "%s", cs->dlog);
						}
						/* moves received data in sk-buffer */
						skb_put_data(skb, cs->rcvbuf,
							     cs->rcvidx);
						skb_queue_tail(&cs->rq, skb);
					}
				}

			}
			/* throw damaged packets away, reset receive-buffer, indicate RX */
			ptr = cs->rcvbuf;
			cs->rcvidx = 0;
			schedule_event(cs, D_RCVBUFREADY);
		}
	}
	/* Packet to long, overflow */
	if (cs->rcvidx >= MAX_DFRAME_LEN_L1) {
		if (cs->debug & L1_DEB_WARN)
			debugl1(cs, "AMD7930: empty_Dfifo L2-Framelength overrun");
		cs->rcvidx = 0;
		return;
	}
	/* AMD interrupts on */
	AmdIrqOn(cs);
}


static void
Amd7930_fill_Dfifo(struct IsdnCardState *cs)
{

	WORD dtcrr, dtcrw, len, count;
	BYTE txstat, dmr3;
	BYTE *ptr, *deb_ptr;

	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
		debugl1(cs, "Amd7930: fill_Dfifo");

	if ((!cs->tx_skb) || (cs->tx_skb->len <= 0))
		return;

	dtcrw = 0;
	if (!cs->dc.amd7930.tx_xmtlen)
		/* new Frame */
		len = dtcrw = cs->tx_skb->len;
	/* continue frame */
	else len = cs->dc.amd7930.tx_xmtlen;


	/* AMD interrupts off */
	AmdIrqOff(cs);

	deb_ptr = ptr = cs->tx_skb->data;

	/* while free place in tx-fifo available and data in sk-buffer */
	txstat = 0x10;
	while ((txstat & 0x10) && (cs->tx_cnt < len)) {
		wByteAMD(cs, 0x04, *ptr);
		ptr++;
		cs->tx_cnt++;
		txstat = rByteAMD(cs, 0x07);
	}
	count = ptr - cs->tx_skb->data;
	skb_pull(cs->tx_skb, count);


	dtcrr = rWordAMD(cs, 0x85); // DTCR
	dmr3  = rByteAMD(cs, 0x8E);

	if (cs->debug & L1_DEB_ISAC) {
		debugl1(cs, "Amd7930: fill_Dfifo, DMR3: 0x%02X, DTCR read: 0x%04X write: 0x%02X 0x%02X", dmr3, dtcrr, LOBYTE(dtcrw), HIBYTE(dtcrw));
	}

	/* writeing of dtcrw starts transmit */
	if (!cs->dc.amd7930.tx_xmtlen) {
		wWordAMD(cs, 0x85, dtcrw);
		cs->dc.amd7930.tx_xmtlen = dtcrw;
	}

	if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
		debugl1(cs, "Amd7930: fill_Dfifo dbusytimer running");
		del_timer(&cs->dbusytimer);
	}
	cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
	add_timer(&cs->dbusytimer);

	if (cs->debug & L1_DEB_ISAC_FIFO) {
		char *t = cs->dlog;

		t += sprintf(t, "Amd7930: fill_Dfifo cnt: %d |", count);
		QuickHex(t, deb_ptr, count);
		debugl1(cs, "%s", cs->dlog);
	}
	/* AMD interrupts on */
	AmdIrqOn(cs);
}


void Amd7930_interrupt(struct IsdnCardState *cs, BYTE irflags)
{
	BYTE dsr1, dsr2, lsr;
	WORD der;

	while (irflags)
	{

		dsr1 = rByteAMD(cs, 0x02);
		der  = rWordAMD(cs, 0x03);
		dsr2 = rByteAMD(cs, 0x07);
		lsr  = rByteAMD(cs, 0xA1);

		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "Amd7930: interrupt: flags: 0x%02X, DSR1: 0x%02X, DSR2: 0x%02X, LSR: 0x%02X, DER=0x%04X", irflags, dsr1, dsr2, lsr, der);

		/* D error -> read DER and DSR2 bit 2 */
		if (der || (dsr2 & 4)) {

			if (cs->debug & L1_DEB_WARN)
				debugl1(cs, "Amd7930: interrupt: D error DER=0x%04X", der);

			/* RX, TX abort if collision detected */
			if (der & 2) {
				wByteAMD(cs, 0x21, 0xC2);
				wByteAMD(cs, 0x21, 0x02);
				if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
					del_timer(&cs->dbusytimer);
				if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
					schedule_event(cs, D_CLEARBUSY);
				/* restart frame */
				if (cs->tx_skb) {
					skb_push(cs->tx_skb, cs->tx_cnt);
					cs->tx_cnt = 0;
					cs->dc.amd7930.tx_xmtlen = 0;
					Amd7930_fill_Dfifo(cs);
				} else {
					printk(KERN_WARNING "HiSax: Amd7930 D-Collision, no skb\n");
					debugl1(cs, "Amd7930: interrupt: D-Collision, no skb");
				}
			}
			/* remove damaged data from fifo */
			Amd7930_empty_Dfifo(cs, 1);

			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
				del_timer(&cs->dbusytimer);
			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
				schedule_event(cs, D_CLEARBUSY);
			/* restart TX-Frame */
			if (cs->tx_skb) {
				skb_push(cs->tx_skb, cs->tx_cnt);
				cs->tx_cnt = 0;
				cs->dc.amd7930.tx_xmtlen = 0;
				Amd7930_fill_Dfifo(cs);
			}
		}

		/* D TX FIFO empty -> fill */
		if (irflags & 1) {
			if (cs->debug & L1_DEB_ISAC)
				debugl1(cs, "Amd7930: interrupt: clear Timer and fill D-TX-FIFO if data");

			/* AMD interrupts off */
			AmdIrqOff(cs);

			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
				del_timer(&cs->dbusytimer);
			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
				schedule_event(cs, D_CLEARBUSY);
			if (cs->tx_skb) {
				if (cs->tx_skb->len)
					Amd7930_fill_Dfifo(cs);
			}
			/* AMD interrupts on */
			AmdIrqOn(cs);
		}


		/* D RX FIFO full or tiny packet in Fifo -> empty */
		if ((irflags & 2) || (dsr1 & 2)) {
			if (cs->debug & L1_DEB_ISAC)
				debugl1(cs, "Amd7930: interrupt: empty D-FIFO");
			Amd7930_empty_Dfifo(cs, 0);
		}


		/* D-Frame transmit complete */
		if (dsr1 & 64) {
			if (cs->debug & L1_DEB_ISAC) {
				debugl1(cs, "Amd7930: interrupt: transmit packet ready");
			}
			/* AMD interrupts off */
			AmdIrqOff(cs);

			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
				del_timer(&cs->dbusytimer);
			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
				schedule_event(cs, D_CLEARBUSY);

			if (cs->tx_skb) {
				if (cs->debug & L1_DEB_ISAC)
					debugl1(cs, "Amd7930: interrupt: TX-Packet ready, freeing skb");
				dev_kfree_skb_irq(cs->tx_skb);
				cs->tx_cnt = 0;
				cs->dc.amd7930.tx_xmtlen = 0;
				cs->tx_skb = NULL;
			}
			if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
				if (cs->debug & L1_DEB_ISAC)
					debugl1(cs, "Amd7930: interrupt: TX-Packet ready, next packet dequeued");
				cs->tx_cnt = 0;
				cs->dc.amd7930.tx_xmtlen = 0;
				Amd7930_fill_Dfifo(cs);
			}
			else
				schedule_event(cs, D_XMTBUFREADY);
			/* AMD interrupts on */
			AmdIrqOn(cs);
		}

		/* LIU status interrupt -> read LSR, check statechanges */
		if (lsr & 0x38) {
			/* AMD interrupts off */
			AmdIrqOff(cs);

			if (cs->debug & L1_DEB_ISAC)
				debugl1(cs, "Amd: interrupt: LSR=0x%02X, LIU is in state %d", lsr, ((lsr & 0x7) + 2));

			cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;

			schedule_event(cs, D_L1STATECHANGE);
			/* AMD interrupts on */
			AmdIrqOn(cs);
		}

		/* reads Interrupt-Register again. If there is a new interrupt-flag: restart handler */
		irflags = rByteAMD(cs, 0x00);
	}

}

static void
Amd7930_l1hw(struct PStack *st, int pr, void *arg)
{
	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
	struct sk_buff *skb = arg;
	u_long flags;

	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "Amd7930: l1hw called, pr: 0x%04X", pr);

	switch (pr) {
	case (PH_DATA | REQUEST):
		if (cs->debug & DEB_DLOG_HEX)
			LogFrame(cs, skb->data, skb->len);
		if (cs->debug & DEB_DLOG_VERBOSE)
			dlogframe(cs, skb, 0);
		spin_lock_irqsave(&cs->lock, flags);
		if (cs->tx_skb) {
			skb_queue_tail(&cs->sq, skb);
#ifdef L2FRAME_DEBUG		/* psa */
			if (cs->debug & L1_DEB_LAPD)
				Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA Queued", 0);
#endif
		} else {
			cs->tx_skb = skb;
			cs->tx_cnt = 0;
			cs->dc.amd7930.tx_xmtlen = 0;
#ifdef L2FRAME_DEBUG		/* psa */
			if (cs->debug & L1_DEB_LAPD)
				Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA", 0);
#endif
			Amd7930_fill_Dfifo(cs);
		}
		spin_unlock_irqrestore(&cs->lock, flags);
		break;
	case (PH_PULL | INDICATION):
		spin_lock_irqsave(&cs->lock, flags);
		if (cs->tx_skb) {
			if (cs->debug & L1_DEB_WARN)
				debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen");
			skb_queue_tail(&cs->sq, skb);
			spin_unlock_irqrestore(&cs->lock, flags);
			break;
		}
		if (cs->debug & DEB_DLOG_HEX)
			LogFrame(cs, skb->data, skb->len);
		if (cs->debug & DEB_DLOG_VERBOSE)
			dlogframe(cs, skb, 0);
		cs->tx_skb = skb;
		cs->tx_cnt = 0;
		cs->dc.amd7930.tx_xmtlen = 0;
#ifdef L2FRAME_DEBUG		/* psa */
		if (cs->debug & L1_DEB_LAPD)
			Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA_PULLED", 0);
#endif
		Amd7930_fill_Dfifo(cs);
		spin_unlock_irqrestore(&cs->lock, flags);
		break;
	case (PH_PULL | REQUEST):
#ifdef L2FRAME_DEBUG		/* psa */
		if (cs->debug & L1_DEB_LAPD)
			debugl1(cs, "Amd7930: l1hw: -> PH_REQUEST_PULL, skb: %s", (cs->tx_skb) ? "yes" : "no");
#endif
		if (!cs->tx_skb) {
			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
		} else
			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
		break;
	case (HW_RESET | REQUEST):
		spin_lock_irqsave(&cs->lock, flags);
		if ((cs->dc.amd7930.ph_state == 8)) {
			/* b-channels off, PH-AR cleared
			 * change to F3 */
			Amd7930_ph_command(cs, 0x20, "HW_RESET REQUEST"); //LMR1 bit 5
			spin_unlock_irqrestore(&cs->lock, flags);
		} else {
			Amd7930_ph_command(cs, 0x40, "HW_RESET REQUEST");
			cs->dc.amd7930.ph_state = 2;
			spin_unlock_irqrestore(&cs->lock, flags);
			Amd7930_new_ph(cs);
		}
		break;
	case (HW_ENABLE | REQUEST):
		cs->dc.amd7930.ph_state = 9;
		Amd7930_new_ph(cs);
		break;
	case (HW_INFO3 | REQUEST):
		// automatic
		break;
	case (HW_TESTLOOP | REQUEST):
		/* not implemented yet */
		break;
	case (HW_DEACTIVATE | RESPONSE):
		skb_queue_purge(&cs->rq);
		skb_queue_purge(&cs->sq);
		if (cs->tx_skb) {
			dev_kfree_skb(cs->tx_skb);
			cs->tx_skb = NULL;
		}
		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
			del_timer(&cs->dbusytimer);
		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
			schedule_event(cs, D_CLEARBUSY);
		break;
	default:
		if (cs->debug & L1_DEB_WARN)
			debugl1(cs, "Amd7930: l1hw: unknown %04x", pr);
		break;
	}
}

static void
setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
{

	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "Amd7930: setstack called");

	st->l1.l1hw = Amd7930_l1hw;
}


static void
DC_Close_Amd7930(struct IsdnCardState *cs) {
	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "Amd7930: DC_Close called");
}


static void
dbusy_timer_handler(struct timer_list *t)
{
	struct IsdnCardState *cs = from_timer(cs, t, dbusytimer);
	u_long flags;
	struct PStack *stptr;
	WORD dtcr, der;
	BYTE dsr1, dsr2;


	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "Amd7930: dbusy_timer expired!");

	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
		spin_lock_irqsave(&cs->lock, flags);
		/* D Transmit Byte Count Register:
		 * Counts down packet's number of Bytes, 0 if packet ready */
		dtcr = rWordAMD(cs, 0x85);
		dsr1 = rByteAMD(cs, 0x02);
		dsr2 = rByteAMD(cs, 0x07);
		der  = rWordAMD(cs, 0x03);

		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "Amd7930: dbusy_timer_handler: DSR1=0x%02X, DSR2=0x%02X, DER=0x%04X, cs->tx_skb->len=%u, tx_stat=%u, dtcr=%u, cs->tx_cnt=%u", dsr1, dsr2, der, cs->tx_skb->len, cs->dc.amd7930.tx_xmtlen, dtcr, cs->tx_cnt);

		if ((cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) {	/* D-Channel Busy */
			test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
			stptr = cs->stlist;
			spin_unlock_irqrestore(&cs->lock, flags);
			while (stptr != NULL) {
				stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
				stptr = stptr->next;
			}

		} else {
			/* discard frame; reset transceiver */
			test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
			if (cs->tx_skb) {
				dev_kfree_skb_any(cs->tx_skb);
				cs->tx_cnt = 0;
				cs->tx_skb = NULL;
				cs->dc.amd7930.tx_xmtlen = 0;
			} else {
				printk(KERN_WARNING "HiSax: Amd7930: D-Channel Busy no skb\n");
				debugl1(cs, "Amd7930: D-Channel Busy no skb");

			}
			/* Transmitter reset, abort transmit */
			wByteAMD(cs, 0x21, 0x82);
			wByteAMD(cs, 0x21, 0x02);
			spin_unlock_irqrestore(&cs->lock, flags);
			cs->irq_func(cs->irq, cs);

			if (cs->debug & L1_DEB_ISAC)
				debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset");
		}
	}
}



void Amd7930_init(struct IsdnCardState *cs)
{
	WORD *ptr;
	BYTE cmd, cnt;

	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "Amd7930: initamd called");

	cs->dc.amd7930.tx_xmtlen = 0;
	cs->dc.amd7930.old_state = 0;
	cs->dc.amd7930.lmr1 = 0x40;
	cs->dc.amd7930.ph_command = Amd7930_ph_command;
	cs->setstack_d = setstack_Amd7930;
	cs->DC_Close = DC_Close_Amd7930;

	/* AMD Initialisation */
	for (ptr = initAMD; *ptr != 0xFFFF; ) {
		cmd = LOBYTE(*ptr);

		/* read */
		if (*ptr++ >= 0x100) {
			if (cmd < 8)
				/* reset register */
				rByteAMD(cs, cmd);
			else {
				wByteAMD(cs, 0x00, cmd);
				for (cnt = *ptr++; cnt > 0; cnt--)
					rByteAMD(cs, 0x01);
			}
		}
		/* write */
		else if (cmd < 8)
			wByteAMD(cs, cmd, LOBYTE(*ptr++));

		else {
			wByteAMD(cs, 0x00, cmd);
			for (cnt = *ptr++; cnt > 0; cnt--)
				wByteAMD(cs, 0x01, LOBYTE(*ptr++));
		}
	}
}

void setup_Amd7930(struct IsdnCardState *cs)
{
	INIT_WORK(&cs->tqueue, Amd7930_bh);
	timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0);
}
