Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/allwinner/if_awg.c
Show First 20 Lines • Show All 384 Lines • ▼ Show 20 Lines | awg_media_change(if_t ifp) | ||||
AWG_UNLOCK(sc); | AWG_UNLOCK(sc); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
awg_setup_txbuf(struct awg_softc *sc, int index, struct mbuf **mp) | awg_setup_txbuf(struct awg_softc *sc, int index, struct mbuf **mp) | ||||
{ | { | ||||
bus_dmamap_t map; | |||||
bus_dma_segment_t segs[TX_MAX_SEGS]; | bus_dma_segment_t segs[TX_MAX_SEGS]; | ||||
int error, nsegs, cur, first, i; | int error, nsegs, cur, first, last, i; | ||||
u_int csum_flags; | u_int csum_flags; | ||||
uint32_t flags, status; | uint32_t flags, status; | ||||
struct mbuf *m; | struct mbuf *m; | ||||
cur = first = index; | cur = first = index; | ||||
map = sc->tx.buf_map[first].map; | |||||
m = *mp; | m = *mp; | ||||
error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, | error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, map, m, segs, | ||||
sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT); | &nsegs, BUS_DMA_NOWAIT); | ||||
if (error == EFBIG) { | if (error == EFBIG) { | ||||
m = m_collapse(m, M_NOWAIT, TX_MAX_SEGS); | m = m_collapse(m, M_NOWAIT, TX_MAX_SEGS); | ||||
if (m == NULL) { | if (m == NULL) { | ||||
device_printf(sc->dev, "awg_setup_txbuf: m_collapse failed\n"); | device_printf(sc->dev, "awg_setup_txbuf: m_collapse failed\n"); | ||||
return (0); | return (0); | ||||
} | } | ||||
*mp = m; | *mp = m; | ||||
error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, | error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, map, m, | ||||
sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT); | segs, &nsegs, BUS_DMA_NOWAIT); | ||||
} | } | ||||
if (error != 0) { | if (error != 0) { | ||||
device_printf(sc->dev, "awg_setup_txbuf: bus_dmamap_load_mbuf_sg failed\n"); | device_printf(sc->dev, "awg_setup_txbuf: bus_dmamap_load_mbuf_sg failed\n"); | ||||
return (0); | return (0); | ||||
} | } | ||||
bus_dmamap_sync(sc->tx.buf_tag, sc->tx.buf_map[index].map, | bus_dmamap_sync(sc->tx.buf_tag, map, BUS_DMASYNC_PREWRITE); | ||||
BUS_DMASYNC_PREWRITE); | |||||
flags = TX_FIR_DESC; | flags = TX_FIR_DESC; | ||||
status = 0; | status = 0; | ||||
if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) { | if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) { | ||||
if ((m->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP)) != 0) | if ((m->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP)) != 0) | ||||
csum_flags = TX_CHECKSUM_CTL_FULL; | csum_flags = TX_CHECKSUM_CTL_FULL; | ||||
else | else | ||||
csum_flags = TX_CHECKSUM_CTL_IP; | csum_flags = TX_CHECKSUM_CTL_IP; | ||||
Show All 24 Lines | for (i = 0; i < nsegs; i++) { | ||||
* deferred until the whole chain is fully set up. | * deferred until the whole chain is fully set up. | ||||
*/ | */ | ||||
status = TX_DESC_CTL; | status = TX_DESC_CTL; | ||||
++sc->tx.queued; | ++sc->tx.queued; | ||||
cur = TX_NEXT(cur); | cur = TX_NEXT(cur); | ||||
} | } | ||||
sc->tx.buf_map[first].mbuf = m; | /* Store mapping and mbuf in the last segment */ | ||||
last = TX_SKIP(cur, TX_DESC_COUNT - 1); | |||||
sc->tx.buf_map[first].map = sc->tx.buf_map[last].map; | |||||
sc->tx.buf_map[last].map = map; | |||||
sc->tx.buf_map[last].mbuf = m; | |||||
/* | /* | ||||
* The whole mbuf chain has been DMA mapped, | * The whole mbuf chain has been DMA mapped, | ||||
* fix the first descriptor. | * fix the first descriptor. | ||||
*/ | */ | ||||
sc->tx.desc_ring[first].status = htole32(TX_DESC_CTL); | sc->tx.desc_ring[first].status = htole32(TX_DESC_CTL); | ||||
return (nsegs); | return (nsegs); | ||||
▲ Show 20 Lines • Show All 1,261 Lines • Show Last 20 Lines |