| 1739 | } |
| 1740 | |
| 1741 | static void |
| 1742 | cpsw_rx_enqueue(struct cpsw_softc *sc) |
| 1743 | { |
| 1744 | bus_dma_segment_t seg[1]; |
| 1745 | struct cpsw_cpdma_bd bd; |
| 1746 | struct cpsw_slot *first_new_slot, *last_old_slot, *next, *slot; |
| 1747 | int error, nsegs, added = 0; |
| 1748 | |
| 1749 | /* Register new mbufs with hardware. */ |
| 1750 | first_new_slot = NULL; |
| 1751 | last_old_slot = STAILQ_LAST(&sc->rx.active, cpsw_slot, next); |
| 1752 | while ((slot = STAILQ_FIRST(&sc->rx.avail)) != NULL) { |
| 1753 | if (first_new_slot == NULL) |
| 1754 | first_new_slot = slot; |
| 1755 | if (slot->mbuf == NULL) { |
| 1756 | slot->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); |
| 1757 | if (slot->mbuf == NULL) { |
| 1758 | device_printf(sc->dev, |
| 1759 | "Unable to fill RX queue\n"); |
| 1760 | break; |
| 1761 | } |
| 1762 | slot->mbuf->m_len = |
| 1763 | slot->mbuf->m_pkthdr.len = |
| 1764 | slot->mbuf->m_ext.ext_size; |
| 1765 | } |
| 1766 | |
| 1767 | error = bus_dmamap_load_mbuf_sg(sc->mbuf_dtag, slot->dmamap, |
| 1768 | slot->mbuf, seg, &nsegs, BUS_DMA_NOWAIT); |
| 1769 | |
| 1770 | KASSERT(nsegs == 1, ("More than one segment (nsegs=%d)", nsegs)); |
| 1771 | KASSERT(error == 0, ("DMA error (error=%d)", error)); |
| 1772 | if (error != 0 || nsegs != 1) { |
| 1773 | device_printf(sc->dev, |
| 1774 | "%s: Can't prep RX buf for DMA (nsegs=%d, error=%d)\n", |
| 1775 | __func__, nsegs, error); |
| 1776 | bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap); |
| 1777 | m_freem(slot->mbuf); |
| 1778 | slot->mbuf = NULL; |
| 1779 | break; |
| 1780 | } |
| 1781 | |
| 1782 | bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_PREREAD); |
| 1783 | |
| 1784 | /* Create and submit new rx descriptor. */ |
| 1785 | if ((next = STAILQ_NEXT(slot, next)) != NULL) |
| 1786 | bd.next = cpsw_cpdma_bd_paddr(sc, next); |
| 1787 | else |
| 1788 | bd.next = 0; |
| 1789 | bd.bufptr = seg->ds_addr; |
| 1790 | bd.bufoff = 0; |
| 1791 | bd.buflen = MCLBYTES - 1; |
| 1792 | bd.pktlen = bd.buflen; |
| 1793 | bd.flags = CPDMA_BD_OWNER; |
| 1794 | cpsw_cpdma_write_bd(sc, slot, &bd); |
| 1795 | ++added; |
| 1796 | |
| 1797 | STAILQ_REMOVE_HEAD(&sc->rx.avail, next); |
| 1798 | STAILQ_INSERT_TAIL(&sc->rx.active, slot, next); |
no test coverage detected