Пример #1
0
int iavc_send(capi_softc_t *capi_sc, struct mbuf *m)
{
    iavc_softc_t *sc = (iavc_softc_t*) capi_sc->ctx;

    if (sc->sc_state != IAVC_UP) {
	printf("iavc%d: attempt to send before device up\n", sc->sc_unit);

	if (m->m_next) i4b_Bfreembuf(m->m_next);
	i4b_Dfreembuf(m);

	return (ENXIO);
    }

    if (_IF_QFULL(&sc->sc_txq)) {
#if defined (__FreeBSD__) && __FreeBSD__ > 4
	_IF_DROP(&sc->sc_txq);
#else
	IF_DROP(&sc->sc_txq);
#endif

	printf("iavc%d: tx overflow, message dropped\n", sc->sc_unit);

	if (m->m_next) i4b_Bfreembuf(m->m_next);
	i4b_Dfreembuf(m);

    } else {
	_IF_ENQUEUE(&sc->sc_txq, m);

	iavc_start_tx(sc);
    }
    
    return 0;
}
Пример #2
0
int iavc_send(capi_softc_t *capi_sc, struct mbuf *m)
{
    iavc_softc_t *sc = (iavc_softc_t*) capi_sc->ctx;

    if (sc->sc_state != IAVC_UP) {
	aprint_error_dev(&sc->sc_dev, "attempt to send before device up\n");

	if (m->m_next) i4b_Bfreembuf(m->m_next);
	i4b_Dfreembuf(m);

	return (ENXIO);
    }

    if (IF_QFULL(&sc->sc_txq)) {
	IF_DROP(&sc->sc_txq);

	aprint_error_dev(&sc->sc_dev, "tx overflow, message dropped\n");

	if (m->m_next) i4b_Bfreembuf(m->m_next);
	i4b_Dfreembuf(m);

    } else {
	IF_ENQUEUE(&sc->sc_txq, m);

	iavc_start_tx(sc);
    }

    return 0;
}
Пример #3
0
/*---------------------------------------------------------------------------*
 *	i4bputqueue_hipri - put message into front of queue to userland
 *---------------------------------------------------------------------------*/
void
i4bputqueue_hipri(struct mbuf *m)
{
    if(!openflag)
    {
        i4b_Dfreembuf(m);
        return;
    }

    crit_enter();

    if(IF_QFULL(&i4b_rdqueue))
    {
        struct mbuf *m1;
        IF_DEQUEUE(&i4b_rdqueue, m1);
        i4b_Dfreembuf(m1);
        NDBGL4(L4_ERR, "ERROR, queue full, removing entry!");
    }

    IF_PREPEND(&i4b_rdqueue, m);

    crit_exit();

    if(readflag)
    {
        readflag = 0;
        wakeup((caddr_t) &i4b_rdqueue);
    }

    KNOTE(&kq_rd_info.ki_note, 0);
}
Пример #4
0
/*---------------------------------------------------------------------------*
 *	I.430 Timer T3 expire function
 *---------------------------------------------------------------------------*/
static void
timer3_expired(struct isic_softc *sc)
{
	if(sc->sc_I430T3)
	{
		NDBGL1(L1_T_ERR, "state = %s", isic_printstate(sc));
		sc->sc_I430T3 = 0;

		/* XXX try some recovery here XXX */
		switch(sc->sc_cardtyp) {
#if NNISACSX > 0
			case CARD_TYPEP_AVMA1PCIV2:
				isic_isacsx_recover(sc);
				break;
#endif /* NNISACSX > 0 */
			default:
#if NNISAC > 0
				isic_recover(sc);
#endif /* NNISAC > 0 */
				break;
		}

		sc->sc_init_tries++;	/* increment retry count */

/*XXX*/		if(sc->sc_init_tries > 4)
		{
			int s = splnet();

			sc->sc_init_tries = 0;

			if(sc->sc_obuf2 != NULL)
			{
				i4b_Dfreembuf(sc->sc_obuf2);
				sc->sc_obuf2 = NULL;
			}
			if(sc->sc_obuf != NULL)
			{
				i4b_Dfreembuf(sc->sc_obuf);
				sc->sc_obuf = NULL;
				sc->sc_freeflag = 0;
				sc->sc_op = NULL;
				sc->sc_ol = 0;
			}

			splx(s);

			isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_NOL1ACC, 0);
		}

		isic_next_state(sc, EV_T3);
	}
	else
	{
		NDBGL1(L1_T_ERR, "expired without starting it ....");
	}
}
Пример #5
0
/*---------------------------------------------------------------------------*
 *	i4bread - device driver read routine
 *---------------------------------------------------------------------------*/
PDEVSTATIC int
i4bread(dev_t dev, struct uio *uio, int ioflag)
{
	struct mbuf *m;
	int x;
	int error = 0;

	if(minor(dev))
		return(ENODEV);

	while(IF_QEMPTY(&i4b_rdqueue))
	{
		x = splimp();
		readflag = 1;
		splx(x);
		tsleep((caddr_t) &i4b_rdqueue, (PZERO + 1) | PCATCH, "bird", 0);
	}

	x = splimp();

	IF_DEQUEUE(&i4b_rdqueue, m);

	splx(x);
		
	if(m && m->m_len)
		error = uiomove(m->m_data, m->m_len, uio);
	else
		error = EIO;
		
	if(m)
		i4b_Dfreembuf(m);

	return(error);
}
Пример #6
0
/*---------------------------------------------------------------------------*
 *	got s or i frame, check if valid ack for last sent frame
 *---------------------------------------------------------------------------*/
void
i4b_rxd_ack(l2_softc_t *l2sc, int nr)
{

#ifdef NOTDEF
	NDBGL2(L2_ERROR, "N(R)=%d, UA=%d, V(R)=%d, V(S)=%d, V(A)=%d",
		nr,
		l2sc->ua_num,
		l2sc->vr,
		l2sc->vs,
		l2sc->va);
#endif

	if(l2sc->ua_num != UA_EMPTY)
	{
		CRIT_VAR;

		CRIT_BEG;
		
		M128DEC(nr);

		if(l2sc->ua_num != nr)
			NDBGL2(L2_ERROR, "((N(R)-1)=%d) != (UA=%d) !!!", nr, l2sc->ua_num);
			
		i4b_Dfreembuf(l2sc->ua_frame);
		l2sc->ua_num = UA_EMPTY;
		
		CRIT_END;
	}
}
Пример #7
0
/*---------------------------------------------------------------------------*
 *	got s or i frame, check if valid ack for last sent frame
 *---------------------------------------------------------------------------*/
