void octeon_eth_buf_ext_free_ext(caddr_t buf, u_int size, void *arg) { uint64_t *work = (void *)arg; cn30xxfpa_buf_put_paddr(octeon_eth_fb_wqe, XKPHYS_TO_PHYS(work)); cn30xxfpa_buf_put_paddr(octeon_eth_fb_pkt, XKPHYS_TO_PHYS(buf)); }
int octeon_eth_send(struct octeon_eth_softc *sc, struct mbuf *m) { paddr_t gaddr = 0; uint64_t *gbuf = NULL; int result = 0, error; gaddr = cn30xxfpa_buf_get_paddr(octeon_eth_fb_sg); if (gaddr == 0) { log(LOG_WARNING, "%s: cannot allocate gather buffer from free pool allocator\n", sc->sc_dev.dv_xname); result = 1; goto done; } gbuf = (uint64_t *)(uintptr_t)PHYS_TO_XKPHYS(gaddr, CCA_CACHED); error = octeon_eth_send_buf(sc, m, gbuf); if (error != 0) { /* already logging */ cn30xxfpa_buf_put_paddr(octeon_eth_fb_sg, gaddr); result = error; goto done; } octeon_eth_send_queue_add(sc, m, gbuf); done: return result; }
int cn30xxfpa_buf_init(int poolno, size_t size, size_t nelems, struct cn30xxfpa_buf **rfb) { struct cn30xxfpa_softc *sc = &cn30xxfpa_softc; struct cn30xxfpa_buf *fb; int nsegs; paddr_t paddr; nsegs = 1/* XXX */; fb = malloc(sizeof(*fb) + sizeof(*fb->fb_dma_segs) * nsegs, M_DEVBUF, M_WAITOK | M_ZERO); if (fb == NULL) return 1; fb->fb_poolno = poolno; fb->fb_size = size; fb->fb_nelems = nelems; fb->fb_len = size * nelems; fb->fb_dmat = sc->sc_dmat; fb->fb_dma_segs = (void *)(fb + 1); fb->fb_dma_nsegs = nsegs; cn30xxfpa_buf_dma_alloc(fb); for (paddr = fb->fb_paddr; paddr < fb->fb_paddr + fb->fb_len; paddr += fb->fb_size) cn30xxfpa_buf_put_paddr(fb, paddr); *rfb = fb; return 0; }
int octeon_eth_buf_free_work(struct octeon_eth_softc *sc, uint64_t *work, uint64_t word2) { /* XXX when jumbo frame */ if (ISSET(word2, PIP_WQE_WORD2_IP_BUFS)) { paddr_t addr; paddr_t start_buffer; addr = XKPHYS_TO_PHYS(work[3] & PIP_WQE_WORD3_ADDR); start_buffer = addr & ~(2048 - 1); cn30xxfpa_buf_put_paddr(octeon_eth_fb_pkt, start_buffer); } cn30xxfpa_buf_put_paddr(octeon_eth_fb_wqe, XKPHYS_TO_PHYS(work)); return 0; }
void octeon_eth_buf_ext_free_m(caddr_t buf, u_int size, void *arg) { uint64_t *work = (void *)arg; int s = splnet(); cn30xxfpa_buf_put_paddr(octeon_eth_fb_wqe, XKPHYS_TO_PHYS(work)); splx(s); }
void octeon_eth_send_queue_flush(struct octeon_eth_softc *sc) { const int64_t sent_count = sc->sc_hard_done_cnt; int i; OCTEON_ETH_KASSERT(sent_count <= 0); for (i = 0; i < 0 - sent_count; i++) { struct mbuf *m; uint64_t *gbuf; octeon_eth_send_queue_del(sc, &m, &gbuf); cn30xxfpa_buf_put_paddr(octeon_eth_fb_sg, XKPHYS_TO_PHYS(gbuf)); m_freem(m); } cn30xxfau_op_add_8(&sc->sc_fau_done, i); }