Example #1
0
int
sfxge_intr_init(struct sfxge_softc *sc)
{
	device_t dev;
	struct sfxge_intr *intr;
	efsys_mem_t *esmp;
	int rc;

	dev = sc->dev;
	intr = &sc->intr;
	esmp = &intr->status;

	KASSERT(intr->state == SFXGE_INTR_UNINITIALIZED,
	    ("Interrupts already initialized"));

	/* Try to setup MSI-X or MSI interrupts if available. */
	if ((rc = sfxge_intr_setup_msix(sc)) == 0)
		device_printf(dev, "Using MSI-X interrupts\n");
	else if ((rc = sfxge_intr_setup_msi(sc)) == 0)
		device_printf(dev, "Using MSI interrupts\n");
	else if ((rc = sfxge_intr_setup_fixed(sc)) == 0) {
		device_printf(dev, "Using fixed interrupts\n");
	} else {
		device_printf(dev, "Couldn't setup interrupts\n");
		return (ENOMEM);
	}

	/* Set up DMA for interrupts. */
	if ((rc = sfxge_dma_alloc(sc, EFX_INTR_SIZE, esmp)) != 0)
		return (ENOMEM);

	intr->state = SFXGE_INTR_INITIALIZED;

	return (0);
}
Example #2
0
static int
sfxge_ev_qinit(struct sfxge_softc *sc, unsigned int index)
{
	struct sfxge_evq *evq;
	efsys_mem_t *esmp;
	int rc;

	KASSERT(index < SFXGE_RX_SCALE_MAX, ("index >= SFXGE_RX_SCALE_MAX"));

	evq = malloc(sizeof(struct sfxge_evq), M_SFXGE, M_ZERO | M_WAITOK);
	evq->sc = sc;
	evq->index = index;
	sc->evq[index] = evq;
	esmp = &evq->mem;

	/* Initialise TX completion list */
	evq->txqs = &evq->txq;

	/* Allocate DMA space. */
	if ((rc = sfxge_dma_alloc(sc, EFX_EVQ_SIZE(SFXGE_NEVS), esmp)) != 0)
		return (rc);

	/* Allocate buffer table entries. */
	sfxge_sram_buf_tbl_alloc(sc, EFX_EVQ_NBUFS(SFXGE_NEVS),
				 &evq->buf_base_id);

	mtx_init(&evq->lock, "evq", NULL, MTX_DEF);

	evq->init_state = SFXGE_EVQ_INITIALIZED;

	return (0);
}
Example #3
0
int
sfxge_mcdi_init(struct sfxge_softc *sc)
{
	efx_nic_t *enp;
	struct sfxge_mcdi *mcdi;
	efx_mcdi_transport_t *emtp;
	efsys_mem_t *esmp;
	int max_msg_size;
	int rc;

	enp = sc->enp;
	mcdi = &sc->mcdi;
	emtp = &mcdi->transport;
	esmp = &mcdi->mem;
	max_msg_size = sizeof (uint32_t) + MCDI_CTL_SDU_LEN_MAX_V2;

	KASSERT(mcdi->state == SFXGE_MCDI_UNINITIALIZED,
	    ("MCDI already initialized"));

	SFXGE_MCDI_LOCK_INIT(mcdi, device_get_nameunit(sc->dev));

	mcdi->state = SFXGE_MCDI_INITIALIZED;

	if ((rc = sfxge_dma_alloc(sc, max_msg_size, esmp)) != 0)
		goto fail;

	emtp->emt_context = sc;
	emtp->emt_dma_mem = esmp;
	emtp->emt_execute = sfxge_mcdi_execute;
	emtp->emt_ev_cpl = sfxge_mcdi_ev_cpl;
	emtp->emt_exception = sfxge_mcdi_exception;
#if EFSYS_OPT_MCDI_LOGGING
	emtp->emt_logger = sfxge_mcdi_logger;
	SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
		       SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
		       OID_AUTO, "mcdi_logging", CTLFLAG_RW,
		       &sc->mcdi_logging, 0,
		       "MCDI logging");
#endif

	if ((rc = efx_mcdi_init(enp, emtp)) != 0)
		goto fail;

	return (0);

fail:
	SFXGE_MCDI_LOCK_DESTROY(mcdi);
	mcdi->state = SFXGE_MCDI_UNINITIALIZED;
	return (rc);
}
Example #4
0
static int
sfxge_ev_qinit(struct sfxge_softc *sc, unsigned int index)
{
	struct sfxge_evq *evq;
	efsys_mem_t *esmp;
	int rc;

	KASSERT(index < SFXGE_RX_SCALE_MAX, ("index >= SFXGE_RX_SCALE_MAX"));

	evq = malloc(sizeof(struct sfxge_evq), M_SFXGE, M_ZERO | M_WAITOK);
	evq->sc = sc;
	evq->index = index;
	sc->evq[index] = evq;
	esmp = &evq->mem;

	/* Build an event queue with room for one event per tx and rx buffer,
	 * plus some extra for link state events and MCDI completions.
	 * There are three tx queues in the first event queue and one in
	 * other.
	 */
	if (index == 0)
		evq->entries =
			ROUNDUP_POW_OF_TWO(sc->rxq_entries +
					   3 * sc->txq_entries +
					   128);
	else
		evq->entries =
			ROUNDUP_POW_OF_TWO(sc->rxq_entries +
					   sc->txq_entries +
					   128);

	/* Initialise TX completion list */
	evq->txqs = &evq->txq;

	/* Allocate DMA space. */
	if ((rc = sfxge_dma_alloc(sc, EFX_EVQ_SIZE(evq->entries), esmp)) != 0)
		return (rc);

	/* Allocate buffer table entries. */
	sfxge_sram_buf_tbl_alloc(sc, EFX_EVQ_NBUFS(evq->entries),
				 &evq->buf_base_id);

	SFXGE_EVQ_LOCK_INIT(evq, device_get_nameunit(sc->dev), index);

	evq->init_state = SFXGE_EVQ_INITIALIZED;

	return (0);
}