Beispiel #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) {
	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;
}
Beispiel #2
0
static int iavc_send_init(iavc_softc_t *sc)
{
    struct mbuf *m = i4b_Dgetmbuf(15);
    u_int8_t *p;
    int s;

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

    /*
     * byte  0x11 = SEND_INIT
     * dword NumApplications
     * dword NumNCCIs
     * dword BoardNumber
     */

    p = amcc_put_byte(mtod(m, u_int8_t*), 0);
    p = amcc_put_byte(p, 0);
    p = amcc_put_byte(p, SEND_INIT);
    p = amcc_put_word(p, 1); /* XXX MaxAppl XXX */
    p = amcc_put_word(p, sc->sc_capi.sc_nbch);
    p = amcc_put_word(p, sc->sc_unit);

    s = splnet();
    IF_ENQUEUE(&sc->sc_txq, m);

    iavc_start_tx(sc);

    sc->sc_state = IAVC_INIT;
    splx(s);
    return 0;
}
Beispiel #3
0
int iavc_release(capi_softc_t *capi_sc, int applid)
{
    iavc_softc_t *sc = (iavc_softc_t*) capi_sc->ctx;
    struct mbuf *m = i4b_Dgetmbuf(7);
    u_int8_t *p;

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

    /*
     * byte  0x14 = SEND_RELEASE
     * dword ApplId
     */

    p = amcc_put_byte(mtod(m, u_int8_t*), 0);
    p = amcc_put_byte(p, 0);
    p = amcc_put_byte(p, SEND_RELEASE);
    p = amcc_put_word(p, applid);

    IF_ENQUEUE(&sc->sc_txq, m);

    iavc_start_tx(sc);
    return 0;
}
Beispiel #4
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;
}
Beispiel #5
0
int iavc_handle_intr(iavc_softc_t *sc)
{
    u_int32_t status;
    u_int32_t newcsr;

    if (!sc->sc_dma) {
	while (iavc_rx_full(sc))
	    iavc_handle_rx(sc);
	return 0;
    }

    status = AMCC_READ(sc, AMCC_INTCSR);
    if ((status & ANY_S5933_INT) == 0)
	return 0;

    newcsr = sc->sc_csr | (status & ALL_INT);
    if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
    if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
    AMCC_WRITE(sc, AMCC_INTCSR, newcsr);
    sc->sc_intr = 1;

    if (status & RX_TC_INT) {
	u_int32_t rxlen;

	bus_dmamap_sync(sc->dmat, sc->rx_map, 0, sc->rx_map->dm_mapsize,
	  BUS_DMASYNC_POSTREAD);

	if (sc->sc_recv1 == 0) {
	    sc->sc_recv1 = *(u_int32_t*)(sc->sc_recvbuf);
	    rxlen = (sc->sc_recv1 + 3) & ~3;

	    AMCC_WRITE(sc, AMCC_RXPTR, sc->rx_map->dm_segs[0].ds_addr);
	    AMCC_WRITE(sc, AMCC_RXLEN, rxlen ? rxlen : 4);
	} else {
	    iavc_handle_rx(sc);
	    sc->sc_recv1 = 0;
	    AMCC_WRITE(sc, AMCC_RXPTR, sc->rx_map->dm_segs[0].ds_addr);
	    AMCC_WRITE(sc, AMCC_RXLEN, 4);
	}
    }

    if (status & TX_TC_INT) {
	bus_dmamap_sync(sc->dmat, sc->tx_map, 0, sc->tx_map->dm_mapsize,
	  BUS_DMASYNC_POSTWRITE);
	sc->sc_csr &= ~EN_TX_TC_INT;
	iavc_start_tx(sc);
    }

    AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr);
    sc->sc_intr = 0;

    return 0;
}
Beispiel #6
0
void iavc_handle_intr(iavc_softc_t *sc)
{
    u_int32_t status;
    u_int32_t newcsr;

    if (!sc->sc_dma) {
	while (iavc_rx_full(sc))
	    iavc_handle_rx(sc);
	return;
    }

    status = AMCC_READ(sc, AMCC_INTCSR);
    if ((status & ANY_S5933_INT) == 0)
	return;

    newcsr = sc->sc_csr | (status & ALL_INT);
    if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
    if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
    AMCC_WRITE(sc, AMCC_INTCSR, newcsr);
    sc->sc_intr = TRUE;

    if (status & RX_TC_INT) {
	u_int32_t rxlen;

	if (sc->sc_recvlen == 0) {
	    sc->sc_recvlen = *((u_int32_t*)(&sc->sc_recvbuf[0]));
	    rxlen = (sc->sc_recvlen + 3) & ~3;
	    AMCC_WRITE(sc, AMCC_RXPTR, vtophys(&sc->sc_recvbuf[4]));
	    AMCC_WRITE(sc, AMCC_RXLEN, rxlen);
	} else {
	    iavc_handle_rx(sc);
	    sc->sc_recvlen = 0;
	    AMCC_WRITE(sc, AMCC_RXPTR, vtophys(&sc->sc_recvbuf[0]));
	    AMCC_WRITE(sc, AMCC_RXLEN, 4);
	}
    }

    if (status & TX_TC_INT) {
	sc->sc_csr &= ~EN_TX_TC_INT;
	iavc_start_tx(sc);
    }

    AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr);
    sc->sc_intr = FALSE;
}
Beispiel #7
0
int iavc_register(capi_softc_t *capi_sc, int applid, int nchan)
{
    iavc_softc_t *sc = (iavc_softc_t*) capi_sc->ctx;
    struct mbuf *m = i4b_Dgetmbuf(23);
    u_int8_t *p;

    if (!m) {
	aprint_error("iavc%d: can't get memory\n", sc->sc_unit);
	return (ENOMEM);
    }

    /*
     * byte  0x12 = SEND_REGISTER
     * dword ApplId
     * dword NumMessages
     * dword NumB3Connections 0..nbch
     * dword NumB3Blocks
     * dword B3Size
     */

    p = amcc_put_byte(mtod(m, u_int8_t*), 0);
    p = amcc_put_byte(p, 0);
    p = amcc_put_byte(p, SEND_REGISTER);
    p = amcc_put_word(p, applid);
#if 0
    p = amcc_put_word(p, 1024 + (nchan + 1));
#else
    p = amcc_put_word(p, 1024 * (nchan + 1));
#endif
    p = amcc_put_word(p, nchan);
    p = amcc_put_word(p, 8);
    p = amcc_put_word(p, 2048);

    IF_ENQUEUE(&sc->sc_txq, m);

    iavc_start_tx(sc);

    return 0;
}
Beispiel #8
0
static int iavc_receive_start(iavc_softc_t *sc, u_int8_t *dmabuf)
{
    struct mbuf *m = i4b_Dgetmbuf(3);
    u_int8_t *p;

    if (sc->sc_blocked && sc->sc_state == IAVC_UP)
	printf("iavc%d: receive_start\n", sc->sc_unit);

    if (!m) {
	printf("iavc%d: can't get memory\n", sc->sc_unit);
	return (ENOMEM);
    }

    /*
     * byte  0x73 = SEND_POLLACK
     */

    p = amcc_put_byte(mtod(m, u_int8_t*), 0);
    p = amcc_put_byte(p, 0);
    p = amcc_put_byte(p, SEND_POLLACK);
    
    _IF_PREPEND(&sc->sc_txq, m);

    NDBGL4(L4_IAVCDBG, "iavc%d: blocked = %d, state = %d",
		sc->sc_unit, sc->sc_blocked, sc->sc_state);

    sc->sc_blocked = FALSE;
    iavc_start_tx(sc);
    
    /* If this was our first START, register our readiness */

    if (sc->sc_state != IAVC_UP) {
	sc->sc_state = IAVC_UP;
	capi_ll_control(&sc->sc_capi, CAPI_CTRL_READY, TRUE);
    }

    return 0;
}
Beispiel #9
0
static int iavc_receive_start(iavc_softc_t *sc)
{
    struct mbuf *m = i4b_Dgetmbuf(3);
    u_int8_t *p;

    if (sc->sc_blocked && sc->sc_state == IAVC_UP)
	printf("%s: receive_start\n", device_xname(&sc->sc_dev));

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

    /*
     * byte  0x73 = SEND_POLLACK
     */

    p = amcc_put_byte(mtod(m, u_int8_t*), 0);
    p = amcc_put_byte(p, 0);
    p = amcc_put_byte(p, SEND_POLLACK);

    IF_PREPEND(&sc->sc_txq, m);

    NDBGL4(L4_IAVCDBG, "%s: blocked = %d, state = %d",
      device_xname(&sc->sc_dev), sc->sc_blocked, sc->sc_state);

    sc->sc_blocked = 0;
    iavc_start_tx(sc);

    /* If this was our first START, register our readiness */
    if (sc->sc_state != IAVC_UP) {
	sc->sc_state = IAVC_UP;
	capi_ll_control(&sc->sc_capi, CAPI_CTRL_READY, 1);
    }

    return 0;
}