bus/dpaa: decouple FQ portal alloc and init

The decoupling of FQ portal allocation is required as a
pre-requisite to support Rx interrupts as we need to have
event FD's at portal allocation i.e. before the
initialization of the Frame Queues.
This change will help us get the event fd once the portals
have been allocated for static FQ's.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
This commit is contained in:
Nipun Gupta 2019-08-29 15:57:11 +05:30 committed by Ferruh Yigit
parent 84e3d0853e
commit b9c9416790
9 changed files with 93 additions and 50 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -90,20 +90,20 @@ DPDK_18.02 {
rte_dpaa_portal_fq_close;
rte_dpaa_portal_fq_init;
local: *;
} DPDK_17.11;
DPDK_18.08 {
global:
fman_if_get_sg_enable;
fman_if_set_sg;
of_get_mac_address;
local: *;
} DPDK_18.02;
DPDK_18.11 {
global:
bman_thread_irq;
fman_if_get_sg_enable;
fman_if_set_sg;
@ -114,12 +114,18 @@ DPDK_18.11 {
qman_thread_fd;
qman_thread_irq;
local: *;
} DPDK_18.08;
DPDK_19.05 {
global:
qman_set_fq_lookup_table;
local: *;
} DPDK_18.11;
DPDK_19.11 {
global:
fsl_qman_fq_portal_create;
} DPDK_19.05;

View File

@ -643,6 +643,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 |
@ -686,6 +688,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;

View File

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