Пример #1
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);
    }
}
Пример #2
0
int
iavc_b1dma_detect(iavc_softc_t *sc)
{
    AMCC_WRITE(sc, AMCC_MCSR, 0);
    DELAY(10*1000);
    AMCC_WRITE(sc, AMCC_MCSR, 0x0f000000);
    DELAY(10*1000);
    AMCC_WRITE(sc, AMCC_MCSR, 0);
    DELAY(42*1000);

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

    if (AMCC_READ(sc, AMCC_INTCSR) != 0)
	return 1;

    AMCC_WRITE(sc, AMCC_RXPTR, 0xffffffff);
    AMCC_WRITE(sc, AMCC_TXPTR, 0xffffffff);
    if ((AMCC_READ(sc, AMCC_RXPTR) != 0xfffffffc) ||
	(AMCC_READ(sc, AMCC_TXPTR) != 0xfffffffc))
	return 2;

    AMCC_WRITE(sc, AMCC_RXPTR, 0);
    AMCC_WRITE(sc, AMCC_TXPTR, 0);
    if ((AMCC_READ(sc, AMCC_RXPTR) != 0) ||
	(AMCC_READ(sc, AMCC_TXPTR) != 0))
	return 3;

    iavc_write_port(sc, 0x10, 0x00);
    iavc_write_port(sc, 0x07, 0x00);

    iavc_write_port(sc, 0x02, 0x02);
    iavc_write_port(sc, 0x03, 0x02);

    if (((iavc_read_port(sc, 0x02) & 0xfe) != 0x02) ||
	(iavc_read_port(sc, 0x03) != 0x03))
	return 4;

    iavc_write_port(sc, 0x02, 0x00);
    iavc_write_port(sc, 0x03, 0x00);

    if (((iavc_read_port(sc, 0x02) & 0xfe) != 0x00) ||
	(iavc_read_port(sc, 0x03) != 0x01))
	return 5;

    return (0); /* found */
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
0
void b1dma_reset(iavc_softc_t *sc)
{
    int s = SPLI4B();

    sc->sc_csr = 0;
    AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr);
    AMCC_WRITE(sc, AMCC_MCSR, 0);
    AMCC_WRITE(sc, AMCC_RXLEN, 0);
    AMCC_WRITE(sc, AMCC_TXLEN, 0);

    iavc_write_port(sc, 0x10, 0x00); /* XXX magic numbers from */
    iavc_write_port(sc, 0x07, 0x00); /* XXX the linux driver */

    splx(s);

    AMCC_WRITE(sc, AMCC_MCSR, 0);
    DELAY(10 * 1000);
    AMCC_WRITE(sc, AMCC_MCSR, 0x0f000000);
    DELAY(10 * 1000);
    AMCC_WRITE(sc, AMCC_MCSR, 0);
    DELAY(42 * 1000);
}
Пример #6
0
int iavc_load(capi_softc_t *capi_sc, int len, u_int8_t *cp)
{
    iavc_softc_t *sc = (iavc_softc_t*) capi_sc->ctx;
    u_int8_t val;

    aprint_debug_dev(&sc->sc_dev, "reset card ....\n");

    if (sc->sc_dma)
	iavc_b1dma_reset(sc);	/* PCI cards */
    else if (sc->sc_t1)
	iavc_t1_reset(sc);		/* ISA attachment T1 */
    else
	iavc_b1_reset(sc);		/* ISA attachment B1 */

    DELAY(1000);

    aprint_debug_dev(&sc->sc_dev, "start loading %d bytes firmware\n", len);

    while (len && b1io_save_put_byte(sc, *cp++) == 0)
	len--;

    if (len) {
	aprint_error_dev(&sc->sc_dev, "loading failed, can't write to card, len = %d\n", len);
	return (EIO);
    }

    aprint_debug_dev(&sc->sc_dev, "firmware loaded, wait for ACK\n");

    if(sc->sc_capi.card_type == CARD_TYPEC_AVM_B1_ISA)
	    iavc_put_byte(sc, SEND_POLL);
    else
	    iavc_put_byte(sc, SEND_POLLACK);

    for (len = 0; len < 1000 && !iavc_rx_full(sc); len++)
	DELAY(100);

    if (!iavc_rx_full(sc)) {
	aprint_error_dev(&sc->sc_dev, "loading failed, no ack\n");
	return (EIO);
    }

    val = iavc_get_byte(sc);

    if ((sc->sc_dma && val != RECEIVE_POLLDWORD) ||
      (!sc->sc_dma && val != RECEIVE_POLL)) {
	aprint_error_dev(&sc->sc_dev, "loading failed, bad ack = %02x\n", val);
	return (EIO);
    }

    aprint_debug_dev(&sc->sc_dev, "got ACK = 0x%02x\n", val);

    /* Start the DMA engine */
    if (sc->sc_dma) {
	int s;

	s = splnet();

	sc->sc_csr = AVM_FLAG;
	AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr);
	AMCC_WRITE(sc, AMCC_MCSR, (EN_A2P_TRANSFERS|EN_P2A_TRANSFERS|
				   A2P_HI_PRIORITY|P2A_HI_PRIORITY|
				   RESET_A2P_FLAGS|RESET_P2A_FLAGS));

	iavc_write_port(sc, 0x07, 0x30); /* XXX magic numbers from */
	iavc_write_port(sc, 0x10, 0xf0); /* XXX the linux driver */

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

	sc->sc_recv1 = 0;
	AMCC_WRITE(sc, AMCC_RXPTR, sc->rx_map->dm_segs[0].ds_addr);
	AMCC_WRITE(sc, AMCC_RXLEN, 4);
	sc->sc_csr |= EN_RX_TC_INT|EN_TX_TC_INT;
	AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr);

	splx(s);
    }

