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); } } }
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); }
/* * 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 */
/* * 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); }