void
i4b_rxd_ack(l2_softc_t *l2sc, struct isdn_l3_driver *drv, int nr)
{

#ifdef NOTDEF
	NDBGL2(L2_ERROR, "N(R)=%d, UA=%d, V(R)=%d, V(S)=%d, V(A)=%d",
		nr,
		l2sc->ua_num,
		l2sc->vr,
		l2sc->vs,
		l2sc->va);
#endif

	if(l2sc->ua_num != UA_EMPTY)
	{
		int s;

		s = splnet();
		
		M128DEC(nr);

		if(l2sc->ua_num != nr)
			NDBGL2(L2_ERROR, "((N(R)-1)=%d) != (UA=%d) !!!", nr, l2sc->ua_num);
			
		i4b_Dfreembuf(l2sc->ua_frame);
		l2sc->ua_num = UA_EMPTY;
		
		splx(s);
	}
}
Пример #8
0
/*---------------------------------------------------------------------------*
 *	i4bread - device driver read routine
 *---------------------------------------------------------------------------*/
PDEVSTATIC int
i4bread(struct dev_read_args *ap)
{
    cdev_t dev = ap->a_head.a_dev;
    struct mbuf *m;
    int error = 0;

    if (minor(dev))
        return(ENODEV);

    crit_enter();
    while(IF_QEMPTY(&i4b_rdqueue))
    {
        readflag = 1;
        error = tsleep((caddr_t) &i4b_rdqueue, PCATCH, "bird", 0);
        if (error != 0) {
            crit_exit();
            return error;
        }
    }

    IF_DEQUEUE(&i4b_rdqueue, m);

    crit_exit();

    if(m && m->m_len)
        error = uiomove(m->m_data, m->m_len, ap->a_uio);
    else
        error = EIO;

    if(m)
        i4b_Dfreembuf(m);

    return(error);
}
Пример #9
0
/*---------------------------------------------------------------------------*
 *	i4bread - device driver read routine
 *---------------------------------------------------------------------------*/
PDEVSTATIC int
isdnread(dev_t dev, struct uio *uio, int ioflag)
{
	struct mbuf *m;
	int x;
	int error = 0;

	if(minor(dev))
		return(ENODEV);

	x = splnet();
	while(IF_QEMPTY(&i4b_rdqueue))
	{
		readflag = 1;
		error = tsleep((void *) &i4b_rdqueue, (PZERO + 1) | PCATCH, "bird", 0);
		if (error != 0) {
			splx(x);
			return error;
		}
	}

	IF_DEQUEUE(&i4b_rdqueue, m);

	splx(x);

	if(m && m->m_len)
		error = uiomove(m->m_data, m->m_len, uio);
	else
		error = EIO;

	if(m)
		i4b_Dfreembuf(m);

	return(error);
}
Пример #10
0
/*---------------------------------------------------------------------------*
 *	got s or i frame, check if valid ack for last sent frame
 *---------------------------------------------------------------------------*/
void
i4b_rxd_ack(l2_softc_t *l2sc, int nr)
{

#ifdef NOTDEF
	DBGL2(L2_ERROR, "i4b_rxd_ack", ("N(R)=%d, UA=%d, V(R)=%d, V(S)=%d, V(A)=%d\n",
		nr,
		l2sc->ua_num,
		l2sc->vr,
		l2sc->vs,
		l2sc->va));
#endif

	if(l2sc->ua_num != UA_EMPTY)
	{
		int s;
		
		M128DEC(nr);

		if(l2sc->ua_num != nr)
			DBGL2(L2_ERROR, "i4b_rxd_ack", ("((N(R)-1)=%d) != (UA=%d) !!!\n", nr, l2sc->ua_num));
			
		s = SPLI4B();
		
		i4b_Dfreembuf(l2sc->ua_frame);
		l2sc->ua_num = UA_EMPTY;
		
		splx(s);
	}
}
Пример #11
0
/*---------------------------------------------------------------------------*
 *	routine CLEAR EXCEPTION CONDITIONS (Q.921 03/93 page 83)
 *---------------------------------------------------------------------------*/
void
i4b_clear_exception_conditions(l2_softc_t *l2sc)
{
	CRIT_VAR;

	CRIT_BEG;
	
/*XXX -------------------------------------------------------------- */
/*XXX is this really appropriate here or should it moved elsewhere ? */

	i4b_Dcleanifq(&l2sc->i_queue);
	
	if(l2sc->ua_num != UA_EMPTY)
	{
		i4b_Dfreembuf(l2sc->ua_frame);
		l2sc->ua_num = UA_EMPTY;
	}
/*XXX -------------------------------------------------------------- */

	l2sc->peer_busy = 0;

	l2sc->rej_excpt = 0;

	l2sc->own_busy = 0;

	l2sc->ack_pend = 0;	

	CRIT_END;	
}
Пример #12
0
/*---------------------------------------------------------------------------*
 *	I.430 Timer T3 expire function
 *---------------------------------------------------------------------------*/	
static void
timer3_expired(struct l1_softc *sc)
{
	if(sc->sc_I430T3)
	{
		NDBGL1(L1_T_ERR, "state = %s", ifpnp_printstate(sc));
		sc->sc_I430T3 = 0;

		/* XXX try some recovery here XXX */

		ifpnp_recover(sc);

		sc->sc_init_tries++;	/* increment retry count */

/*XXX*/		if(sc->sc_init_tries > 4)
		{
			int s = SPLI4B();

			sc->sc_init_tries = 0;
			
			if(sc->sc_obuf2 != NULL)
			{
				i4b_Dfreembuf(sc->sc_obuf2);
				sc->sc_obuf2 = NULL;
			}
			if(sc->sc_obuf != NULL)
			{
				i4b_Dfreembuf(sc->sc_obuf);
				sc->sc_obuf = NULL;
				sc->sc_freeflag = 0;
				sc->sc_op = NULL;
				sc->sc_ol = 0;
			}

			splx(s);

			i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL);
		}
		
		ifpnp_next_state(sc, EV_T3);		
	}
	else
	{
		NDBGL1(L1_T_ERR, "expired without starting it ....");
	}
}
Пример #13
0
/*---------------------------------------------------------------------------*
 *	dl_unit_data_ind - process a rx'd U-frame got from layer 2
 *---------------------------------------------------------------------------*/
