Пример #1
0
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));
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
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);
}
Пример #6
0
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);
}