X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fbus%2Ffslmc%2Fqbman%2Fqbman_portal.c;h=dd62e9af3fff18375e9d903ab67dc95377e837cd;hb=3af0c2a203e16d83ea86754efb70c030956ff85b;hp=be4e2e5776d4ab73b84aa58cb2831370151c2cc9;hpb=98a7ea332ba3da0f74ec951595d36a616165b255;p=dpdk.git diff --git a/drivers/bus/fslmc/qbman/qbman_portal.c b/drivers/bus/fslmc/qbman/qbman_portal.c index be4e2e5776..dd62e9af3f 100644 --- a/drivers/bus/fslmc/qbman/qbman_portal.c +++ b/drivers/bus/fslmc/qbman/qbman_portal.c @@ -44,6 +44,8 @@ #define QBMAN_CINH_SWP_IER 0xe40 #define QBMAN_CINH_SWP_ISDR 0xe80 #define QBMAN_CINH_SWP_IIR 0xec0 +#define QBMAN_CINH_SWP_DQRR_ITR 0xa80 +#define QBMAN_CINH_SWP_ITPR 0xf40 /* CENA register offsets */ #define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6)) @@ -218,6 +220,26 @@ void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask) qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask); } +uint32_t qbman_swp_dqrr_thrshld_read_status(struct qbman_swp *p) +{ + return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_DQRR_ITR); +} + +void qbman_swp_dqrr_thrshld_write(struct qbman_swp *p, uint32_t mask) +{ + qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_DQRR_ITR, mask); +} + +uint32_t qbman_swp_intr_timeout_read_status(struct qbman_swp *p) +{ + return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ITPR); +} + +void qbman_swp_intr_timeout_write(struct qbman_swp *p, uint32_t mask) +{ + qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ITPR, mask); +} + uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p) { return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER); @@ -574,6 +596,76 @@ 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, + const struct qbman_eq_desc *d, + const struct qbman_fd *fd, + int num_frames) +{ + uint32_t *p; + const uint32_t *cl = qb_cl(d); + 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)); + memcpy(&p[1], &cl[1], 28); + 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)); + p[0] = cl[0] | s->eqcr.pi_vb; + eqcr_pi++; + 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; +} + /*************************/ /* Static (push) dequeue */ /*************************/ @@ -1393,7 +1485,7 @@ int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid, 1, ctx); } -uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr) +uint8_t qbman_get_dqrr_idx(const struct qbman_result *dqrr) { return QBMAN_IDX_FROM_DQRR(dqrr); }