int
i4b_dl_unit_data_ind(int unit, struct mbuf *m)
{
#ifdef NOTDEF
	DBGL2(L2_PRIM, "DL-UNIT-DATA-IND", ("unit %d\n",unit));
#endif
	i4b_decode_q931(unit, m->m_len, m->m_data);
	i4b_Dfreembuf(m);
	return(0);
}
Пример #14
0
static void iavc_start_tx(iavc_softc_t *sc)
{
    struct mbuf *m;
    u_int32_t txlen;

    /* If device has put us on hold, punt. */

    if (sc->sc_blocked) {
	return;
    }

    /* If using DMA and transmitter busy, punt. */
    if (sc->sc_dma && (sc->sc_csr & EN_TX_TC_INT)) {
	return;
    }

    /* Else, see if we have messages to send. */
    IF_DEQUEUE(&sc->sc_txq, m);
    if (!m) {
	return;
    }

    /* Have message, will send. */
    if (CAPIMSG_LEN(m->m_data)) {
	/* A proper CAPI message, possibly with B3 data */
	txlen = iavc_tx_capimsg(sc, m);
    } else {
	/* A board control message to be sent as is */
	txlen = iavc_tx_ctrlmsg(sc, m);
    }

    if (m->m_next) {
	i4b_Bfreembuf(m->m_next);
	m->m_next = NULL;
    }
    i4b_Dfreembuf(m);

    /* Kick DMA into motion if applicable */
    if (sc->sc_dma) {
	txlen = (txlen + 3) & ~3;

	bus_dmamap_sync(sc->dmat, sc->tx_map, 0, txlen,
	  BUS_DMASYNC_PREWRITE);

	AMCC_WRITE(sc, AMCC_TXPTR, sc->tx_map->dm_segs[0].ds_addr);
	AMCC_WRITE(sc, AMCC_TXLEN, txlen);
	sc->sc_csr |= EN_TX_TC_INT;

	if (!sc->sc_intr)
	    AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr);
    }
}
Пример #15
0
/*---------------------------------------------------------------------------*
 *	i4bputqueue_hipri - put message into front of queue to userland
 *---------------------------------------------------------------------------*/
void
i4bputqueue_hipri(struct mbuf *m)
{
	int x;
	
	if(!openflag)
	{
		i4b_Dfreembuf(m);
		return;
	}

	x = splimp();
	
	if(IF_QFULL(&i4b_rdqueue))
	{
		struct mbuf *m1;
		IF_DEQUEUE(&i4b_rdqueue, m1);
		i4b_Dfreembuf(m1);
		DBGL4(L4_ERR, "i4bputqueue", ("ERROR, queue full, removing entry!\n"));
	}

	IF_PREPEND(&i4b_rdqueue, m);

	splx(x);	

	if(readflag)
	{
		readflag = 0;
		wakeup((caddr_t) &i4b_rdqueue);
	}

	if(selflag)
	{
		selflag = 0;
		selwakeup(&select_rd_info);
	}
}
Пример #16
0
/*---------------------------------------------------------------------------*
 *	i4bputqueue_hipri - put message into front of queue to userland
 *---------------------------------------------------------------------------*/
void
i4bputqueue_hipri(struct mbuf *m)
{
	int x;

	if(!openflag)
	{
		i4b_Dfreembuf(m);
		return;
	}

	x = splnet();

	if(IF_QFULL(&i4b_rdqueue))
	{
		struct mbuf *m1;
		IF_DEQUEUE(&i4b_rdqueue, m1);
		i4b_Dfreembuf(m1);
		NDBGL4(L4_ERR, "ERROR, queue full, removing entry!");
	}

	IF_PREPEND(&i4b_rdqueue, m);

	splx(x);

	if(readflag)
	{
		readflag = 0;
		wakeup((void *) &i4b_rdqueue);
	}

	if(selflag)
	{
		selflag = 0;
		selnotify(&select_rd_info, 0, 0);
	}
}
Пример #17
0
/*---------------------------------------------------------------------------*
 *	L2 -> L1: PH-DATA-REQUEST (D-Channel)
 *
 *	NOTE: We may get called here from ihfc_hdlc_Dread or isac_hdlc_Dread
 *	via the upper layers.
 *---------------------------------------------------------------------------*/
static int
ihfc_ph_data_req(int unit, struct mbuf *m, int freeflag)
{
	ihfc_sc_t *sc = &ihfc_softc[unit];
	u_char chan = 0;
	HFC_VAR;

	if (!m) return 0;

	HFC_BEG;

	if(S_PHSTATE != 3)
	{
		NDBGL1(L1_PRIM, "L1 was not running: "
			"ihfc_ph_activate_req(unit = %d)!", unit);

			ihfc_ph_activate_req(unit);
	}

	/* "Allow" I-frames (-hp) */

	if (freeflag == MBUF_DONTFREE)	m = m_copypacket(m, M_DONTWAIT);

	if (!_IF_QFULL(&S_IFQUEUE) && m)
	{
		IF_ENQUEUE(&S_IFQUEUE, m);

		ihfc_B_start(unit, chan);	/* (recycling) */
	}
	else
	{
		NDBGL1(L1_ERROR, "No frame out (unit = %d)", unit);
		if (m) i4b_Dfreembuf(m);

		HFC_END;
		return 0;
	}

	if (S_INTR_ACTIVE) S_INT_S1 |= 0x04;

	HFC_END;

	return 1;
}
Пример #18
0
/*---------------------------------------------------------------------------*
 *	ISACSX interrupt service routine
 *---------------------------------------------------------------------------*/
