Esempio n. 1
0
static void copy_wr_to_sq(struct t4_wq *wq, union t4_wr *wqe, u8 len16)
{
	u64 *src, *dst;

	src = (u64 *)wqe;
	dst = (u64 *)((u8 *)wq->sq.queue + wq->sq.wq_pidx * T4_EQ_ENTRY_SIZE);
	if (t4_sq_onchip(wq)) {
		len16 = align(len16, 4);

		/* In onchip mode the copy below will be made to WC memory and
		 * could trigger DMA. In offchip mode the copy below only
		 * queues the WQE, DMA cannot start until t4_ring_sq_db
		 * happens */
		mmio_wc_start();
	}
	while (len16) {
		*dst++ = *src++;
		if (dst == (u64 *)&wq->sq.queue[wq->sq.size])
			dst = (u64 *)wq->sq.queue;
		*dst++ = *src++;
		if (dst == (u64 *)&wq->sq.queue[wq->sq.size])
			dst = (u64 *)wq->sq.queue;
		len16--;

		/* NOTE len16 cannot be large enough to write to the
		   same sq.queue memory twice in this loop */
	}

	if (t4_sq_onchip(wq))
		mmio_flush_writes();
}
Esempio n. 2
0
static void copy_wr_to_sq(struct t4_wq *wq, union t4_wr *wqe, u8 len16)
{
	void *src, *dst;
	uintptr_t end;
	int total, len;

	src = &wqe->flits[0];
	dst = &wq->sq.queue->flits[wq->sq.wq_pidx *
	    (T4_EQ_ENTRY_SIZE / sizeof(__be64))];
	if (t4_sq_onchip(wq)) {
		len16 = align(len16, 4);

		/* In onchip mode the copy below will be made to WC memory and
		 * could trigger DMA. In offchip mode the copy below only
		 * queues the WQE, DMA cannot start until t4_ring_sq_db
		 * happens */
		mmio_wc_start();
	}

	/* NOTE len16 cannot be large enough to write to the
	   same sq.queue memory twice in this loop */
	total = len16 * 16;
	end = (uintptr_t)&wq->sq.queue[wq->sq.size];
	if (__predict_true((uintptr_t)dst + total <= end)) {
		/* Won't wrap around. */
		memcpy(dst, src, total);
	} else {
		len = end - (uintptr_t)dst;
		memcpy(dst, src, len);
		memcpy(wq->sq.queue, src + len, total - len);
	}

	if (t4_sq_onchip(wq))
		mmio_flush_writes();
}