/* $Id: netjet.c,v 1.29.2.4 2004/02/11 13:21:34 keil Exp $
*
* low level stuff for Traverse Technologie NETJet ISDN cards
*
* Author Karsten Keil
* Copyright by Karsten Keil <keil@isdn4linux.de>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
* Thanks to Traverse Technologies Australia for documents and information
*
* 16-Apr-2002 - led code added - Guy Ellis (guy@traverse.com.au)
*
*/
#include <linux/init.h>
#include "hisax.h"
#include "isac.h"
#include "hscx.h"
#include "isdnl1.h"
#include <linux/interrupt.h>
#include <linux/ppp_defs.h>
#include <linux/slab.h>
#include <asm/io.h>
#include "netjet.h"
/* Interface functions */
u_char
NETjet_ReadIC(struct IsdnCardState *cs, u_char offset)
{
u_char ret;
cs->hw.njet.auxd &= 0xfc;
cs->hw.njet.auxd |= (offset >> 4) & 3;
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
ret = bytein(cs->hw.njet.isac + ((offset & 0xf) << 2));
return (ret);
}
void
NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value)
{
cs->hw.njet.auxd &= 0xfc;
cs->hw.njet.auxd |= (offset >> 4) & 3;
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
byteout(cs->hw.njet.isac + ((offset & 0xf) << 2), value);
}
void
NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size)
{
cs->hw.njet.auxd &= 0xfc;
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
insb(cs->hw.njet.isac, data, size);
}
void
NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
{
cs->hw.njet.auxd &= 0xfc;
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
outsb(cs->hw.njet.isac, data, size);
}
static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
{
u_int mask = 0x000000ff, val = 0, *p = pos;
u_int i;
val |= fill;
if (chan) {
val <<= 8;
mask <<= 8;
}
mask ^= 0xffffffff;
for (i = 0; i < cnt; i++) {
*p &= mask;
*p++ |= val;
if (p > bcs->hw.tiger.s_end)
p = bcs->hw.tiger.send;
}
}
static void
mode_tiger(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
u_char led;
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "Tiger mode %d bchan %d/%d",
mode, bc, bcs->channel);
bcs->mode = mode;
bcs->channel = bc;
switch (mode) {
case (L1_MODE_NULL):
fill_mem(bcs, bcs->hw.tiger.send,
NETJET_DMA_TXSIZE, bc, 0xff);
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "Tiger stat rec %d/%d send %d",
bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err,
bcs->hw.tiger.s_tot);
if ((cs->bcs[0].mode == L1_MODE_NULL) &&
(cs->bcs[1].mode == L1_MODE_NULL)) {
cs->hw.njet.dmactrl = 0;
byteout(cs->hw.njet.base + NETJET_DMACTRL,
cs->hw.njet.dmactrl);
byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
}
if (cs->typ == ISDN_CTYPE_NETJET_S)
{
// led off
led = bc & 0x01;