void
isic_isacsx_irq(struct isic_softc *sc, int ista)
{
	register u_char c = 0;
	register u_char istad = 0;

	NDBGL1(L1_F_MSG, "%s: ista = 0x%02x", device_xname(&sc->sc_dev), ista);

	/* was it an HDLC interrupt ? */
	if (ista & ISACSX_ISTA_ICD)
	{
		istad = ISAC_READ(I_ISTAD);
		NDBGL1(L1_F_MSG, "%s: istad = 0x%02x", device_xname(&sc->sc_dev), istad);

		if(istad & (ISACSX_ISTAD_RFO|ISACSX_ISTAD_XMR|ISACSX_ISTAD_XDU))
		{
			/* not really EXIR, but very similar */
			c |= isic_isacsx_exir_hdlr(sc, istad);
		}
	}

	if(istad & ISACSX_ISTAD_RME)	/* receive message end */
	{
		register int rest;
		u_char rsta;

		/* get rx status register */

		rsta = ISAC_READ(I_RSTAD);

		/* Check for Frame and CRC valid */
		if((rsta & ISACSX_RSTAD_MASK) != (ISACSX_RSTAD_VFR|ISACSX_RSTAD_CRC))
		{
			int error = 0;

			if(!(rsta & ISACSX_RSTAD_VFR))	/* VFR error */
			{
				error++;
				NDBGL1(L1_I_ERR, "%s: Frame not valid error", device_xname(&sc->sc_dev));
			}

			if(!(rsta & ISACSX_RSTAD_CRC))	/* CRC error */
			{
				error++;
				NDBGL1(L1_I_ERR, "%s: CRC error", device_xname(&sc->sc_dev));
			}

			if(rsta & ISACSX_RSTAD_RDO)	/* ReceiveDataOverflow */
			{
				error++;
				NDBGL1(L1_I_ERR, "%s: Data Overrun error", device_xname(&sc->sc_dev));
			}

			if(rsta & ISACSX_RSTAD_RAB)	/* ReceiveABorted */
			{
				error++;
				NDBGL1(L1_I_ERR, "%s: Receive Aborted error", device_xname(&sc->sc_dev));
			}

			if(error == 0)
				NDBGL1(L1_I_ERR, "%s: RME unknown error, RSTAD = 0x%02x!", device_xname(&sc->sc_dev), rsta);

			i4b_Dfreembuf(sc->sc_ibuf);

			c |= ISACSX_CMDRD_RMC|ISACSX_CMDRD_RRES;

			sc->sc_ibuf = NULL;
			sc->sc_ib = NULL;
			sc->sc_ilen = 0;

			ISAC_WRITE(I_CMDRD, ISACSX_CMDRD_RMC|ISACSX_CMDRD_RRES);

			return;
		}

		rest = (ISAC_READ(I_RBCLD) & (ISACSX_FIFO_LEN-1));

		if(rest == 0)
			rest = ISACSX_FIFO_LEN;

		if(sc->sc_ibuf == NULL)
		{
			if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
				sc->sc_ib = sc->sc_ibuf->m_data;
			else
				panic("isic_isacsx_irq: RME, i4b_Dgetmbuf returns NULL!\n");
			sc->sc_ilen = 0;
		}

		if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
		{
			ISAC_RDFIFO(sc->sc_ib, rest);
			 /* the  last byte contains status, strip it */
			sc->sc_ilen += rest - 1;

			sc->sc_ibuf->m_pkthdr.len =
				sc->sc_ibuf->m_len = sc->sc_ilen;

			if(sc->sc_trace & TRACE_D_RX)
			{
				i4b_trace_hdr hdr;

				memset(&hdr, 0, sizeof hdr);
				hdr.type = TRC_CH_D;
				hdr.dir = FROM_NT;
				hdr.count = ++sc->sc_trace_dcount;
				isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
			}

			c |= ISACSX_CMDRD_RMC;

			if(sc->sc_intr_valid == ISIC_INTR_VALID &&
			   (((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S))
			{
				isdn_layer2_data_ind(&sc->sc_l2, sc->sc_l3token, sc->sc_ibuf);
			}
			else
			{
				i4b_Dfreembuf(sc->sc_ibuf);
			}
		}
		else
		{
			NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
			i4b_Dfreembuf(sc->sc_ibuf);
			c |= ISACSX_CMDRD_RMC|ISACSX_CMDRD_RRES;
		}

		sc->sc_ibuf = NULL;
		sc->sc_ib = NULL;
		sc->sc_ilen = 0;
	}

	if(istad & ISACSX_ISTAD_RPF)	/* receive fifo full */
	{
		if(sc->sc_ibuf == NULL)
		{
			if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
				sc->sc_ib= sc->sc_ibuf->m_data;
			else
				panic("isic_isacsx_irq: RPF, i4b_Dgetmbuf returns NULL!\n");
			sc->sc_ilen = 0;
		}

		if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISACSX_FIFO_LEN))
		{
			ISAC_RDFIFO(sc->sc_ib, ISACSX_FIFO_LEN);
			sc->sc_ilen += ISACSX_FIFO_LEN;
			sc->sc_ib += ISACSX_FIFO_LEN;
			c |= ISACSX_CMDRD_RMC;
		}
		else
		{
			NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
			i4b_Dfreembuf(sc->sc_ibuf);
			sc->sc_ibuf = NULL;
			sc->sc_ib = NULL;
			sc->sc_ilen = 0;
			c |= ISACSX_CMDRD_RMC|ISACSX_CMDRD_RRES;
		}
	}

	if(istad & ISACSX_ISTAD_XPR)	/* transmit fifo empty (XPR bit set) */
	{
		if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
		{
			sc->sc_freeflag = sc->sc_freeflag2;
			sc->sc_obuf = sc->sc_obuf2;
			sc->sc_op = sc->sc_obuf->m_data;
			sc->sc_ol = sc->sc_obuf->m_len;
			sc->sc_obuf2 = NULL;
#ifdef NOTDEF
			printf("ob2=%x, op=%x, ol=%d, f=%d #",
				sc->sc_obuf,
				sc->sc_op,
				sc->sc_ol,
				sc->sc_state);
#endif
		}
		else
		{
#ifdef NOTDEF
			printf("ob=%x, op=%x, ol=%d, f=%d #",
				sc->sc_obuf,
				sc->sc_op,
				sc->sc_ol,
				sc->sc_state);
#endif
		}

		if(sc->sc_obuf)
		{
			ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISACSX_FIFO_LEN));

			if(sc->sc_ol > ISACSX_FIFO_LEN)	/* length > 32 ? */
			{
				sc->sc_op += ISACSX_FIFO_LEN; /* bufferptr+32 */
				sc->sc_ol -= ISACSX_FIFO_LEN; /* length - 32 */
				c |= ISACSX_CMDRD_XTF;	    /* set XTF bit */
			}
			else
			{
				if(sc->sc_freeflag)
				{
					i4b_Dfreembuf(sc->sc_obuf);
					sc->sc_freeflag = 0;
				}
				sc->sc_obuf = NULL;
				sc->sc_op = NULL;
				sc->sc_ol = 0;

				c |= ISACSX_CMDRD_XTF | ISACSX_CMDRD_XME;
			}
		}
		else
		{
			sc->sc_state &= ~ISAC_TX_ACTIVE;
		}
	}

	if(ista & ISACSX_ISTA_CIC)	/* channel status change CISQ */
	{
		register u_char ci;

		/* get command/indication rx register*/

		ci = ISAC_READ(I_CIR0);

		/* C/I code change IRQ (flag already cleared by CIR0 read) */

		if(ci & ISACSX_CIR0_CIC0)
			isic_isacsx_ind_hdlr(sc, (ci >> 4) & 0xf);
	}

	if(c)
	{
		ISAC_WRITE(I_CMDRD, c);
	}
}
Пример #19
0
static int iavc_receive(iavc_softc_t *sc, u_int8_t *dmabuf, int b3data)
{
    struct mbuf *m;
    u_int32_t ApplId, Length;

    /*
     * byte  0x21 = RECEIVE_MESSAGE
     * dword ApplId
     * dword length
     * ...   CAPI msg
     *
     * --or--
     *
     * byte  0x22 = RECEIVE_DATA_B3_IND
     * dword ApplId
     * dword length
     * ...   CAPI msg
     * dword datalen
     * ...   B3 data
     */

    if (sc->sc_dma) {
	dmabuf = amcc_get_word(dmabuf, &ApplId);
	dmabuf = amcc_get_word(dmabuf, &Length);
    } else {
	ApplId = iavc_get_word(sc);
	Length = iavc_get_slice(sc, sc->sc_recvbuf);
	dmabuf = sc->sc_recvbuf;
    }

    m = i4b_Dgetmbuf(Length);
    if (!m) {
	aprint_error_dev(&sc->sc_dev, "can't get memory for receive\n");
	return (ENOMEM);
    }

    memcpy(mtod(m, u_int8_t*), dmabuf, Length);

#if 0
	{
	    u_int8_t *p = mtod(m, u_int8_t*);
	    int len = 0;
	    printf("%s: applid=%d, len=%d\n", device_xname(&sc->sc_dev),
	      ApplId, Length);
	    while (len < m->m_len) {
		printf(" %02x", p[len]);
		if (len && (len % 16) == 0) printf("\n");
		len++;
	    }
	    if (len % 16) printf("\n");
	}
#endif

    if (b3data) {
	if (sc->sc_dma) {
	    dmabuf = amcc_get_word(dmabuf + Length, &Length);
	} else {
	    Length = iavc_get_slice(sc, sc->sc_recvbuf);
	    dmabuf = sc->sc_recvbuf;
	}

	m->m_next = i4b_Bgetmbuf(Length);
	if (!m->m_next) {
	    aprint_error_dev(&sc->sc_dev, "can't get memory for receive\n");
	    i4b_Dfreembuf(m);
	    return (ENOMEM);
	}

	memcpy(mtod(m->m_next, u_int8_t*), dmabuf, Length);
    }

    capi_ll_receive(&sc->sc_capi, m);
    return 0;
}
Пример #20
0
/*---------------------------------------------------------------------------*
 *	process a received U-frame
 *---------------------------------------------------------------------------*/
