| 2415 | #endif /* DEVICE_POLLING */ |
| 2416 | |
| 2417 | static void |
| 2418 | arge_tx_locked(struct arge_softc *sc) |
| 2419 | { |
| 2420 | struct arge_txdesc *txd; |
| 2421 | struct arge_desc *cur_tx; |
| 2422 | struct ifnet *ifp; |
| 2423 | uint32_t ctrl; |
| 2424 | int cons, prod; |
| 2425 | |
| 2426 | ARGE_LOCK_ASSERT(sc); |
| 2427 | |
| 2428 | cons = sc->arge_cdata.arge_tx_cons; |
| 2429 | prod = sc->arge_cdata.arge_tx_prod; |
| 2430 | |
| 2431 | ARGEDEBUG(sc, ARGE_DBG_TX, "%s: cons=%d, prod=%d\n", __func__, cons, |
| 2432 | prod); |
| 2433 | |
| 2434 | if (cons == prod) |
| 2435 | return; |
| 2436 | |
| 2437 | bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, |
| 2438 | sc->arge_cdata.arge_tx_ring_map, |
| 2439 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
| 2440 | |
| 2441 | ifp = sc->arge_ifp; |
| 2442 | /* |
| 2443 | * Go through our tx list and free mbufs for those |
| 2444 | * frames that have been transmitted. |
| 2445 | */ |
| 2446 | for (; cons != prod; ARGE_INC(cons, ARGE_TX_RING_COUNT)) { |
| 2447 | cur_tx = &sc->arge_rdata.arge_tx_ring[cons]; |
| 2448 | ctrl = cur_tx->packet_ctrl; |
| 2449 | /* Check if descriptor has "finished" flag */ |
| 2450 | if ((ctrl & ARGE_DESC_EMPTY) == 0) |
| 2451 | break; |
| 2452 | |
| 2453 | ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_PKT_SENT); |
| 2454 | |
| 2455 | sc->arge_cdata.arge_tx_cnt--; |
| 2456 | ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; |
| 2457 | |
| 2458 | txd = &sc->arge_cdata.arge_txdesc[cons]; |
| 2459 | |
| 2460 | if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); |
| 2461 | |
| 2462 | bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, |
| 2463 | BUS_DMASYNC_POSTWRITE); |
| 2464 | bus_dmamap_unload(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap); |
| 2465 | |
| 2466 | /* Free only if it's first descriptor in list */ |
| 2467 | if (txd->tx_m) |
| 2468 | m_freem(txd->tx_m); |
| 2469 | txd->tx_m = NULL; |
| 2470 | |
| 2471 | /* reset descriptor */ |
| 2472 | cur_tx->packet_addr = 0; |
| 2473 | } |
| 2474 |
no test coverage detected