Beispiel #1
0
static void
pcn_reclaim(pcn_t *pcnp)
{
	pcn_tx_desc_t	*tmdp;

	while (pcnp->pcn_txavail != PCN_TXRING) {
		int index = pcnp->pcn_txreclaim;

		tmdp = &pcnp->pcn_txdescp[index];

		/* sync before reading */
		SYNCTXDESC(pcnp, index, DDI_DMA_SYNC_FORKERNEL);

		/* check if chip is still working on it */
		if (tmdp->pcn_txctl & PCN_TXCTL_OWN)
			break;

		pcnp->pcn_txavail++;
		pcnp->pcn_txreclaim = (index + 1) % PCN_TXRING;
	}

	if (pcnp->pcn_txavail >= PCN_TXRESCHED) {
		if (pcnp->pcn_wantw) {
			pcnp->pcn_wantw = B_FALSE;

			/* Disable TX interrupt */
			PCN_CSR_CLRBIT(pcnp, PCN_CSR_EXTCTL1,
			    PCN_EXTCTL1_LTINTEN);

			mac_tx_update(pcnp->pcn_mh);
		}
	}
}
Beispiel #2
0
static void
pcn_startall(pcn_t *pcnp)
{
	ASSERT(mutex_owned(&pcnp->pcn_intrlock));
	ASSERT(mutex_owned(&pcnp->pcn_xmtlock));

	(void) pcn_initialize(pcnp, B_FALSE);

	/* Start chip and enable interrupts */
	PCN_CSR_SETBIT(pcnp, PCN_CSR_CSR, PCN_CSR_START|PCN_CSR_INTEN);

	pcn_start_timer(pcnp);

	if (IS_RUNNING(pcnp))
		mac_tx_update(pcnp->pcn_mh);
}
Beispiel #3
0
/*
 * function to drain a TxCQ and process its CQEs
 *
 * dev - software handle to the device
 * cq - pointer to the cq to drain
 *
 * return the number of CQEs processed
 */
uint16_t
oce_drain_wq_cq(void *arg)
{
	uint16_t num_cqe = 0;
	struct oce_dev *dev;
	struct oce_wq *wq;

	wq = (struct oce_wq *)arg;
	dev = wq->parent;

	/* do while we do not reach a cqe that is not valid */
	num_cqe = oce_process_tx_compl(wq, B_FALSE);

	/* check if we need to restart Tx */
	if (wq->resched && num_cqe) {
		wq->resched = B_FALSE;
		mac_tx_update(dev->mac_handle);
	}

	return (num_cqe);
} /* oce_process_wq_cqe */
Beispiel #4
0
/*
 * ISR/periodic callbacks.
 */
uint_t
efe_intr(caddr_t arg1, caddr_t arg2)
{
	efe_t *efep = (void *)arg1;
	uint32_t status;
	mblk_t *mp = NULL;

	_NOTE(ARGUNUSED(arg2));

	mutex_enter(&efep->efe_intrlock);

	if (efep->efe_flags & FLAG_SUSPENDED) {
		mutex_exit(&efep->efe_intrlock);
		return (DDI_INTR_UNCLAIMED);
	}

	status = GETCSR(efep, CSR_INTSTAT);
	if (!(status & INTSTAT_ACTV)) {
		mutex_exit(&efep->efe_intrlock);
		return (DDI_INTR_UNCLAIMED);
	}
	PUTCSR(efep, CSR_INTSTAT, status);

	if (status & INTSTAT_RCC) {
		mp = efe_recv(efep);
	}

	if (status & INTSTAT_RQE) {
		efep->efe_ierrors++;
		efep->efe_macrcv_errors++;

		/* Kick the receiver */
		PUTCSR(efep, CSR_COMMAND, COMMAND_RXQUEUED);
	}

	if (status & INTSTAT_TXC) {
		mutex_enter(&efep->efe_txlock);

		efe_send_done(efep);

		mutex_exit(&efep->efe_txlock);
	}

	if (status & INTSTAT_FATAL) {
		mutex_enter(&efep->efe_txlock);

		efe_error(efep->efe_dip, "bus error; resetting!");
		efe_restart(efep);

		mutex_exit(&efep->efe_txlock);
	}

	mutex_exit(&efep->efe_intrlock);

	if (mp != NULL) {
		mac_rx(efep->efe_mh, NULL, mp);
	}

	if (status & INTSTAT_TXC) {
		mac_tx_update(efep->efe_mh);
	}

	if (status & INTSTAT_FATAL) {
		mii_reset(efep->efe_miih);
	}

	return (DDI_INTR_CLAIMED);
}