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:
Haiying Wang 2017-09-16 16:22:17 +05:30 committed by Ferruh Yigit
parent cb3bfcbb21
commit 43f7ff9de4
6 changed files with 91 additions and 166 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}