/* 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, cs->dlog);
							}
                                                        /* moves received data in sk-buffer */
							memcpy(skb_put(skb, cs->rcvidx), 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);
	}
	init_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, 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 REQEST"); //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 IsdnCardState *cs)
{
	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 __devinit
setup_Amd7930(struct IsdnCardState *cs)
{
        INIT_WORK(&cs->tqueue, Amd7930_bh);
	cs->dbusytimer.function = (void *) dbusy_timer_handler;
	cs->dbusytimer.data = (long) cs;
	init_timer(&cs->dbusytimer);
}
