Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/oce/oce_if.c
Show First 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | |||||
static void oce_media_status(struct ifnet *ifp, struct ifmediareq *req); | static void oce_media_status(struct ifnet *ifp, struct ifmediareq *req); | ||||
static int oce_media_change(struct ifnet *ifp); | static int oce_media_change(struct ifnet *ifp); | ||||
/* Transmit routines prototypes */ | /* Transmit routines prototypes */ | ||||
static int oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index); | static int oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index); | ||||
static void oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq); | static void oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq); | ||||
static void oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, | static void oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, | ||||
uint32_t status); | uint32_t status); | ||||
static void oce_tx_clean(POCE_SOFTC sc); | |||||
static int oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, | static int oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, | ||||
struct oce_wq *wq); | struct oce_wq *wq); | ||||
/* Receive routines prototypes */ | /* Receive routines prototypes */ | ||||
static void oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe); | static void oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe); | ||||
static int oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe); | static int oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe); | ||||
static int oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe); | static int oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe); | ||||
static void oce_rx(struct oce_rq *rq, uint32_t rqe_idx, | static void oce_rx(struct oce_rq *rq, uint32_t rqe_idx, | ||||
▲ Show 20 Lines • Show All 427 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
oce_multiq_flush(struct ifnet *ifp) | oce_multiq_flush(struct ifnet *ifp) | ||||
{ | { | ||||
POCE_SOFTC sc = ifp->if_softc; | POCE_SOFTC sc = ifp->if_softc; | ||||
struct mbuf *m; | struct mbuf *m; | ||||
int i = 0; | int i = 0; | ||||
for (i = 0; i < sc->nwqs; i++) { | for (i = 0; i < sc->nwqs; i++) { | ||||
LOCK(&sc->wq[i]->tx_lock); | |||||
while ((m = buf_ring_dequeue_sc(sc->wq[i]->br)) != NULL) | while ((m = buf_ring_dequeue_sc(sc->wq[i]->br)) != NULL) | ||||
m_freem(m); | m_freem(m); | ||||
UNLOCK(&sc->wq[i]->tx_lock); | |||||
} | } | ||||
if_qflush(ifp); | if_qflush(ifp); | ||||
} | } | ||||
/***************************************************************************** | /***************************************************************************** | ||||
* Driver interrupt routines functions * | * Driver interrupt routines functions * | ||||
▲ Show 20 Lines • Show All 449 Lines • ▼ Show 20 Lines | oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, uint32_t status) | ||||
if (sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) { | if (sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) { | ||||
if (wq->ring->num_used < (wq->ring->num_items / 2)) { | if (wq->ring->num_used < (wq->ring->num_items / 2)) { | ||||
sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE); | sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE); | ||||
oce_tx_restart(sc, wq); | oce_tx_restart(sc, wq); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static void | |||||
oce_tx_clean(POCE_SOFTC sc) | |||||
{ | |||||
int i = 0; | |||||
struct oce_wq *wq; | |||||
for_all_wq_queues(sc, wq, i) { | |||||
LOCK(&wq->tx_lock); | |||||
while (wq->pkt_desc_tail != wq->pkt_desc_head) { | |||||
oce_tx_complete(wq, 0, 0); | |||||
} | |||||
UNLOCK(&wq->tx_lock); | |||||
} | |||||
} | |||||
static void | static void | ||||
oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq) | oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq) | ||||
{ | { | ||||
if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING) | if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING) | ||||
return; | return; | ||||
#if __FreeBSD_version >= 800000 | #if __FreeBSD_version >= 800000 | ||||
▲ Show 20 Lines • Show All 144 Lines • ▼ Show 20 Lines | |||||
oce_wq_handler(void *arg) | oce_wq_handler(void *arg) | ||||
{ | { | ||||
struct oce_wq *wq = (struct oce_wq *)arg; | struct oce_wq *wq = (struct oce_wq *)arg; | ||||
POCE_SOFTC sc = wq->parent; | POCE_SOFTC sc = wq->parent; | ||||
struct oce_cq *cq = wq->cq; | struct oce_cq *cq = wq->cq; | ||||
struct oce_nic_tx_cqe *cqe; | struct oce_nic_tx_cqe *cqe; | ||||
int num_cqes = 0; | int num_cqes = 0; | ||||
LOCK(&wq->tx_lock); | |||||
bus_dmamap_sync(cq->ring->dma.tag, | bus_dmamap_sync(cq->ring->dma.tag, | ||||
cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); | cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); | ||||
cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe); | cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe); | ||||
while (cqe->u0.dw[3]) { | while (cqe->u0.dw[3]) { | ||||
DW_SWAP((uint32_t *) cqe, sizeof(oce_wq_cqe)); | DW_SWAP((uint32_t *) cqe, sizeof(oce_wq_cqe)); | ||||
wq->ring->cidx = cqe->u0.s.wqe_index + 1; | wq->ring->cidx = cqe->u0.s.wqe_index + 1; | ||||
if (wq->ring->cidx >= wq->ring->num_items) | if (wq->ring->cidx >= wq->ring->num_items) | ||||
wq->ring->cidx -= wq->ring->num_items; | wq->ring->cidx -= wq->ring->num_items; | ||||
oce_tx_complete(wq, cqe->u0.s.wqe_index, cqe->u0.s.status); | oce_tx_complete(wq, cqe->u0.s.wqe_index, cqe->u0.s.status); | ||||
wq->tx_stats.tx_compl++; | wq->tx_stats.tx_compl++; | ||||
cqe->u0.dw[3] = 0; | cqe->u0.dw[3] = 0; | ||||
RING_GET(cq->ring, 1); | RING_GET(cq->ring, 1); | ||||
bus_dmamap_sync(cq->ring->dma.tag, | bus_dmamap_sync(cq->ring->dma.tag, | ||||
cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); | cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); | ||||
cqe = | cqe = | ||||
RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe); | RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe); | ||||
num_cqes++; | num_cqes++; | ||||
} | } | ||||
if (num_cqes) | if (num_cqes) | ||||
oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE); | oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE); | ||||
UNLOCK(&wq->tx_lock); | |||||
return 0; | return 0; | ||||
} | } | ||||
static int | static int | ||||
oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq) | oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq) | ||||
{ | { | ||||
POCE_SOFTC sc = ifp->if_softc; | POCE_SOFTC sc = ifp->if_softc; | ||||
▲ Show 20 Lines • Show All 835 Lines • ▼ Show 20 Lines | for (i = 0; i < sc->intr_count; i++) { | ||||
if (sc->intrs[i].tq != NULL) { | if (sc->intrs[i].tq != NULL) { | ||||
taskqueue_drain(sc->intrs[i].tq, &sc->intrs[i].task); | taskqueue_drain(sc->intrs[i].tq, &sc->intrs[i].task); | ||||
} | } | ||||
} | } | ||||
LOCK(&sc->dev_lock); | LOCK(&sc->dev_lock); | ||||
/* Delete RX queue in card with flush param */ | /* Delete RX queue in card with flush param */ | ||||
oce_stop_rx(sc); | oce_stop_rx(sc); | ||||
/* Flush the mbufs that are still in TX queues */ | |||||
oce_tx_clean(sc); | |||||
/* Invalidate any pending cq and eq entries*/ | /* Invalidate any pending cq and eq entries*/ | ||||
for_all_evnt_queues(sc, eq, i) | for_all_evnt_queues(sc, eq, i) | ||||
oce_drain_eq(eq); | oce_drain_eq(eq); | ||||
for_all_rq_queues(sc, rq, i) | for_all_rq_queues(sc, rq, i) | ||||
oce_drain_rq_cq(rq); | oce_drain_rq_cq(rq); | ||||
for_all_wq_queues(sc, wq, i) | for_all_wq_queues(sc, wq, i) | ||||
oce_drain_wq_cq(wq); | oce_drain_wq_cq(wq); | ||||
▲ Show 20 Lines • Show All 261 Lines • Show Last 20 Lines |