void
i4b_rxd_u_frame(int unit, struct mbuf *m)
{
	l2_softc_t *l2sc = &l2_softc[unit];
	u_char *ptr = m->m_data;

	int sapi = GETSAPI(*(ptr + OFF_SAPI));
	int tei = GETTEI(*(ptr + OFF_TEI));	
	int pfbit = GETUPF(*(ptr + OFF_CNTL));
	
	switch(*(ptr + OFF_CNTL) & ~UPFBIT)
	{
		/* commands */

		case SABME:
			if((l2sc->tei_valid == TEI_VALID) &&
			   (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
			{
				l2sc->stat.rx_sabme++;
				NDBGL2(L2_U_MSG, "SABME, sapi = %d, tei = %d", sapi, tei);
				l2sc->rxd_PF = pfbit;
				i4b_next_l2state(l2sc, EV_RXSABME);
			}
			i4b_Dfreembuf(m);
			break;

		case UI:
			if(sapi == SAPI_L2M &&
			   tei == GROUP_TEI &&
			   *(ptr + OFF_MEI) == MEI)
			{
				/* layer 2 management (SAPI = 63) */
				l2sc->stat.rx_tei++;
				i4b_tei_rxframe(unit, m);
			}
			else if(sapi == SAPI_CCP && tei == GROUP_TEI)
			{
				/* call control (SAPI = 0) */
				l2sc->stat.rx_ui++;
				/* strip ui header */
				m_adj(m, UI_HDR_LEN);
				/* to upper layer */
				DL_Unit_Data_Ind(unit, m);
			}
			else
			{
				l2sc->stat.err_rx_badui++;
				NDBGL2(L2_U_ERR, "unknown UI frame!");
				i4b_Dfreembuf(m);				
			}
			break;
			
		case DISC:
			if((l2sc->tei_valid == TEI_VALID) &&
			   (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
			{		
				l2sc->stat.rx_disc++;
				NDBGL2(L2_U_MSG, "DISC, sapi = %d, tei = %d", sapi, tei);
				l2sc->rxd_PF = pfbit;
				i4b_next_l2state(l2sc, EV_RXDISC);
			}
			i4b_Dfreembuf(m);
			break;

		case XID:
			if((l2sc->tei_valid == TEI_VALID) &&
			   (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
			{		
				l2sc->stat.rx_xid++;
				NDBGL2(L2_U_MSG, "XID, sapi = %d, tei = %d", sapi, tei);
			}
			i4b_Dfreembuf(m);			
			break;
			
		/* responses */

		case DM:
			if((l2sc->tei_valid == TEI_VALID) &&
			   (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
			{		
				l2sc->stat.rx_dm++;
				NDBGL2(L2_U_MSG, "DM, sapi = %d, tei = %d", sapi, tei);
				i4b_print_frame(m->m_len, m->m_data);
				l2sc->rxd_PF = pfbit;
				i4b_next_l2state(l2sc, EV_RXDM);
			}
			i4b_Dfreembuf(m);
			break;
			
		case UA:
			if((l2sc->tei_valid == TEI_VALID) &&
			   (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
			{		
				l2sc->stat.rx_ua++;
				NDBGL2(L2_U_MSG, "UA, sapi = %d, tei = %d", sapi, tei);
				l2sc->rxd_PF = pfbit;
				i4b_next_l2state(l2sc, EV_RXUA);
			}
			i4b_Dfreembuf(m);			
			break;			

		case FRMR:
			if((l2sc->tei_valid == TEI_VALID) &&
			   (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
			{
				l2sc->stat.rx_frmr++;
				NDBGL2(L2_U_MSG, "FRMR, sapi = %d, tei = %d", sapi, tei);
				l2sc->rxd_PF = pfbit;
				i4b_next_l2state(l2sc, EV_RXFRMR);
			}
			i4b_Dfreembuf(m);			
			break;

		default:
			if((l2sc->tei_valid == TEI_VALID) &&
			   (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
			{		
				NDBGL2(L2_U_ERR, "UNKNOWN TYPE ERROR, sapi = %d, tei = %d, frame = ", sapi, tei);
				i4b_print_frame(m->m_len, m->m_data);
			}
			else
			{		
				NDBGL2(L2_U_ERR, "not mine -  UNKNOWN TYPE ERROR, sapi = %d, tei = %d, frame = ", sapi, tei);
				i4b_print_frame(m->m_len, m->m_data);
			}
			l2sc->stat.err_rx_badui++;			
			i4b_Dfreembuf(m);			
			break;
	}
}
Пример #21
0
/*---------------------------------------------------------------------------*
 *	ISAC interrupt service routine
 *---------------------------------------------------------------------------*/
void
ifpnp_isac_irq(struct l1_softc *sc, int ista)
{
	u_char c = 0;
	NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista);

	if(ista & ISAC_ISTA_EXI)	/* extended interrupt */
	{
		c |= ifpnp_isac_exir_hdlr(sc, ISAC_READ(I_EXIR));
	}
	
	if(ista & ISAC_ISTA_RME)	/* receive message end */
	{
		int rest;
		u_char rsta;

		/* get rx status register */
		
		rsta = ISAC_READ(I_RSTA);

		if((rsta & ISAC_RSTA_MASK) != 0x20)
		{
			int error = 0;
			
			if(!(rsta & ISAC_RSTA_CRC))	/* CRC error */
			{
				error++;
				NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit);
			}
	
			if(rsta & ISAC_RSTA_RDO)	/* ReceiveDataOverflow */
			{
				error++;
				NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit);
			}
	
			if(rsta & ISAC_RSTA_RAB)	/* ReceiveABorted */
			{
				error++;
				NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit);
			}

			if(error == 0)			
				NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta);

			i4b_Dfreembuf(sc->sc_ibuf);

			c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;

			sc->sc_ibuf = NULL;
			sc->sc_ib = NULL;
			sc->sc_ilen = 0;

			ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES);
			ISACCMDRWRDELAY();

			return;
		}

		rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1));

		if(rest == 0)
			rest = ISAC_FIFO_LEN;

		if(sc->sc_ibuf == NULL)
		{
			if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
				sc->sc_ib = sc->sc_ibuf->m_data;
			else
				panic("ifpnp_isac_irq: RME, i4b_Dgetmbuf returns NULL!\n");
			sc->sc_ilen = 0;
		}

		if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
		{
			ISAC_RDFIFO(sc->sc_ib, rest);
			sc->sc_ilen += rest;
			
			sc->sc_ibuf->m_pkthdr.len =
				sc->sc_ibuf->m_len = sc->sc_ilen;

			if(sc->sc_trace & TRACE_D_RX)
			{
				i4b_trace_hdr_t hdr;
				hdr.unit = L0IFPNPUNIT(sc->sc_unit);
				hdr.type = TRC_CH_D;
				hdr.dir = FROM_NT;
				hdr.count = ++sc->sc_trace_dcount;
				MICROTIME(hdr.time);
				i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
			}

			c |= ISAC_CMDR_RMC;

			if(sc->sc_enabled &&
			   (ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S))
			{
				i4b_l1_ph_data_ind(L0IFPNPUNIT(sc->sc_unit), sc->sc_ibuf);
			}
			else
			{
				i4b_Dfreembuf(sc->sc_ibuf);
			}
		}
		else
		{
			NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
			i4b_Dfreembuf(sc->sc_ibuf);
			c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
		}

		sc->sc_ibuf = NULL;
		sc->sc_ib = NULL;
		sc->sc_ilen = 0;
	}

	if(ista & ISAC_ISTA_RPF)	/* receive fifo full */
	{
		if(sc->sc_ibuf == NULL)
		{
			if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
				sc->sc_ib= sc->sc_ibuf->m_data;
			else
				panic("ifpnp_isac_irq: RPF, i4b_Dgetmbuf returns NULL!\n");
			sc->sc_ilen = 0;
		}

		if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN))
		{
			ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN);
			sc->sc_ilen += ISAC_FIFO_LEN;			
			sc->sc_ib += ISAC_FIFO_LEN;
			c |= ISAC_CMDR_RMC;
		}
		else
		{
			NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
			i4b_Dfreembuf(sc->sc_ibuf);
			sc->sc_ibuf = NULL;
			sc->sc_ib = NULL;
			sc->sc_ilen = 0;
			c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;			
		}
	}

	if(ista & ISAC_ISTA_XPR)	/* transmit fifo empty (XPR bit set) */
	{
		if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
		{
			sc->sc_freeflag = sc->sc_freeflag2;
			sc->sc_obuf = sc->sc_obuf2;
			sc->sc_op = sc->sc_obuf->m_data;
			sc->sc_ol = sc->sc_obuf->m_len;
			sc->sc_obuf2 = NULL;
#ifdef NOTDEF			
			kprintf("ob2=%x, op=%x, ol=%d, f=%d #",
				sc->sc_obuf,
				sc->sc_op,
				sc->sc_ol,
				sc->sc_state);
#endif				
		}
		else
		{
#ifdef NOTDEF
			kprintf("ob=%x, op=%x, ol=%d, f=%d #",
				sc->sc_obuf,
				sc->sc_op,
				sc->sc_ol,
				sc->sc_state);
#endif
		}			
		
		if(sc->sc_obuf)
		{			
			ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN));
	
			if(sc->sc_ol > ISAC_FIFO_LEN)	/* length > 32 ? */
			{
				sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */
				sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */
				c |= ISAC_CMDR_XTF;	    /* set XTF bit */
			}
			else
			{
				if(sc->sc_freeflag)
				{
					i4b_Dfreembuf(sc->sc_obuf);
					sc->sc_freeflag = 0;
				}
				sc->sc_obuf = NULL;
				sc->sc_op = NULL;
				sc->sc_ol = 0;
	
				c |= ISAC_CMDR_XTF | ISAC_CMDR_XME;
			}
		}
		else
		{
			sc->sc_state &= ~ISAC_TX_ACTIVE;
		}
	}
	
	if(ista & ISAC_ISTA_CISQ)	/* channel status change CISQ */
	{
		u_char ci;
	
		/* get command/indication rx register*/
	
		ci = ISAC_READ(I_CIRR);

		/* if S/Q IRQ, read SQC reg to clr SQC IRQ */
	
		if(ci & ISAC_CIRR_SQC)
			ISAC_READ(I_SQRR);

		/* C/I code change IRQ (flag already cleared by CIRR read) */
	
		if(ci & ISAC_CIRR_CIC0)
			ifpnp_isac_ind_hdlr(sc, (ci >> 2) & 0xf);
	}
Пример #22
0
/*---------------------------------------------------------------------------*
 *	Data source switch for Read channels - 1, 3 and 5 (B and D-Channel)
 *---------------------------------------------------------------------------*/
void
ihfc_putmbuf (ihfc_sc_t *sc, u_char chan, struct mbuf *m)
{
	i4b_trace_hdr_t hdr;

	if (chan < 2)
	{
		if(S_TRACE & TRACE_D_RX)
		{
			hdr.count = ++S_DTRACECOUNT;
			hdr.dir   = FROM_NT;
			hdr.type  = TRC_CH_D;
			hdr.unit  = S_I4BUNIT;

			MICROTIME(hdr.time);

			i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
		}

		if (!S_ENABLED) { i4b_Dfreembuf(m); return; }

		m->m_pkthdr.len = m->m_len;
	
		i4b_l1_ph_data_ind(S_I4BUNIT, m);
	}
	else
	{
		if(S_TRACE & TRACE_B_RX)
		{
			hdr.count = ++S_BTRACECOUNT;
			hdr.dir   = FROM_NT;
			hdr.type  = (chan < 4) ? TRC_CH_B1 : TRC_CH_B2;
			hdr.unit  = S_I4BUNIT;

			MICROTIME(hdr.time);

			i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
		}

		if (!S_ENABLED) { i4b_Bfreembuf(m); return; }

		if (S_PROT == BPROT_NONE)
		{
			if(!i4b_l1_bchan_tel_silence(m->m_data, m->m_len))
			{
				S_BDRVLINK->bch_activity(S_BDRVLINK->unit, ACT_RX);
			}

			if (!_IF_QFULL(&S_IFQUEUE))
			{
				S_BYTES += m->m_len;
				IF_ENQUEUE(&S_IFQUEUE, m);
				S_BDRVLINK->bch_rx_data_ready(S_BDRVLINK->unit);
			}

			return;
		}

		if (S_PROT == BPROT_RHDLC)
		{
			S_MBUFDUMMY = m;
			S_BYTES    += m->m_pkthdr.len = m->m_len;
			S_BDRVLINK->bch_rx_data_ready(S_BDRVLINK->unit);
			S_MBUFDUMMY = NULL;

			return;
		}

		NDBGL1(L1_ERROR, "Unknown protocol: %d", S_PROT);
	}
}
Пример #23
0
/*---------------------------------------------------------------------------*
 *
 *	L2 -> L1: PH-DATA-REQUEST
 *	=========================
 *
 *	parms:
 *		unit		physical interface unit number
 *		m		mbuf containing L2 frame to be sent out
 *		freeflag	MBUF_FREE: free mbuf here after having sent
 *						it out
 *				MBUF_DONTFREE: mbuf is freed by Layer 2
 *	returns:
 *		==0	fail, nothing sent out
 *		!=0	ok, frame sent out
 *
 *---------------------------------------------------------------------------*/
int
ifpi_ph_data_req(int unit, struct mbuf *m, int freeflag)
{
	u_char cmd;
	struct l1_softc *sc = ifpi_scp[unit];

#ifdef NOTDEF
	NDBGL1(L1_PRIM, "PH-DATA-REQ, unit %d, freeflag=%d", unit, freeflag);
#endif

	if(m == NULL)			/* failsafe */
		return (0);

	crit_enter();

	if(sc->sc_I430state == ST_F3)	/* layer 1 not running ? */
	{
		NDBGL1(L1_I_ERR, "still in state F3!");
		ifpi_ph_activate_req(unit);
	}

	if(sc->sc_state & ISAC_TX_ACTIVE)
	{
		if(sc->sc_obuf2 == NULL)
		{
			sc->sc_obuf2 = m;		/* save mbuf ptr */

			if(freeflag)
				sc->sc_freeflag2 = 1;	/* IRQ must mfree */
			else
				sc->sc_freeflag2 = 0;	/* IRQ must not mfree */

			NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", ifpi_printstate(sc));

			if(sc->sc_trace & TRACE_D_TX)
			{
				i4b_trace_hdr_t hdr;
				hdr.unit = L0IFPIUNIT(unit);
				hdr.type = TRC_CH_D;
				hdr.dir = FROM_TE;
				hdr.count = ++sc->sc_trace_dcount;
				MICROTIME(hdr.time);
				i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
			}
			crit_exit();
			return(1);
		}

		NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", ifpi_printstate(sc));
	
		if(freeflag == MBUF_FREE)
			i4b_Dfreembuf(m);			
	
		crit_exit();
		return (0);
	}

	if(sc->sc_trace & TRACE_D_TX)
	{
		i4b_trace_hdr_t hdr;
		hdr.unit = L0IFPIUNIT(unit);
		hdr.type = TRC_CH_D;
		hdr.dir = FROM_TE;
		hdr.count = ++sc->sc_trace_dcount;
		MICROTIME(hdr.time);
		i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
	}
	
	sc->sc_state |= ISAC_TX_ACTIVE;	/* set transmitter busy flag */

	NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set");

	sc->sc_freeflag = 0;		/* IRQ must NOT mfree */
	
	ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */

	if(m->m_len > ISAC_FIFO_LEN)	/* message > 32 bytes ? */
	{
		sc->sc_obuf = m;	/* save mbuf ptr */
		sc->sc_op = m->m_data + ISAC_FIFO_LEN; 	/* ptr for irq hdl */
		sc->sc_ol = m->m_len - ISAC_FIFO_LEN;	/* length for irq hdl */

		if(freeflag)
			sc->sc_freeflag = 1;	/* IRQ must mfree */
		
		cmd = ISAC_CMDR_XTF;
	}
	else
	{
		sc->sc_obuf = NULL;
		sc->sc_op = NULL;
		sc->sc_ol = 0;

		if(freeflag)
			i4b_Dfreembuf(m);

		cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
  	}

	ISAC_WRITE(I_CMDR, cmd);
	ISACCMDRWRDELAY();

	crit_exit();
	
	return(1);
}
Пример #24
0
/*---------------------------------------------------------------------------*
 *	ISAC interrupt service routine
 *---------------------------------------------------------------------------*/
void
isic_isac_irq(struct isic_softc *sc, int ista)
{
	register u_char c = 0;
	NDBGL1(L1_F_MSG, "%s: ista = 0x%02x", device_xname(&sc->sc_dev), ista);

	if(ista & ISAC_ISTA_EXI)	/* extended interrupt */
	{
		u_int8_t exirstat = ISAC_READ(I_EXIR);
		if (sc->sc_intr_valid == ISIC_INTR_VALID)
			c |= isic_isac_exir_hdlr(sc, exirstat);
	}

	if(ista & ISAC_ISTA_RME)	/* receive message end */
	{
		register int rest;
		u_char rsta;

		/* get rx status register */

		rsta = ISAC_READ(I_RSTA);

		if((rsta & ISAC_RSTA_MASK) != 0x20)
		{
			int error = 0;

			if(!(rsta & ISAC_RSTA_CRC))	/* CRC error */
			{
				error++;
				NDBGL1(L1_I_ERR, "%s: CRC error", device_xname(&sc->sc_dev));
			}

			if(rsta & ISAC_RSTA_RDO)	/* ReceiveDataOverflow */
			{
				error++;
				NDBGL1(L1_I_ERR, "%s: Data Overrun error", device_xname(&sc->sc_dev));
			}

			if(rsta & ISAC_RSTA_RAB)	/* ReceiveABorted */
			{
				error++;
				NDBGL1(L1_I_ERR, "%s: Receive Aborted error", device_xname(&sc->sc_dev));
			}

			if(error == 0)
			{
				NDBGL1(L1_I_ERR, "%s: RME unknown error, RSTA = 0x%02x!", device_xname(&sc->sc_dev), rsta);
			}

			i4b_Dfreembuf(sc->sc_ibuf);

			c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;

			sc->sc_ibuf = NULL;
			sc->sc_ib = NULL;
			sc->sc_ilen = 0;

			ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES);
			ISACCMDRWRDELAY();

			return;
		}

		rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1));

		if(rest == 0)
			rest = ISAC_FIFO_LEN;

		if(sc->sc_ibuf == NULL)
		{
			if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
				sc->sc_ib = sc->sc_ibuf->m_data;
			else
				panic("isic_isac_irq: RME, i4b_Dgetmbuf returns NULL!");
			sc->sc_ilen = 0;
		}

		if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
		{
			ISAC_RDFIFO(sc->sc_ib, rest);
			sc->sc_ilen += rest;

			sc->sc_ibuf->m_pkthdr.len =
				sc->sc_ibuf->m_len = sc->sc_ilen;

			if(sc->sc_trace & TRACE_D_RX)
			{
				i4b_trace_hdr hdr;
				memset(&hdr, 0, sizeof hdr);
				hdr.type = TRC_CH_D;
				hdr.dir = FROM_NT;
				hdr.count = ++sc->sc_trace_dcount;
				isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
			}

			c |= ISAC_CMDR_RMC;

			if(sc->sc_intr_valid == ISIC_INTR_VALID &&
			   (((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S))
			{
				isdn_layer2_data_ind(&sc->sc_l2, sc->sc_l3token, sc->sc_ibuf);
			}
			else
			{
				i4b_Dfreembuf(sc->sc_ibuf);
			}
		}
		else
		{
			NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
			i4b_Dfreembuf(sc->sc_ibuf);
			c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
		}

		sc->sc_ibuf = NULL;
		sc->sc_ib = NULL;
		sc->sc_ilen = 0;
	}

	if(ista & ISAC_ISTA_RPF)	/* receive fifo full */
	{
		if(sc->sc_ibuf == NULL)
		{
			if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
				sc->sc_ib= sc->sc_ibuf->m_data;
			else
				panic("isic_isac_irq: RPF, i4b_Dgetmbuf returns NULL!");
			sc->sc_ilen = 0;
		}

		if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN))
		{
			ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN);
			sc->sc_ilen += ISAC_FIFO_LEN;
			sc->sc_ib += ISAC_FIFO_LEN;
			c |= ISAC_CMDR_RMC;
		}
		else
		{
			NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
			i4b_Dfreembuf(sc->sc_ibuf);
			sc->sc_ibuf = NULL;
			sc->sc_ib = NULL;
			sc->sc_ilen = 0;
			c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
		}
	}

	if(ista & ISAC_ISTA_XPR)	/* transmit fifo empty (XPR bit set) */
	{
		if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
		{
			sc->sc_freeflag = sc->sc_freeflag2;
			sc->sc_obuf = sc->sc_obuf2;
			sc->sc_op = sc->sc_obuf->m_data;
			sc->sc_ol = sc->sc_obuf->m_len;
			sc->sc_obuf2 = NULL;
#ifdef NOTDEF
			printf("ob2=%x, op=%x, ol=%d, f=%d #",
				sc->sc_obuf,
				sc->sc_op,
				sc->sc_ol,
				sc->sc_state);
#endif
		}
		else
		{
#ifdef NOTDEF
			printf("ob=%x, op=%x, ol=%d, f=%d #",
				sc->sc_obuf,
				sc->sc_op,
				sc->sc_ol,
				sc->sc_state);
#endif
		}

		if(sc->sc_obuf)
		{
			ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN));

			if(sc->sc_ol > ISAC_FIFO_LEN)	/* length > 32 ? */
			{
				sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */
				sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */
				c |= ISAC_CMDR_XTF;	    /* set XTF bit */
			}
			else
			{
				if(sc->sc_freeflag)
				{
					i4b_Dfreembuf(sc->sc_obuf);
					sc->sc_freeflag = 0;
				}
				sc->sc_obuf = NULL;
				sc->sc_op = NULL;
				sc->sc_ol = 0;

				c |= ISAC_CMDR_XTF | ISAC_CMDR_XME;
			}
		}
		else
		{
			sc->sc_state &= ~ISAC_TX_ACTIVE;
		}
	}

	if(ista & ISAC_ISTA_CISQ)	/* channel status change CISQ */
	{
		register u_char ci;

		/* get command/indication rx register*/

		ci = ISAC_READ(I_CIRR);

		/* if S/Q IRQ, read SQC reg to clr SQC IRQ */

		if(ci & ISAC_CIRR_SQC)
			(void) ISAC_READ(I_SQRR);

		/* C/I code change IRQ (flag already cleared by CIRR read) */

		if(ci & ISAC_CIRR_CIC0)
			isic_isac_ind_hdlr(sc, (ci >> 2) & 0xf);
	}

	if(c)
	{
		ISAC_WRITE(I_CMDR, c);
		ISACCMDRWRDELAY();
	}
}
Пример #25
0
/*---------------------------------------------------------------------------*
 *
 *	L2 -> L1: PH-DATA-REQUEST
 *	=========================
 *
 *	parms:
 *		token		softc of physical driver
 *		m		mbuf containing L2 frame to be sent out
 *		freeflag	MBUF_FREE: free mbuf here after having sent
 *						it out
 *				MBUF_DONTFREE: mbuf is freed by Layer 2
 *	returns:
 *		==0	fail, nothing sent out
 *		!=0	ok, frame sent out
 *
 *---------------------------------------------------------------------------*/
