@@ -498,11 +498,10 @@ static inline void qm_mr_pvb_update(struct qm_portal *portal)
dcbit_ro(res);
}
-static inline
-struct qman_portal *qman_create_portal(
- struct qman_portal *portal,
- const struct qm_portal_config *c,
- const struct qman_cgrs *cgrs)
+struct qman_portal *
+qman_init_portal(struct qman_portal *portal,
+ const struct qm_portal_config *c,
+ const struct qman_cgrs *cgrs)
{
struct qm_portal *p;
char buf[16];
@@ -511,6 +510,9 @@ struct qman_portal *qman_create_portal(
p = &portal->p;
+ if (!c)
+ c = portal->config;
+
if (dpaa_svr_family == SVR_LS1043A_FAMILY)
portal->use_eqcr_ci_stashing = 3;
else
@@ -632,21 +634,23 @@ struct qman_portal *qman_create_portal(
static struct qman_portal global_portals[MAX_GLOBAL_PORTALS];
static rte_atomic16_t global_portals_used[MAX_GLOBAL_PORTALS];
-static struct qman_portal *
-qman_alloc_global_portal(void)
+struct qman_portal *
+qman_alloc_global_portal(struct qm_portal_config *q_pcfg)
{
unsigned int i;
for (i = 0; i < MAX_GLOBAL_PORTALS; i++) {
- if (rte_atomic16_test_and_set(&global_portals_used[i]))
+ if (rte_atomic16_test_and_set(&global_portals_used[i])) {
+ global_portals[i].config = q_pcfg;
return &global_portals[i];
+ }
}
pr_err("No portal available (%x)\n", MAX_GLOBAL_PORTALS);
return NULL;
}
-static int
+int
qman_free_global_portal(struct qman_portal *portal)
{
unsigned int i;
@@ -661,22 +665,15 @@ qman_free_global_portal(struct qman_portal *portal)
}
struct qman_portal *qman_create_affine_portal(const struct qm_portal_config *c,
- const struct qman_cgrs *cgrs,
- int alloc)
+ const struct qman_cgrs *cgrs)
{
struct qman_portal *res;
- struct qman_portal *portal;
-
- if (alloc)
- portal = qman_alloc_global_portal();
- else
- portal = get_affine_portal();
+ struct qman_portal *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.
*/
-
- res = qman_create_portal(portal, c, cgrs);
+ res = qman_init_portal(portal, c, cgrs);
if (res) {
spin_lock(&affine_mask_lock);
CPU_SET(c->cpu, &affine_mask);
@@ -62,7 +62,7 @@ static int fsl_qman_portal_init(uint32_t index, int is_shared)
qpcfg.node = NULL;
qpcfg.irq = qmfd;
- portal = qman_create_affine_portal(&qpcfg, NULL, 0);
+ portal = qman_create_affine_portal(&qpcfg, NULL);
if (!portal) {
pr_err("Qman portal initialisation failed (%d)\n",
qpcfg.cpu);
@@ -121,13 +121,13 @@ void qman_thread_irq(void)
out_be32(qpcfg.addr_virt[DPAA_PORTAL_CI] + 0x36C0, 0);
}
-struct qman_portal *fsl_qman_portal_create(void)
+struct qman_portal *fsl_qman_fq_portal_create(void)
{
- struct qman_portal *res;
+ struct qman_portal *portal = NULL;
struct qm_portal_config *q_pcfg;
struct dpaa_ioctl_irq_map irq_map;
struct dpaa_ioctl_portal_map q_map = {0};
- int q_fd, ret;
+ int q_fd = 0, ret;
q_pcfg = kzalloc((sizeof(struct qm_portal_config)), 0);
if (!q_pcfg) {
@@ -155,38 +155,58 @@ struct qman_portal *fsl_qman_portal_create(void)
q_fd = open(QMAN_PORTAL_IRQ_PATH, O_RDONLY);
if (q_fd == -1) {
pr_err("QMan irq init failed\n");
- goto err1;
+ goto err;
}
q_pcfg->irq = q_fd;
- res = qman_create_affine_portal(q_pcfg, NULL, true);
- if (!res) {
+ portal = qman_alloc_global_portal(q_pcfg);
+ if (!portal) {
pr_err("Qman portal initialisation failed (%d)\n",
q_pcfg->cpu);
- goto err2;
+ goto err;
}
irq_map.type = dpaa_portal_qman;
irq_map.portal_cinh = q_map.addr.cinh;
process_portal_irq_map(q_fd, &irq_map);
- return res;
-err2:
- close(q_fd);
-err1:
+ return portal;
+err:
+ if (portal)
+ qman_free_global_portal(portal);
+ if (q_fd)
+ close(q_fd);
process_portal_unmap(&q_map.addr);
kfree(q_pcfg);
return NULL;
}
-int fsl_qman_portal_destroy(struct qman_portal *qp)
+int fsl_qman_fq_portal_init(struct qman_portal *qp)
+{
+ struct qman_portal *res;
+
+ res = qman_init_portal(qp, NULL, NULL);
+ if (!res) {
+ pr_err("Qman portal initialisation failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int fsl_qman_fq_portal_destroy(struct qman_portal *qp)
{
const struct qm_portal_config *cfg;
struct dpaa_portal_map addr;
int ret;
cfg = qman_destroy_affine_portal(qp);
+
+ ret = qman_free_global_portal(qp);
+ if (ret)
+ pr_err("qman_free_global_portal() (%d)\n", ret);
+
kfree(qp);
process_portal_irq_unmap(cfg->irq);
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017 NXP
+ * Copyright 2017,2019 NXP
*
*/
@@ -145,11 +145,18 @@ int qm_get_wpm(int *wpm);
struct qman_portal *qman_create_affine_portal(
const struct qm_portal_config *config,
- const struct qman_cgrs *cgrs,
- int alloc);
+ const struct qman_cgrs *cgrs);
const struct qm_portal_config *
qman_destroy_affine_portal(struct qman_portal *q);
+struct qman_portal *
+qman_init_portal(struct qman_portal *portal,
+ const struct qm_portal_config *c,
+ const struct qman_cgrs *cgrs);
+
+struct qman_portal *qman_alloc_global_portal(struct qm_portal_config *q_pcfg);
+int qman_free_global_portal(struct qman_portal *portal);
+
struct qm_portal_config *qm_get_unused_portal(void);
struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
@@ -321,7 +321,6 @@ rte_dpaa_portal_fq_init(void *arg, struct qman_fq *fq)
{
/* Affine above created portal with channel*/
u32 sdqcr;
- struct qman_portal *qp;
int ret;
if (unlikely(!RTE_PER_LCORE(dpaa_io))) {
@@ -333,21 +332,21 @@ rte_dpaa_portal_fq_init(void *arg, struct qman_fq *fq)
}
/* Initialise qman specific portals */
- qp = fsl_qman_portal_create();
- if (!qp) {
- DPAA_BUS_LOG(ERR, "Unable to alloc fq portal");
+ ret = fsl_qman_fq_portal_init(fq->qp);
+ if (ret) {
+ DPAA_BUS_LOG(ERR, "Unable to init fq portal");
return -1;
}
- fq->qp = qp;
+
sdqcr = QM_SDQCR_CHANNELS_POOL_CONV(fq->ch_id);
- qman_static_dequeue_add(sdqcr, qp);
+ qman_static_dequeue_add(sdqcr, fq->qp);
return 0;
}
int rte_dpaa_portal_fq_close(struct qman_fq *fq)
{
- return fsl_qman_portal_destroy(fq->qp);
+ return fsl_qman_fq_portal_destroy(fq->qp);
}
void
@@ -1217,7 +1217,8 @@ struct qman_fq {
u32 fqid_le;
u16 ch_id;
u8 cgr_groupid;
- u8 is_static;
+ u8 is_static:4;
+ u8 qp_initialized:4;
/* DPDK Interface */
void *dpaa_intf;
@@ -2,6 +2,7 @@
*
* Copyright 2010-2011 Freescale Semiconductor, Inc.
* All rights reserved.
+ * Copyright 2019 NXP
*
*/
@@ -74,8 +75,9 @@ int qman_global_init(void);
int bman_global_init(void);
/* Direct portal create and destroy */
-struct qman_portal *fsl_qman_portal_create(void);
-int fsl_qman_portal_destroy(struct qman_portal *qp);
+struct qman_portal *fsl_qman_fq_portal_create(void);
+int fsl_qman_fq_portal_destroy(struct qman_portal *qp);
+int fsl_qman_fq_portal_init(struct qman_portal *qp);
#ifdef __cplusplus
}
@@ -123,3 +123,10 @@ DPDK_19.05 {
local: *;
} DPDK_18.11;
+
+DPDK_19.11 {
+ global:
+ fsl_qman_fq_portal_create;
+
+ local: *;
+} DPDK_19.05;
@@ -629,6 +629,8 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
dev->data->dev_conf.rxmode.max_rx_pkt_len);
/* checking if push mode only, no error check for now */
if (dpaa_push_mode_max_queue > dpaa_push_queue_idx) {
+ struct qman_portal *qp;
+
dpaa_push_queue_idx++;
opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
opts.fqd.fq_ctrl = QM_FQCTRL_AVOIDBLOCK |
@@ -672,6 +674,14 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
}
rxq->is_static = true;
+
+ /* Allocate qman specific portals */
+ qp = fsl_qman_fq_portal_create();
+ if (!qp) {
+ DPAA_PMD_ERR("Unable to alloc fq portal");
+ return -1;
+ }
+ rxq->qp = qp;
}
rxq->bp_array = rte_dpaa_bpid_info;
dev->data->rx_queues[queue_idx] = rxq;
@@ -517,12 +517,13 @@ dpaa_eth_queue_portal_rx(struct qman_fq *fq,
{
int ret;
- if (unlikely(fq->qp == NULL)) {
+ if (unlikely(!fq->qp_initialized)) {
ret = rte_dpaa_portal_fq_init((void *)0, fq);
if (ret) {
DPAA_PMD_ERR("Failure in affining portal %d", ret);
return 0;
}
+ fq->qp_initialized = 1;
}
return qman_portal_poll_rx(nb_bufs, (void **)bufs, fq->qp);