#ifdef notyet
    /* good happy place */
    if(sc->sc_capi.card_type == CARD_TYPEC_AVM_B1_ISA)
	b1isa_setup_irq(sc);
#endif

    iavc_send_init(sc);

    return 0;
}
Пример #7
0
int iavc_load(capi_softc_t *capi_sc, int len, u_int8_t *cp)
{
    iavc_softc_t *sc = (iavc_softc_t*) capi_sc->ctx;
    u_int8_t val;

    if(bootverbose)
	printf("iavc%d: reset card ....\n", sc->sc_unit);

    if (sc->sc_dma)
	b1dma_reset(sc);	/* PCI cards */
    else if (sc->sc_t1)
	t1_reset(sc);		/* ISA attachment T1 */
    else
	b1_reset(sc);		/* ISA attachment B1 */

    DELAY(1000);

    if(bootverbose)
	    printf("iavc%d: start loading %d bytes firmware ....\n", sc->sc_unit, len);
    
    while (len && b1io_save_put_byte(sc, *cp++) == 0)
	len--;

    if (len) {
	printf("iavc%d: loading failed, can't write to card, len = %d\n",
	       sc->sc_unit, len);
	return (EIO);
    }

    if(bootverbose)
    	printf("iavc%d: firmware loaded, wait for ACK ....\n", sc->sc_unit);
    
    if(sc->sc_capi.card_type == CARD_TYPEC_AVM_B1_ISA)
	    iavc_put_byte(sc, SEND_POLL);
    else
	    iavc_put_byte(sc, SEND_POLLACK);    	
    
    for (len = 0; len < 1000 && !iavc_rx_full(sc); len++)
	DELAY(100);
    
    if (!iavc_rx_full(sc)) {
	printf("iavc%d: loading failed, no ack\n", sc->sc_unit);
	return (EIO);
    }
    
    val = iavc_get_byte(sc);

    if ((sc->sc_dma && val != RECEIVE_POLLDWORD) ||
	(!sc->sc_dma && val != RECEIVE_POLL)) {
	printf("iavc%d: loading failed, bad ack = %02x\n", sc->sc_unit, val);
	return (EIO);
    }

    if(bootverbose)
	    printf("iavc%d: got ACK = 0x%02x\n", sc->sc_unit, val);    

    if (sc->sc_dma) {
	/* Start the DMA engine */

	int s = SPLI4B();

	sc->sc_csr = AVM_FLAG;
	AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr);
	AMCC_WRITE(sc, AMCC_MCSR, (EN_A2P_TRANSFERS|EN_P2A_TRANSFERS|
				   A2P_HI_PRIORITY|P2A_HI_PRIORITY|
				   RESET_A2P_FLAGS|RESET_P2A_FLAGS));

	iavc_write_port(sc, 0x07, 0x30); /* XXX magic numbers from */
	iavc_write_port(sc, 0x10, 0xf0); /* XXX the linux driver */

	sc->sc_recvlen = 0;
	AMCC_WRITE(sc, AMCC_RXPTR, vtophys(&sc->sc_recvbuf[0]));
	AMCC_WRITE(sc, AMCC_RXLEN, 4);
	sc->sc_csr |= EN_RX_TC_INT|EN_TX_TC_INT;
	AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr);

	splx(s);
    }

    if(sc->sc_capi.card_type == CARD_TYPEC_AVM_B1_ISA)
	b1isa_setup_irq(sc);
    
    iavc_send_init(sc);

    return 0;
}