static int
isic_std_ph_data_req(isdn_layer1token token, struct mbuf *m, int freeflag)
{
	struct isic_softc *sc = (struct isic_softc*)token;
	u_char cmd;
	int s;

	if (m == NULL)			/* failsafe */
		return (0);

	s = splnet();

	if(sc->sc_I430state == ST_F3)	/* layer 1 not running ? */
	{
		NDBGL1(L1_I_ERR, "still in state F3!");
		isic_std_ph_activate_req(token);
	}

	if(sc->sc_state & ISAC_TX_ACTIVE)
	{
		if(sc->sc_obuf2 == NULL)
		{
			sc->sc_obuf2 = m;		/* save mbuf ptr */

			if(freeflag)
				sc->sc_freeflag2 = 1;	/* IRQ must mfree */
			else
				sc->sc_freeflag2 = 0;	/* IRQ must not mfree */

			NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", isic_printstate(sc));

			if(sc->sc_trace & TRACE_D_TX)
			{
				i4b_trace_hdr hdr;
				hdr.type = TRC_CH_D;
				hdr.dir = FROM_TE;
				hdr.count = ++sc->sc_trace_dcount;
				isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, m->m_len, m->m_data);
			}
			splx(s);
			return(1);
		}

		NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", isic_printstate(sc));

		if(freeflag == MBUF_FREE)
			i4b_Dfreembuf(m);

		splx(s);
		return (0);
	}

	if(sc->sc_trace & TRACE_D_TX)
	{
		i4b_trace_hdr hdr;
		hdr.type = TRC_CH_D;
		hdr.dir = FROM_TE;
		hdr.count = ++sc->sc_trace_dcount;
		isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, m->m_len, m->m_data);
	}

	sc->sc_state |= ISAC_TX_ACTIVE;	/* set transmitter busy flag */

	NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set");

	sc->sc_freeflag = 0;		/* IRQ must NOT mfree */

	ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */

	if(m->m_len > ISAC_FIFO_LEN)	/* message > 32 bytes ? */
	{
		sc->sc_obuf = m;	/* save mbuf ptr */
		sc->sc_op = m->m_data + ISAC_FIFO_LEN; 	/* ptr for irq hdl */
		sc->sc_ol = m->m_len - ISAC_FIFO_LEN;	/* length for irq hdl */

		if(freeflag)
			sc->sc_freeflag = 1;	/* IRQ must mfree */

		cmd = ISAC_CMDR_XTF;
	}
	else
	{
		sc->sc_obuf = NULL;
		sc->sc_op = NULL;
		sc->sc_ol = 0;

		if(freeflag)
			i4b_Dfreembuf(m);

		cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
  	}

	ISAC_WRITE(I_CMDR, cmd);
	ISACCMDRWRDELAY();

	splx(s);

	return(1);
}