isdn4linux-web/workshop/hisax/hfc_2bs0.c.shtml

628 lines
26 KiB
Plaintext

<HTML>
<!-- Generated by c2html-1.0, Copyright 1998 by Dave Whittington -->
<HEAD>
<TITLE>hfc_2bs0.c</TITLE>
<!--#include virtual="/ssi/js.shtml" -->
<!--#include virtual="/ssi/buttondefs.shtml" -->
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<TABLE WIDTH="100%">
<TR>
<TD ALIGN=LEFT WIDTH="90"><!--#include virtual="/ssi/b_home.shtml" --></TD>
<TD ALIGN=RIGHT WIDTH="90"><!--#include virtual="/ssi/b_index.shtml" --></TD>
</TR>
</TABLE>
<CENTER><H1>hfc_2bs0.c</H1></CENTER>
<HR>
<PRE>
<FONT COLOR=#0000FF>/* $Id$
* specific routines for CCD's HFC 2BS0
*
* Author Karsten Keil (keil@temic-ech.spacenet.de)
*
*
* $Log$
* Revision 1.5 1998/05/25 12:57:54 keil
* HiSax golden code from certification, Don't use !!!
* No leased lines, no X75, but many changes.
*
* Revision 1.4 1998/02/12 23:07:29 keil
* change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
*
* Revision 1.3 1997/11/06 17:13:35 keil
* New 2.1 init code
*
* Revision 1.2 1997/10/29 19:04:47 keil
* changes for 2.1
*
* Revision 1.1 1997/09/11 17:31:33 keil
* Common part for HFC 2BS0 based cards
*
*
*/</FONT>
<FONT COLOR=#A521F7>#define</FONT> <A HREF="asuscom.c.shtml#__NO_VERSION__">__NO_VERSION__</A>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"hisax.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"hfc_2bs0.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isac.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdnl1.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/interrupt.h&gt;
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">inline</FONT> <FONT COLOR="#298C52">int</FONT>
WaitForBusy(<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs)
{
<FONT COLOR="#298C52">int</FONT> to = 130;
<FONT COLOR="#298C52">long</FONT> flags;
u_char val;
save_flags(flags);
cli();
<FONT COLOR="#298C52">while</FONT> (!(cs-&gt;BC_Read_Reg(cs, HFC_STATUS, 0) &amp; HFC_BUSY) &amp;&amp; to) {
val = cs-&gt;BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2 |
(cs-&gt;hw.hfc.cip &amp; 3));
udelay(1);
to--;
}
restore_flags(flags);
<FONT COLOR="#298C52">if</FONT> (!to) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"HiSax: waitforBusy timeout\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> (0);
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> (to);
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">inline</FONT> <FONT COLOR="#298C52">int</FONT>
WaitNoBusy(<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs)
{
<FONT COLOR="#298C52">int</FONT> to = 125;
<FONT COLOR="#298C52">while</FONT> ((cs-&gt;BC_Read_Reg(cs, HFC_STATUS, 0) &amp; HFC_BUSY) &amp;&amp; to) {
udelay(1);
to--;
}
<FONT COLOR="#298C52">if</FONT> (!to) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"HiSax: waitforBusy timeout\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> (0);
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> (to);
}
<FONT COLOR="#298C52">int</FONT>
GetFreeFifoBytes(<FONT COLOR="#298C52">struct</FONT> BCState *bcs)
{
<FONT COLOR="#298C52">int</FONT> s;
<FONT COLOR="#298C52">if</FONT> (bcs-&gt;hw.hfc.f1 == bcs-&gt;hw.hfc.f2)
<FONT COLOR="#298C52">return</FONT> (bcs-&gt;cs-&gt;hw.hfc.fifosize);
s = bcs-&gt;hw.hfc.send[bcs-&gt;hw.hfc.f1] - bcs-&gt;hw.hfc.send[bcs-&gt;hw.hfc.f2];
<FONT COLOR="#298C52">if</FONT> (s &lt;= 0)
s += bcs-&gt;cs-&gt;hw.hfc.fifosize;
s = bcs-&gt;cs-&gt;hw.hfc.fifosize - s;
<FONT COLOR="#298C52">return</FONT> (s);
}
<FONT COLOR="#298C52">int</FONT>
ReadZReg(<FONT COLOR="#298C52">struct</FONT> BCState *bcs, u_char reg)
{
<FONT COLOR="#298C52">int</FONT> val;
WaitNoBusy(bcs-&gt;cs);
val = 256 * bcs-&gt;cs-&gt;BC_Read_Reg(bcs-&gt;cs, HFC_DATA, reg | HFC_CIP | HFC_Z_HIGH);
WaitNoBusy(bcs-&gt;cs);
val += bcs-&gt;cs-&gt;BC_Read_Reg(bcs-&gt;cs, HFC_DATA, reg | HFC_CIP | HFC_Z_LOW);
<FONT COLOR="#298C52">return</FONT> (val);
}
<FONT COLOR="#298C52">void</FONT>
hfc_sched_event(<FONT COLOR="#298C52">struct</FONT> BCState *bcs, <FONT COLOR="#298C52">int</FONT> event)
{
bcs-&gt;event |= 1 &lt;&lt; event;
queue_task(&amp;bcs-&gt;tqueue, &amp;tq_immediate);
mark_bh(IMMEDIATE_BH);
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
hfc_clear_fifo(<FONT COLOR="#298C52">struct</FONT> BCState *bcs)
{
<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs = bcs-&gt;cs;
<FONT COLOR="#298C52">long</FONT> flags;
<FONT COLOR="#298C52">int</FONT> idx, cnt;
<FONT COLOR="#298C52">int</FONT> rcnt, z1, z2;
u_char cip, f1, f2;
<FONT COLOR="#298C52">char</FONT> tmp[64];
<FONT COLOR="#298C52">if</FONT> ((cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) &amp;&amp; !(cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX_FIFO">L1_DEB_HSCX_FIFO</A>))
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"hfc_clear_fifo"</FONT>);
save_flags(flags);
cli();
cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
<FONT COLOR="#298C52">if</FONT> ((cip &amp; 0xc3) != (cs-&gt;hw.hfc.cip &amp; 0xc3)) {
cs-&gt;BC_Write_Reg(cs, HFC_STATUS, cip, cip);
WaitForBusy(cs);
}
WaitNoBusy(cs);
f1 = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
WaitNoBusy(cs);
f2 = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel));
z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel));
cnt = 32;
<FONT COLOR="#298C52">while</FONT> (((f1 != f2) || (z1 != z2)) &amp;&amp; cnt--) {
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) {
sprintf(tmp, <FONT COLOR="#FF0000">"hfc clear %d f1(%d) f2(%d)"</FONT>,
bcs-&gt;channel, f1, f2);
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, tmp);
}
rcnt = z1 - z2;
<FONT COLOR="#298C52">if</FONT> (rcnt &lt; 0)
rcnt += cs-&gt;hw.hfc.fifosize;
<FONT COLOR="#298C52">if</FONT> (rcnt)
rcnt++;
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) {
sprintf(tmp, <FONT COLOR="#FF0000">"hfc clear %d z1(%x) z2(%x) cnt(%d)"</FONT>,
bcs-&gt;channel, z1, z2, rcnt);
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, tmp);
}
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
idx = 0;
<FONT COLOR="#298C52">while</FONT> ((idx &lt; rcnt) &amp;&amp; WaitNoBusy(cs)) {
cs-&gt;BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
idx++;
}
<FONT COLOR="#298C52">if</FONT> (f1 != f2) {
WaitNoBusy(cs);
cs-&gt;BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
HFC_CHANNEL(bcs-&gt;channel));
WaitForBusy(cs);
}
cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
WaitNoBusy(cs);
f1 = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
WaitNoBusy(cs);
f2 = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel));
z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel));
}
restore_flags(flags);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">struct</FONT> sk_buff
*
hfc_empty_fifo(<FONT COLOR="#298C52">struct</FONT> BCState *bcs, <FONT COLOR="#298C52">int</FONT> count)
{
u_char *ptr;
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb;
<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs = bcs-&gt;cs;
<FONT COLOR="#298C52">int</FONT> idx;
<FONT COLOR="#298C52">int</FONT> chksum;
u_char stat, cip;
<FONT COLOR="#298C52">char</FONT> tmp[64];
<FONT COLOR="#298C52">if</FONT> ((cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) &amp;&amp; !(cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX_FIFO">L1_DEB_HSCX_FIFO</A>))
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"hfc_empty_fifo"</FONT>);
idx = 0;
<FONT COLOR="#298C52">if</FONT> (count &gt; <A HREF="hisax.h.shtml#HSCX_BUFMAX">HSCX_BUFMAX</A> + 3) {
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_WARN">L1_DEB_WARN</A>)
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"hfc_empty_fifo: incoming packet too large"</FONT>);
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
<FONT COLOR="#298C52">while</FONT> ((idx++ &lt; count) &amp;&amp; WaitNoBusy(cs))
cs-&gt;BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
WaitNoBusy(cs);
stat = cs-&gt;BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
HFC_CHANNEL(bcs-&gt;channel));
WaitForBusy(cs);
<FONT COLOR="#298C52">return</FONT> (NULL);
}
<FONT COLOR="#298C52">if</FONT> (count &lt; 4) {
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_WARN">L1_DEB_WARN</A>)
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"hfc_empty_fifo: incoming packet too small"</FONT>);
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
<FONT COLOR="#298C52">while</FONT> ((idx++ &lt; count) &amp;&amp; WaitNoBusy(cs))
cs-&gt;BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
WaitNoBusy(cs);
stat = cs-&gt;BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
HFC_CHANNEL(bcs-&gt;channel));
WaitForBusy(cs);
<FONT COLOR="#298C52">return</FONT> (NULL);
}
<FONT COLOR="#298C52">if</FONT> (!(skb = dev_alloc_skb(count - 3)))
printk(KERN_WARNING <FONT COLOR="#FF0000">"HFC: receive out of memory\n"</FONT>);
<FONT COLOR="#298C52">else</FONT> {
ptr = skb_put(skb, count - 3);
idx = 0;
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
<FONT COLOR="#298C52">while</FONT> ((idx &lt; count - 3) &amp;&amp; WaitNoBusy(cs)) {
*ptr++ = cs-&gt;BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
idx++;
}
<FONT COLOR="#298C52">if</FONT> (idx != count - 3) {
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"RFIFO BUSY error"</FONT>);
printk(KERN_WARNING <FONT COLOR="#FF0000">"HFC FIFO channel %d BUSY Error\n"</FONT>, bcs-&gt;channel);
dev_kfree_skb(skb);
WaitNoBusy(cs);
stat = cs-&gt;BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
HFC_CHANNEL(bcs-&gt;channel));
WaitForBusy(cs);
<FONT COLOR="#298C52">return</FONT> (NULL);
}
WaitNoBusy(cs);
chksum = (cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip) &lt;&lt; 8);
WaitNoBusy(cs);
chksum += cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
WaitNoBusy(cs);
stat = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) {
sprintf(tmp, <FONT COLOR="#FF0000">"hfc_empty_fifo %d chksum %x stat %x"</FONT>,
bcs-&gt;channel, chksum, stat);
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, tmp);
}
<FONT COLOR="#298C52">if</FONT> (stat) {
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"FIFO CRC error"</FONT>);
dev_kfree_skb(skb);
skb = NULL;
}
WaitNoBusy(cs);
stat = cs-&gt;BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
HFC_CHANNEL(bcs-&gt;channel));
WaitForBusy(cs);
}
<FONT COLOR="#298C52">return</FONT> (skb);
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
hfc_fill_fifo(<FONT COLOR="#298C52">struct</FONT> BCState *bcs)
{
<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs = bcs-&gt;cs;
<FONT COLOR="#298C52">long</FONT> flags;
<FONT COLOR="#298C52">int</FONT> idx, fcnt;
<FONT COLOR="#298C52">int</FONT> count;
u_char cip;
<FONT COLOR="#298C52">char</FONT> tmp[64];
<FONT COLOR="#298C52">if</FONT> (!bcs-&gt;hw.hfc.tx_skb)
<FONT COLOR="#298C52">return</FONT>;
<FONT COLOR="#298C52">if</FONT> (bcs-&gt;hw.hfc.tx_skb-&gt;len &lt;= 0)
<FONT COLOR="#298C52">return</FONT>;
save_flags(flags);
cli();
cip = HFC_CIP | HFC_F1 | HFC_SEND | HFC_CHANNEL(bcs-&gt;channel);
<FONT COLOR="#298C52">if</FONT> ((cip &amp; 0xc3) != (cs-&gt;hw.hfc.cip &amp; 0xc3)) {
cs-&gt;BC_Write_Reg(cs, HFC_STATUS, cip, cip);
WaitForBusy(cs);
}
WaitNoBusy(cs);
bcs-&gt;hw.hfc.f1 = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs-&gt;channel);
WaitNoBusy(cs);
bcs-&gt;hw.hfc.f2 = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
bcs-&gt;hw.hfc.send[bcs-&gt;hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs-&gt;channel));
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) {
sprintf(tmp, <FONT COLOR="#FF0000">"hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)"</FONT>,
bcs-&gt;channel, bcs-&gt;hw.hfc.f1, bcs-&gt;hw.hfc.f2,
bcs-&gt;hw.hfc.send[bcs-&gt;hw.hfc.f1]);
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, tmp);
}
fcnt = bcs-&gt;hw.hfc.f1 - bcs-&gt;hw.hfc.f2;
<FONT COLOR="#298C52">if</FONT> (fcnt &lt; 0)
fcnt += 32;
<FONT COLOR="#298C52">if</FONT> (fcnt &gt; 30) {
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>)
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"hfc_fill_fifo more as 30 frames"</FONT>);
restore_flags(flags);
<FONT COLOR="#298C52">return</FONT>;
}
count = GetFreeFifoBytes(bcs);
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) {
sprintf(tmp, <FONT COLOR="#FF0000">"hfc_fill_fifo %d count(%d/%d)"</FONT>,
bcs-&gt;channel, bcs-&gt;hw.hfc.tx_skb-&gt;len,
count);
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, tmp);
}
<FONT COLOR="#298C52">if</FONT> (count &lt; bcs-&gt;hw.hfc.tx_skb-&gt;len) {
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>)
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"hfc_fill_fifo no fifo mem"</FONT>);
restore_flags(flags);
<FONT COLOR="#298C52">return</FONT>;
}
cip = HFC_CIP | HFC_FIFO_IN | HFC_SEND | HFC_CHANNEL(bcs-&gt;channel);
idx = 0;
<FONT COLOR="#298C52">while</FONT> ((idx &lt; bcs-&gt;hw.hfc.tx_skb-&gt;len) &amp;&amp; WaitNoBusy(cs))
cs-&gt;BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs-&gt;hw.hfc.tx_skb-&gt;data[idx++]);
<FONT COLOR="#298C52">if</FONT> (idx != bcs-&gt;hw.hfc.tx_skb-&gt;len) {
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, <FONT COLOR="#FF0000">"FIFO Send BUSY error"</FONT>);
printk(KERN_WARNING <FONT COLOR="#FF0000">"HFC S FIFO channel %d BUSY Error\n"</FONT>, bcs-&gt;channel);
} <FONT COLOR="#298C52">else</FONT> {
count = bcs-&gt;hw.hfc.tx_skb-&gt;len;
bcs-&gt;tx_cnt -= count;
<FONT COLOR="#298C52">if</FONT> (<A HREF="hisax.h.shtml#PACKET_NOACK">PACKET_NOACK</A> == bcs-&gt;hw.hfc.tx_skb-&gt;pkt_type)
count = -1;
dev_kfree_skb(bcs-&gt;hw.hfc.tx_skb);
bcs-&gt;hw.hfc.tx_skb = NULL;
WaitForBusy(cs);
WaitNoBusy(cs);
cs-&gt;BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs-&gt;channel));
<FONT COLOR="#298C52">if</FONT> (bcs-&gt;st-&gt;lli.l1writewakeup &amp;&amp; (count &gt;= 0))
bcs-&gt;st-&gt;lli.l1writewakeup(bcs-&gt;st, count);
test_and_clear_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;bcs-&gt;Flag);
}
restore_flags(flags);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">void</FONT>
main_irq_hfc(<FONT COLOR="#298C52">struct</FONT> BCState *bcs)
{
<FONT COLOR="#298C52">long</FONT> flags;
<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs = bcs-&gt;cs;
<FONT COLOR="#298C52">int</FONT> z1, z2, rcnt;
u_char f1, f2, cip;
<FONT COLOR="#298C52">int</FONT> receive, transmit, count = 5;
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb;
<FONT COLOR="#298C52">char</FONT> tmp[64];
save_flags(flags);
Begin:
cli();
count--;
cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
<FONT COLOR="#298C52">if</FONT> ((cip &amp; 0xc3) != (cs-&gt;hw.hfc.cip &amp; 0xc3)) {
cs-&gt;BC_Write_Reg(cs, HFC_STATUS, cip, cip);
WaitForBusy(cs);
}
WaitNoBusy(cs);
f1 = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel);
WaitNoBusy(cs);
f2 = cs-&gt;BC_Read_Reg(cs, HFC_DATA, cip);
<FONT COLOR="#298C52">if</FONT> (f1 != f2) {
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) {
sprintf(tmp, <FONT COLOR="#FF0000">"hfc rec %d f1(%d) f2(%d)"</FONT>,
bcs-&gt;channel, f1, f2);
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, tmp);
}
WaitForBusy(cs);
z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel));
z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs-&gt;channel));
rcnt = z1 - z2;
<FONT COLOR="#298C52">if</FONT> (rcnt &lt; 0)
rcnt += cs-&gt;hw.hfc.fifosize;
rcnt++;
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) {
sprintf(tmp, <FONT COLOR="#FF0000">"hfc rec %d z1(%x) z2(%x) cnt(%d)"</FONT>,
bcs-&gt;channel, z1, z2, rcnt);
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, tmp);
}
<FONT COLOR=#0000FF>/* sti(); */</FONT>
<FONT COLOR="#298C52">if</FONT> ((skb = hfc_empty_fifo(bcs, rcnt))) {
skb_queue_tail(&amp;bcs-&gt;rqueue, skb);
hfc_sched_event(bcs, <A HREF="isdnl1.h.shtml#B_RCVBUFREADY">B_RCVBUFREADY</A>);
}
receive = 1;
} <FONT COLOR="#298C52">else</FONT>
receive = 0;
restore_flags(flags);
udelay(1);
cli();
<FONT COLOR="#298C52">if</FONT> (bcs-&gt;hw.hfc.tx_skb) {
transmit = 1;
test_and_set_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;bcs-&gt;Flag);
hfc_fill_fifo(bcs);
<FONT COLOR="#298C52">if</FONT> (test_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;bcs-&gt;Flag))
transmit = 0;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR="#298C52">if</FONT> ((bcs-&gt;hw.hfc.tx_skb = skb_dequeue(&amp;bcs-&gt;squeue))) {
transmit = 1;
test_and_set_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;bcs-&gt;Flag);
hfc_fill_fifo(bcs);
<FONT COLOR="#298C52">if</FONT> (test_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;bcs-&gt;Flag))
transmit = 0;
} <FONT COLOR="#298C52">else</FONT> {
transmit = 0;
hfc_sched_event(bcs, <A HREF="isdnl1.h.shtml#B_XMTBUFREADY">B_XMTBUFREADY</A>);
}
}
restore_flags(flags);
<FONT COLOR="#298C52">if</FONT> ((receive || transmit) &amp;&amp; count)
<FONT COLOR="#298C52">goto</FONT> Begin;
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">void</FONT>
mode_hfc(<FONT COLOR="#298C52">struct</FONT> BCState *bcs, <FONT COLOR="#298C52">int</FONT> mode, <FONT COLOR="#298C52">int</FONT> bc)
{
<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs = bcs-&gt;cs;
<FONT COLOR="#298C52">if</FONT> (cs-&gt;debug &amp; <A HREF="isdnl1.h.shtml#L1_DEB_HSCX">L1_DEB_HSCX</A>) {
<FONT COLOR="#298C52">char</FONT> tmp[40];
sprintf(tmp, <FONT COLOR="#FF0000">"HFC 2BS0 mode %d bchan %d/%d"</FONT>,
mode, bc, bcs-&gt;channel);
<A HREF="isdnl1.c.shtml#debugl1">debugl1</A>(cs, tmp);
}
bcs-&gt;mode = mode;
<FONT COLOR="#298C52">switch</FONT> (mode) {
<FONT COLOR="#298C52">case</FONT> (<A HREF="hisax.h.shtml#L1_MODE_NULL">L1_MODE_NULL</A>):
<FONT COLOR="#298C52">if</FONT> (bc)
cs-&gt;hw.hfc.isac_spcr &amp;= ~0x03;
<FONT COLOR="#298C52">else</FONT>
cs-&gt;hw.hfc.isac_spcr &amp;= ~0x0c;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> (<A HREF="hisax.h.shtml#L1_MODE_TRANS">L1_MODE_TRANS</A>):
<FONT COLOR="#298C52">if</FONT> (bc) {
cs-&gt;hw.hfc.ctmt |= 1;
cs-&gt;hw.hfc.isac_spcr &amp;= ~0x03;
cs-&gt;hw.hfc.isac_spcr |= 0x02;
} <FONT COLOR="#298C52">else</FONT> {
cs-&gt;hw.hfc.ctmt |= 2;
cs-&gt;hw.hfc.isac_spcr &amp;= ~0x0c;
cs-&gt;hw.hfc.isac_spcr |= 0x08;
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> (<A HREF="hisax.h.shtml#L1_MODE_HDLC">L1_MODE_HDLC</A>):
<FONT COLOR="#298C52">if</FONT> (bc) {
cs-&gt;hw.hfc.ctmt &amp;= ~1;
cs-&gt;hw.hfc.isac_spcr &amp;= ~0x03;
cs-&gt;hw.hfc.isac_spcr |= 0x02;
} <FONT COLOR="#298C52">else</FONT> {
cs-&gt;hw.hfc.ctmt &amp;= ~2;
cs-&gt;hw.hfc.isac_spcr &amp;= ~0x0c;
cs-&gt;hw.hfc.isac_spcr |= 0x08;
}
<FONT COLOR="#298C52">break</FONT>;
}
cs-&gt;BC_Write_Reg(cs, HFC_STATUS, cs-&gt;hw.hfc.ctmt, cs-&gt;hw.hfc.ctmt);
cs-&gt;writeisac(cs, <A HREF="isac.h.shtml#ISAC_SPCR">ISAC_SPCR</A>, cs-&gt;hw.hfc.isac_spcr);
<FONT COLOR="#298C52">if</FONT> (mode)
hfc_clear_fifo(bcs);
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
hfc_l2l1(<FONT COLOR="#298C52">struct</FONT> PStack *st, <FONT COLOR="#298C52">int</FONT> pr, <FONT COLOR="#298C52">void</FONT> *arg)
{
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb = arg;
<FONT COLOR="#298C52">long</FONT> flags;
<FONT COLOR="#298C52">switch</FONT> (pr) {
<FONT COLOR="#298C52">case</FONT> (<A HREF="hisax.h.shtml#PH_DATA">PH_DATA</A> | <A HREF="hisax.h.shtml#REQUEST">REQUEST</A>):
save_flags(flags);
cli();
<FONT COLOR="#298C52">if</FONT> (st-&gt;l1.bcs-&gt;hw.hfc.tx_skb) {
skb_queue_tail(&amp;st-&gt;l1.bcs-&gt;squeue, skb);
restore_flags(flags);
} <FONT COLOR="#298C52">else</FONT> {
st-&gt;l1.bcs-&gt;hw.hfc.tx_skb = skb;
test_and_set_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;st-&gt;l1.bcs-&gt;Flag);
st-&gt;l1.bcs-&gt;cs-&gt;BC_Send_Data(st-&gt;l1.bcs);
restore_flags(flags);
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> (<A HREF="hisax.h.shtml#PH_PULL">PH_PULL</A> | <A HREF="hisax.h.shtml#INDICATION">INDICATION</A>):
<FONT COLOR="#298C52">if</FONT> (st-&gt;l1.bcs-&gt;hw.hfc.tx_skb) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"hfc_l2l1: this shouldn't happen\n"</FONT>);
<FONT COLOR="#298C52">break</FONT>;
}
save_flags(flags);
cli();
test_and_set_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;st-&gt;l1.bcs-&gt;Flag);
st-&gt;l1.bcs-&gt;hw.hfc.tx_skb = skb;
st-&gt;l1.bcs-&gt;cs-&gt;BC_Send_Data(st-&gt;l1.bcs);
restore_flags(flags);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> (<A HREF="hisax.h.shtml#PH_PULL">PH_PULL</A> | <A HREF="hisax.h.shtml#REQUEST">REQUEST</A>):
<FONT COLOR="#298C52">if</FONT> (!st-&gt;l1.bcs-&gt;hw.hfc.tx_skb) {
test_and_clear_bit(<A HREF="hisax.h.shtml#FLG_L1_PULL_REQ">FLG_L1_PULL_REQ</A>, &amp;st-&gt;l1.Flags);
st-&gt;l1.l1l2(st, <A HREF="hisax.h.shtml#PH_PULL">PH_PULL</A> | <A HREF="hisax.h.shtml#CONFIRM">CONFIRM</A>, NULL);
} <FONT COLOR="#298C52">else</FONT>
test_and_set_bit(<A HREF="hisax.h.shtml#FLG_L1_PULL_REQ">FLG_L1_PULL_REQ</A>, &amp;st-&gt;l1.Flags);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> (<A HREF="hisax.h.shtml#PH_ACTIVATE">PH_ACTIVATE</A> | <A HREF="hisax.h.shtml#REQUEST">REQUEST</A>):
test_and_set_bit(<A HREF="hisax.h.shtml#BC_FLG_ACTIV">BC_FLG_ACTIV</A>, &amp;st-&gt;l1.bcs-&gt;Flag);
mode_hfc(st-&gt;l1.bcs, st-&gt;l1.mode, st-&gt;l1.bc);
st-&gt;l1.l1l2(st, <A HREF="hisax.h.shtml#PH_ACTIVATE">PH_ACTIVATE</A> | <A HREF="hisax.h.shtml#CONFIRM">CONFIRM</A>, NULL);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> (<A HREF="hisax.h.shtml#PH_DEACTIVATE">PH_DEACTIVATE</A> | <A HREF="hisax.h.shtml#REQUEST">REQUEST</A>):
<FONT COLOR="#298C52">if</FONT> (!test_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;st-&gt;l1.bcs-&gt;Flag))
mode_hfc(st-&gt;l1.bcs, 0, 0);
test_and_clear_bit(<A HREF="hisax.h.shtml#BC_FLG_ACTIV">BC_FLG_ACTIV</A>, &amp;st-&gt;l1.bcs-&gt;Flag);
<FONT COLOR="#298C52">break</FONT>;
}
}
<FONT COLOR="#298C52">void</FONT>
close_hfcstate(<FONT COLOR="#298C52">struct</FONT> BCState *bcs)
{
mode_hfc(bcs, 0, 0);
<FONT COLOR="#298C52">if</FONT> (test_bit(<A HREF="hisax.h.shtml#BC_FLG_INIT">BC_FLG_INIT</A>, &amp;bcs-&gt;Flag)) {
<A HREF="callc.c.shtml#discard_queue">discard_queue</A>(&amp;bcs-&gt;rqueue);
<A HREF="callc.c.shtml#discard_queue">discard_queue</A>(&amp;bcs-&gt;squeue);
<FONT COLOR="#298C52">if</FONT> (bcs-&gt;hw.hfc.tx_skb) {
dev_kfree_skb(bcs-&gt;hw.hfc.tx_skb);
bcs-&gt;hw.hfc.tx_skb = NULL;
test_and_clear_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;bcs-&gt;Flag);
}
}
test_and_clear_bit(<A HREF="hisax.h.shtml#BC_FLG_INIT">BC_FLG_INIT</A>, &amp;bcs-&gt;Flag);
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
open_hfcstate(<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs,
<FONT COLOR="#298C52">int</FONT> bc)
{
<FONT COLOR="#298C52">struct</FONT> BCState *bcs = cs-&gt;bcs + bc;
<FONT COLOR="#298C52">if</FONT> (!test_and_set_bit(<A HREF="hisax.h.shtml#BC_FLG_INIT">BC_FLG_INIT</A>, &amp;bcs-&gt;Flag)) {
skb_queue_head_init(&amp;bcs-&gt;rqueue);
skb_queue_head_init(&amp;bcs-&gt;squeue);
}
bcs-&gt;hw.hfc.tx_skb = NULL;
test_and_clear_bit(<A HREF="hisax.h.shtml#BC_FLG_BUSY">BC_FLG_BUSY</A>, &amp;bcs-&gt;Flag);
bcs-&gt;event = 0;
bcs-&gt;tx_cnt = 0;
<FONT COLOR="#298C52">return</FONT> (0);
}
<FONT COLOR="#298C52">int</FONT>
setstack_hfc(<FONT COLOR="#298C52">struct</FONT> PStack *st, <FONT COLOR="#298C52">struct</FONT> BCState *bcs)
{
<FONT COLOR="#298C52">if</FONT> (open_hfcstate(st-&gt;l1.hardware, bcs-&gt;channel))
<FONT COLOR="#298C52">return</FONT> (-1);
st-&gt;l1.bcs = bcs;
st-&gt;l2.l2l1 = hfc_l2l1;
<A HREF="lmgr.c.shtml#setstack_manager">setstack_manager</A>(st);
bcs-&gt;st = st;
<FONT COLOR="#298C52">return</FONT> (0);
}
<A HREF="asuscom.c.shtml#__initfunc">__initfunc</A>(<FONT COLOR="#298C52">void</FONT>
init_send(<FONT COLOR="#298C52">struct</FONT> BCState *bcs))
{
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">if</FONT> (!(bcs-&gt;hw.hfc.send = kmalloc(32 * <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">int</FONT>), GFP_ATOMIC))) {
printk(KERN_WARNING
<FONT COLOR="#FF0000">"HiSax: No memory for hfc.send\n"</FONT>);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; 32; i++)
bcs-&gt;hw.hfc.send[i] = 0x1fff;
}
<A HREF="asuscom.c.shtml#__initfunc">__initfunc</A>(<FONT COLOR="#298C52">void</FONT>
inithfc(<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs))
{
init_send(&amp;cs-&gt;bcs[0]);
init_send(&amp;cs-&gt;bcs[1]);
cs-&gt;BC_Send_Data = &amp;hfc_fill_fifo;
cs-&gt;bcs[0].BC_SetStack = setstack_hfc;
cs-&gt;bcs[1].BC_SetStack = setstack_hfc;
cs-&gt;bcs[0].BC_Close = close_hfcstate;
cs-&gt;bcs[1].BC_Close = close_hfcstate;
mode_hfc(cs-&gt;bcs, 0, 0);
mode_hfc(cs-&gt;bcs + 1, 0, 0);
}
<FONT COLOR="#298C52">void</FONT>
releasehfc(<FONT COLOR="#298C52">struct</FONT> IsdnCardState *cs)
{
<FONT COLOR="#298C52">if</FONT> (cs-&gt;bcs[0].hw.hfc.send) {
kfree(cs-&gt;bcs[0].hw.hfc.send);
cs-&gt;bcs[0].hw.hfc.send = NULL;
}
<FONT COLOR="#298C52">if</FONT> (cs-&gt;bcs[1].hw.hfc.send) {
kfree(cs-&gt;bcs[1].hw.hfc.send);
cs-&gt;bcs[1].hw.hfc.send = NULL;
}
}
</BODY>
</HTML>