#include "qman.h"
#include <rte_branch_prediction.h>
+#include <rte_dpaa_bus.h>
/* Compilation constants */
#define DQRR_MAXFILL 15
p = &portal->p;
- portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ? 1 : 0);
+ if (dpaa_svr_family == SVR_LS1043A_FAMILY)
+ portal->use_eqcr_ci_stashing = 3;
+ else
+ portal->use_eqcr_ci_stashing =
+ ((qman_ip_rev >= QMAN_REV30) ? 1 : 0);
+
/*
* prep the low-level portal struct with the mapped addresses from the
* config, everything that follows depends on it and "config" is more
* and stash with high-than-DQRR priority.
*/
if (qm_eqcr_init(p, qm_eqcr_pvb,
- portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
+ portal->use_eqcr_ci_stashing, 1)) {
pr_err("Qman EQCR initialisation failed\n");
goto fail_eqcr;
}
return NULL;
}
+#define MAX_GLOBAL_PORTALS 8
+static struct qman_portal global_portals[MAX_GLOBAL_PORTALS];
+static int global_portals_used[MAX_GLOBAL_PORTALS];
+
+static struct qman_portal *
+qman_alloc_global_portal(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAX_GLOBAL_PORTALS; i++) {
+ if (global_portals_used[i] == 0) {
+ global_portals_used[i] = 1;
+ return &global_portals[i];
+ }
+ }
+ pr_err("No portal available (%x)\n", MAX_GLOBAL_PORTALS);
+
+ return NULL;
+}
+
+static int
+qman_free_global_portal(struct qman_portal *portal)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAX_GLOBAL_PORTALS; i++) {
+ if (&global_portals[i] == portal) {
+ global_portals_used[i] = 0;
+ return 0;
+ }
+ }
+ return -1;
+}
+
struct qman_portal *qman_create_affine_portal(const struct qm_portal_config *c,
- const struct qman_cgrs *cgrs)
+ const struct qman_cgrs *cgrs,
+ int alloc)
{
struct qman_portal *res;
- struct qman_portal *portal = get_affine_portal();
+ struct qman_portal *portal;
+
+ if (alloc)
+ portal = qman_alloc_global_portal();
+ else
+ portal = get_affine_portal();
+
/* A criteria for calling this function (from qman_driver.c) is that
* we're already affine to the cpu and won't schedule onto another cpu.
*/
spin_lock_destroy(&qm->cgr_lock);
}
-const struct qm_portal_config *qman_destroy_affine_portal(void)
+const struct qm_portal_config *
+qman_destroy_affine_portal(struct qman_portal *qp)
{
/* We don't want to redirect if we're a slave, use "raw" */
- struct qman_portal *qm = get_affine_portal();
+ struct qman_portal *qm;
const struct qm_portal_config *pcfg;
int cpu;
+ if (qp == NULL)
+ qm = get_affine_portal();
+ else
+ qm = qp;
pcfg = qm->config;
cpu = pcfg->cpu;
spin_lock(&affine_mask_lock);
CPU_CLR(cpu, &affine_mask);
spin_unlock(&affine_mask_lock);
+
+ qman_free_global_portal(qm);
+
return pcfg;
}
do {
qm_dqrr_pvb_update(&p->p);
dq = qm_dqrr_current(&p->p);
- if (!dq)
+ if (unlikely(!dq))
break;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
/* If running on an LE system the fields of the
qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
}
-void qman_static_dequeue_add(u32 pools)
+void qman_static_dequeue_add(u32 pools, struct qman_portal *qp)
{
- struct qman_portal *p = get_affine_portal();
+ struct qman_portal *p = qp ? qp : get_affine_portal();
pools &= p->config->pools;
p->sdqcr |= pools;
qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
}
-void qman_static_dequeue_del(u32 pools)
+void qman_static_dequeue_del(u32 pools, struct qman_portal *qp)
{
- struct qman_portal *p = get_affine_portal();
+ struct qman_portal *p = qp ? qp : get_affine_portal();
pools &= p->config->pools;
p->sdqcr &= ~pools;
qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
}
-u32 qman_static_dequeue_get(void)
+u32 qman_static_dequeue_get(struct qman_portal *qp)
{
- struct qman_portal *p = get_affine_portal();
+ struct qman_portal *p = qp ? qp : get_affine_portal();
return p->sdqcr;
}
}
spin_lock_init(&fq->fqlock);
fq->fqid = fqid;
+ fq->fqid_le = cpu_to_be32(fqid);
fq->flags = flags;
fq->state = qman_fq_state_oos;
fq->cgr_groupid = 0;
int qman_enqueue_multi(struct qman_fq *fq,
const struct qm_fd *fd,
- int frames_to_send)
+ int frames_to_send)
{
struct qman_portal *p = get_affine_portal();
struct qm_portal *portal = &p->p;
/* try to send as many frames as possible */
while (eqcr->available && frames_to_send--) {
- eq->fqid = cpu_to_be32(fq->fqid);
+ eq->fqid = fq->fqid_le;
#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
eq->tag = cpu_to_be32(fq->key);
#else