bus/fslmc: add QBMAN API to do enqueue with multiple frames
Clean it up and update the prototype. Signed-off-by: Haiying Wang <haiying.wang@nxp.com> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
This commit is contained in:
parent
cb3bfcbb21
commit
43f7ff9de4
@ -914,19 +914,33 @@ void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
|
||||
int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd);
|
||||
/**
|
||||
* qbman_swp_enqueue_multiple_eqdesc() - Enqueue multiple frames with separte
|
||||
* enqueue descriptors.
|
||||
* qbman_swp_enqueue_multiple() - Enqueue multiple frames with same
|
||||
eq descriptor
|
||||
* @s: the software portal used for enqueue.
|
||||
* @d: the enqueue descriptors
|
||||
* @d: the enqueue descriptor.
|
||||
* @fd: the frame descriptor to be enqueued.
|
||||
* @num_frames: the number of the frames to be enqueued.
|
||||
*
|
||||
* Return the number of enqueued frames, -EBUSY if the EQCR is not ready.
|
||||
*/
|
||||
int qbman_swp_enqueue_multiple_eqdesc(struct qbman_swp *s,
|
||||
int qbman_swp_enqueue_multiple(struct qbman_swp *s,
|
||||
const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd,
|
||||
int num_frames);
|
||||
/**
|
||||
* qbman_swp_enqueue_multiple_desc() - Enqueue multiple frames with
|
||||
* individual eq descriptor.
|
||||
* @s: the software portal used for enqueue.
|
||||
* @d: the enqueue descriptor.
|
||||
* @fd: the frame descriptor to be enqueued.
|
||||
* @num_frames: the number of the frames to be enqueued.
|
||||
*
|
||||
* Return the number of enqueued frames, -EBUSY if the EQCR is not ready.
|
||||
*/
|
||||
int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
|
||||
const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd,
|
||||
int num_frames);
|
||||
|
||||
/* TODO:
|
||||
* qbman_swp_enqueue_thresh() - Set threshold for EQRI interrupt.
|
||||
@ -1119,16 +1133,6 @@ int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid);
|
||||
*/
|
||||
int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
|
||||
uint64_t ctx);
|
||||
int qbman_swp_fill_ring(struct qbman_swp *s,
|
||||
const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd,
|
||||
uint8_t burst_index);
|
||||
int qbman_swp_flush_ring(struct qbman_swp *s);
|
||||
void qbman_sync(void);
|
||||
int qbman_swp_send_multiple(struct qbman_swp *s,
|
||||
const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd,
|
||||
int frames_to_send);
|
||||
|
||||
int qbman_check_command_complete(struct qbman_swp *s,
|
||||
const struct qbman_result *dq);
|
||||
|
@ -525,64 +525,6 @@ static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qbman_swp_fill_ring(struct qbman_swp *s,
|
||||
const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd,
|
||||
__attribute__((unused)) uint8_t burst_index)
|
||||
{
|
||||
uint32_t *p;
|
||||
const uint32_t *cl = qb_cl(d);
|
||||
uint32_t eqcr_ci;
|
||||
uint8_t diff;
|
||||
|
||||
if (!s->eqcr.available) {
|
||||
eqcr_ci = s->eqcr.ci;
|
||||
s->eqcr.ci = qbman_cena_read_reg(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR_CI) & 0xF;
|
||||
diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
|
||||
eqcr_ci, s->eqcr.ci);
|
||||
s->eqcr.available += diff;
|
||||
if (!diff)
|
||||
return -EBUSY;
|
||||
}
|
||||
p = qbman_cena_write_start_wo_shadow(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR((s->eqcr.pi/* +burst_index */) & 7));
|
||||
memcpy(&p[1], &cl[1], 7 * 4);
|
||||
memcpy(&p[8], fd, sizeof(struct qbman_fd));
|
||||
|
||||
/* lwsync(); */
|
||||
p[0] = cl[0] | s->eqcr.pi_vb;
|
||||
|
||||
s->eqcr.pi++;
|
||||
s->eqcr.pi &= 0xF;
|
||||
s->eqcr.available--;
|
||||
if (!(s->eqcr.pi & 7))
|
||||
s->eqcr.pi_vb ^= QB_VALID_BIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qbman_swp_flush_ring(struct qbman_swp *s)
|
||||
{
|
||||
void *ptr = s->sys.addr_cena;
|
||||
|
||||
dcbf((uint64_t)ptr);
|
||||
dcbf((uint64_t)ptr + 0x40);
|
||||
dcbf((uint64_t)ptr + 0x80);
|
||||
dcbf((uint64_t)ptr + 0xc0);
|
||||
dcbf((uint64_t)ptr + 0x100);
|
||||
dcbf((uint64_t)ptr + 0x140);
|
||||
dcbf((uint64_t)ptr + 0x180);
|
||||
dcbf((uint64_t)ptr + 0x1c0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qbman_sync(void)
|
||||
{
|
||||
lwsync();
|
||||
}
|
||||
|
||||
int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd)
|
||||
{
|
||||
@ -592,7 +534,7 @@ int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
|
||||
return qbman_swp_enqueue_ring_mode(s, d, fd);
|
||||
}
|
||||
|
||||
int qbman_swp_enqueue_multiple_eqdesc(struct qbman_swp *s,
|
||||
int qbman_swp_enqueue_multiple(struct qbman_swp *s,
|
||||
const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd,
|
||||
int num_frames)
|
||||
@ -627,15 +569,12 @@ int qbman_swp_enqueue_multiple_eqdesc(struct qbman_swp *s,
|
||||
memcpy(&p[8], &fd[i], sizeof(*fd));
|
||||
eqcr_pi++;
|
||||
eqcr_pi &= 0xF;
|
||||
/*Pointing to the next enqueue descriptor*/
|
||||
cl += (sizeof(struct qbman_eq_desc) / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
lwsync();
|
||||
|
||||
/* Set the verb byte, have to substitute in the valid-bit */
|
||||
eqcr_pi = s->eqcr.pi;
|
||||
cl = qb_cl(d);
|
||||
for (i = 0; i < num_enqueued; i++) {
|
||||
p = qbman_cena_write_start_wo_shadow(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR(eqcr_pi & 7));
|
||||
@ -644,8 +583,73 @@ int qbman_swp_enqueue_multiple_eqdesc(struct qbman_swp *s,
|
||||
eqcr_pi &= 0xF;
|
||||
if (!(eqcr_pi & 7))
|
||||
s->eqcr.pi_vb ^= QB_VALID_BIT;
|
||||
/*Pointing to the next enqueue descriptor*/
|
||||
cl += (sizeof(struct qbman_eq_desc) / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
/* Flush all the cacheline without load/store in between */
|
||||
eqcr_pi = s->eqcr.pi;
|
||||
addr_cena = (uint64_t)s->sys.addr_cena;
|
||||
for (i = 0; i < num_enqueued; i++) {
|
||||
dcbf((uint64_t *)(addr_cena +
|
||||
QBMAN_CENA_SWP_EQCR(eqcr_pi & 7)));
|
||||
eqcr_pi++;
|
||||
eqcr_pi &= 0xF;
|
||||
}
|
||||
s->eqcr.pi = eqcr_pi;
|
||||
|
||||
return num_enqueued;
|
||||
}
|
||||
|
||||
int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
|
||||
const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd,
|
||||
int num_frames)
|
||||
{
|
||||
uint32_t *p;
|
||||
const uint32_t *cl;
|
||||
uint32_t eqcr_ci, eqcr_pi;
|
||||
uint8_t diff;
|
||||
int i, num_enqueued = 0;
|
||||
uint64_t addr_cena;
|
||||
|
||||
if (!s->eqcr.available) {
|
||||
eqcr_ci = s->eqcr.ci;
|
||||
s->eqcr.ci = qbman_cena_read_reg(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR_CI) & 0xF;
|
||||
diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
|
||||
eqcr_ci, s->eqcr.ci);
|
||||
s->eqcr.available += diff;
|
||||
if (!diff)
|
||||
return 0;
|
||||
}
|
||||
|
||||
eqcr_pi = s->eqcr.pi;
|
||||
num_enqueued = (s->eqcr.available < num_frames) ?
|
||||
s->eqcr.available : num_frames;
|
||||
s->eqcr.available -= num_enqueued;
|
||||
/* Fill in the EQCR ring */
|
||||
for (i = 0; i < num_enqueued; i++) {
|
||||
p = qbman_cena_write_start_wo_shadow(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR(eqcr_pi & 7));
|
||||
cl = qb_cl(&d[i]);
|
||||
memcpy(&p[1], &cl[1], 28);
|
||||
memcpy(&p[8], &fd[i], sizeof(*fd));
|
||||
eqcr_pi++;
|
||||
eqcr_pi &= 0xF;
|
||||
}
|
||||
|
||||
lwsync();
|
||||
|
||||
/* Set the verb byte, have to substitute in the valid-bit */
|
||||
eqcr_pi = s->eqcr.pi;
|
||||
for (i = 0; i < num_enqueued; i++) {
|
||||
p = qbman_cena_write_start_wo_shadow(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR(eqcr_pi & 7));
|
||||
cl = qb_cl(&d[i]);
|
||||
p[0] = cl[0] | s->eqcr.pi_vb;
|
||||
eqcr_pi++;
|
||||
eqcr_pi &= 0xF;
|
||||
if (!(eqcr_pi & 7))
|
||||
s->eqcr.pi_vb ^= QB_VALID_BIT;
|
||||
}
|
||||
|
||||
/* Flush all the cacheline without load/store in between */
|
||||
@ -1493,87 +1497,3 @@ struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx)
|
||||
dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(idx));
|
||||
return dq;
|
||||
}
|
||||
|
||||
int qbman_swp_send_multiple(struct qbman_swp *s,
|
||||
const struct qbman_eq_desc *d,
|
||||
const struct qbman_fd *fd,
|
||||
int frames_to_send)
|
||||
{
|
||||
uint32_t *p;
|
||||
const uint32_t *cl = qb_cl(d);
|
||||
uint32_t eqcr_ci;
|
||||
uint8_t diff;
|
||||
int sent = 0;
|
||||
int i;
|
||||
int initial_pi = s->eqcr.pi;
|
||||
uint64_t start_pointer;
|
||||
|
||||
if (!s->eqcr.available) {
|
||||
eqcr_ci = s->eqcr.ci;
|
||||
s->eqcr.ci = qbman_cena_read_reg(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR_CI) & 0xF;
|
||||
diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
|
||||
eqcr_ci, s->eqcr.ci);
|
||||
if (!diff)
|
||||
goto done;
|
||||
s->eqcr.available += diff;
|
||||
}
|
||||
|
||||
/* we are trying to send frames_to_send,
|
||||
* if we have enough space in the ring
|
||||
*/
|
||||
while (s->eqcr.available && frames_to_send--) {
|
||||
p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
|
||||
/* Write command (except of first byte) and FD */
|
||||
memcpy(&p[1], &cl[1], 7 * 4);
|
||||
memcpy(&p[8], &fd[sent], sizeof(struct qbman_fd));
|
||||
|
||||
initial_pi++;
|
||||
initial_pi &= 0xF;
|
||||
s->eqcr.available--;
|
||||
sent++;
|
||||
}
|
||||
|
||||
done:
|
||||
initial_pi = s->eqcr.pi;
|
||||
lwsync();
|
||||
|
||||
/* in order for flushes to complete faster:
|
||||
* we use a following trick: we record all lines in 32 bit word
|
||||
*/
|
||||
|
||||
initial_pi = s->eqcr.pi;
|
||||
for (i = 0; i < sent; i++) {
|
||||
p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
|
||||
QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
|
||||
|
||||
p[0] = cl[0] | s->eqcr.pi_vb;
|
||||
initial_pi++;
|
||||
initial_pi &= 0xF;
|
||||
|
||||
if (!(initial_pi & 7))
|
||||
s->eqcr.pi_vb ^= QB_VALID_BIT;
|
||||
}
|
||||
|
||||
initial_pi = s->eqcr.pi;
|
||||
|
||||
/* We need to flush all the lines but without
|
||||
* load/store operations between them.
|
||||
* We assign start_pointer before we start loop so that
|
||||
* in loop we do not read it from memory
|
||||
*/
|
||||
start_pointer = (uint64_t)s->sys.addr_cena;
|
||||
for (i = 0; i < sent; i++) {
|
||||
p = (uint32_t *)(start_pointer
|
||||
+ QBMAN_CENA_SWP_EQCR(initial_pi & 7));
|
||||
dcbf((uint64_t)p);
|
||||
initial_pi++;
|
||||
initial_pi &= 0xF;
|
||||
}
|
||||
|
||||
/* Update producer index for the next call */
|
||||
s->eqcr.pi = initial_pi;
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
@ -69,7 +69,8 @@ DPDK_17.08 {
|
||||
qbman_result_SCN_state_in_mem;
|
||||
qbman_swp_dqrr_consume;
|
||||
qbman_swp_dqrr_next;
|
||||
qbman_swp_enqueue_multiple_eqdesc;
|
||||
qbman_swp_enqueue_multiple;
|
||||
qbman_swp_enqueue_multiple_desc;
|
||||
qbman_swp_interrupt_clear_status;
|
||||
qbman_swp_push_set;
|
||||
rte_dpaa2_alloc_dpci_dev;
|
||||
|
@ -634,7 +634,7 @@ dpaa2_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops,
|
||||
}
|
||||
loop = 0;
|
||||
while (loop < frames_to_send) {
|
||||
loop += qbman_swp_send_multiple(swp, &eqdesc,
|
||||
loop += qbman_swp_enqueue_multiple(swp, &eqdesc,
|
||||
&fd_arr[loop],
|
||||
frames_to_send - loop);
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ dpaa2_eventdev_enqueue_burst(void *port, const struct rte_event ev[],
|
||||
}
|
||||
loop = 0;
|
||||
while (loop < frames_to_send) {
|
||||
loop += qbman_swp_enqueue_multiple_eqdesc(swp,
|
||||
loop += qbman_swp_enqueue_multiple_desc(swp,
|
||||
&eqdesc[loop], &fd_arr[loop],
|
||||
frames_to_send - loop);
|
||||
}
|
||||
|
@ -622,7 +622,7 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
|
||||
}
|
||||
loop = 0;
|
||||
while (loop < frames_to_send) {
|
||||
loop += qbman_swp_send_multiple(swp, &eqdesc,
|
||||
loop += qbman_swp_enqueue_multiple(swp, &eqdesc,
|
||||
&fd_arr[loop], frames_to_send - loop);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user