Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

soc: fsl: dpio: Adding QMAN multiple enqueue interface

Update of QMAN the interface to enqueue frame. We now support multiple
enqueue (qbman_swp_enqueue_multiple) and multiple enqueue with
a table of descriptor (qbman_swp_enqueue_multiple_desc).

Signed-off-by: Youri Querry <youri.querry_1@nxp.com>
Acked-by: Roy Pledge <roy.pledge@nxp.com>
Signed-off-by: Li Yang <leoyang.li@nxp.com>

authored by

Youri Querry and committed by
Li Yang
9d988097 bb6d3fb3

+165 -17
+66 -3
drivers/soc/fsl/dpio/dpio-service.c
··· 1 1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 2 /* 3 3 * Copyright 2014-2016 Freescale Semiconductor Inc. 4 - * Copyright 2016 NXP 4 + * Copyright 2016-2019 NXP 5 5 * 6 6 */ 7 7 #include <linux/types.h> ··· 433 433 EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq); 434 434 435 435 /** 436 + * dpaa2_io_service_enqueue_multiple_fq() - Enqueue multiple frames 437 + * to a frame queue using one fqid. 438 + * @d: the given DPIO service. 439 + * @fqid: the given frame queue id. 440 + * @fd: the frame descriptor which is enqueued. 441 + * @nb: number of frames to be enqueud 442 + * 443 + * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready, 444 + * or -ENODEV if there is no dpio service. 445 + */ 446 + int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, 447 + u32 fqid, 448 + const struct dpaa2_fd *fd, 449 + int nb) 450 + { 451 + struct qbman_eq_desc ed; 452 + 453 + d = service_select(d); 454 + if (!d) 455 + return -ENODEV; 456 + 457 + qbman_eq_desc_clear(&ed); 458 + qbman_eq_desc_set_no_orp(&ed, 0); 459 + qbman_eq_desc_set_fq(&ed, fqid); 460 + 461 + return qbman_swp_enqueue_multiple(d->swp, &ed, fd, 0, nb); 462 + } 463 + EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_fq); 464 + 465 + /** 466 + * dpaa2_io_service_enqueue_multiple_desc_fq() - Enqueue multiple frames 467 + * to different frame queue using a list of fqids. 468 + * @d: the given DPIO service. 469 + * @fqid: the given list of frame queue ids. 470 + * @fd: the frame descriptor which is enqueued. 471 + * @nb: number of frames to be enqueud 472 + * 473 + * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready, 474 + * or -ENODEV if there is no dpio service. 475 + */ 476 + int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, 477 + u32 *fqid, 478 + const struct dpaa2_fd *fd, 479 + int nb) 480 + { 481 + int i; 482 + struct qbman_eq_desc ed[32]; 483 + 484 + d = service_select(d); 485 + if (!d) 486 + return -ENODEV; 487 + 488 + for (i = 0; i < nb; i++) { 489 + qbman_eq_desc_clear(&ed[i]); 490 + qbman_eq_desc_set_no_orp(&ed[i], 0); 491 + qbman_eq_desc_set_fq(&ed[i], fqid[i]); 492 + } 493 + 494 + return qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb); 495 + } 496 + EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_desc_fq); 497 + 498 + /** 436 499 * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD. 437 500 * @d: the given DPIO service. 438 501 * @qdid: the given queuing destination id. ··· 589 526 590 527 /** 591 528 * dpaa2_io_store_create() - Create the dma memory storage for dequeue result. 592 - * @max_frames: the maximum number of dequeued result for frames, must be <= 16. 529 + * @max_frames: the maximum number of dequeued result for frames, must be <= 32. 593 530 * @dev: the device to allow mapping/unmapping the DMAable region. 594 531 * 595 532 * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)". ··· 604 541 struct dpaa2_io_store *ret; 605 542 size_t size; 606 543 607 - if (!max_frames || (max_frames > 16)) 544 + if (!max_frames || (max_frames > 32)) 608 545 return NULL; 609 546 610 547 ret = kmalloc(sizeof(*ret), GFP_KERNEL);
+70 -13
drivers/soc/fsl/dpio/qbman-portal.c
··· 1 1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 2 /* 3 3 * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. 4 - * Copyright 2016 NXP 4 + * Copyright 2016-2019 NXP 5 5 * 6 6 */ 7 7 ··· 11 11 #include <soc/fsl/dpaa2-global.h> 12 12 13 13 #include "qbman-portal.h" 14 - 15 - #define QMAN_REV_4000 0x04000000 16 - #define QMAN_REV_4100 0x04010000 17 - #define QMAN_REV_4101 0x04010001 18 - #define QMAN_REV_5000 0x05000000 19 - 20 - #define QMAN_REV_MASK 0xffff0000 21 14 22 15 /* All QBMan command and result structures use this "valid bit" encoding */ 23 16 #define QB_VALID_BIT ((u32)0x80) ··· 149 156 */ 150 157 struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) 151 158 { 152 - struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL); 159 + struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL); 153 160 u32 reg; 154 161 155 162 if (!p) ··· 460 467 int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, 461 468 const struct dpaa2_fd *fd) 462 469 { 463 - struct qbman_eq_desc *p; 470 + struct qbman_eq_desc_with_fd *p; 464 471 u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR); 465 472 466 473 if (!EQAR_SUCCESS(eqar)) 467 474 return -EBUSY; 468 475 469 476 p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); 470 - memcpy(&p->dca, &d->dca, 31); 477 + /* This is mapped as DEVICE type memory, writes are 478 + * with address alignment: 479 + * desc.dca address alignment = 1 480 + * desc.seqnum address alignment = 2 481 + * desc.orpid address alignment = 4 482 + * desc.tgtid address alignment = 8 483 + */ 484 + p->desc.dca = d->dca; 485 + p->desc.seqnum = d->seqnum; 486 + p->desc.orpid = d->orpid; 487 + memcpy(&p->desc.tgtid, &d->tgtid, 24); 471 488 memcpy(&p->fd, fd, sizeof(*fd)); 472 489 473 490 if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { 474 491 /* Set the verb byte, have to substitute in the valid-bit */ 475 492 dma_wmb(); 476 - p->verb = d->verb | EQAR_VB(eqar); 493 + p->desc.verb = d->verb | EQAR_VB(eqar); 477 494 } else { 478 - p->verb = d->verb | EQAR_VB(eqar); 495 + p->desc.verb = d->verb | EQAR_VB(eqar); 479 496 dma_wmb(); 480 497 qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar)); 481 498 } 482 499 483 500 return 0; 501 + } 502 + 503 + /** 504 + * qbman_swp_enqueue_multiple() - Issue a multi enqueue command 505 + * using one enqueue descriptor 506 + * @s: the software portal used for enqueue 507 + * @d: the enqueue descriptor 508 + * @fd: table pointer of frame descriptor table to be enqueued 509 + * @flags: table pointer of flags, not used for the moment 510 + * @num_frames: number of fd to be enqueued 511 + * 512 + * Return the number of fd enqueued, or a negative error number. 513 + */ 514 + int qbman_swp_enqueue_multiple(struct qbman_swp *s, 515 + const struct qbman_eq_desc *d, 516 + const struct dpaa2_fd *fd, 517 + uint32_t *flags, 518 + int num_frames) 519 + { 520 + int count = 0; 521 + 522 + while (count < num_frames) { 523 + if (qbman_swp_enqueue(s, d, fd) != 0) 524 + break; 525 + count++; 526 + } 527 + 528 + return count; 529 + } 530 + 531 + /** 532 + * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command 533 + * using multiple enqueue descriptor 534 + * @s: the software portal used for enqueue 535 + * @d: table of minimal enqueue descriptor 536 + * @fd: table pointer of frame descriptor table to be enqueued 537 + * @num_frames: number of fd to be enqueued 538 + * 539 + * Return the number of fd enqueued, or a negative error number. 540 + */ 541 + int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s, 542 + const struct qbman_eq_desc *d, 543 + const struct dpaa2_fd *fd, 544 + int num_frames) 545 + { 546 + int count = 0; 547 + 548 + while (count < num_frames) { 549 + if (qbman_swp_enqueue(s, &(d[count]), fd) != 0) 550 + break; 551 + count++; 552 + } 553 + 554 + return count; 484 555 } 485 556 486 557 /* Static (push) dequeue */
+24
drivers/soc/fsl/dpio/qbman-portal.h
··· 9 9 10 10 #include <soc/fsl/dpaa2-fd.h> 11 11 12 + #define QMAN_REV_4000 0x04000000 13 + #define QMAN_REV_4100 0x04010000 14 + #define QMAN_REV_4101 0x04010001 15 + #define QMAN_REV_5000 0x05000000 16 + 17 + #define QMAN_REV_MASK 0xffff0000 18 + 12 19 struct dpaa2_dq; 13 20 struct qbman_swp; 14 21 ··· 88 81 u8 wae; 89 82 u8 rspid; 90 83 __le64 rsp_addr; 84 + }; 85 + 86 + struct qbman_eq_desc_with_fd { 87 + struct qbman_eq_desc desc; 91 88 u8 fd[32]; 92 89 }; 93 90 ··· 203 192 void *qbman_swp_mc_start(struct qbman_swp *p); 204 193 void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb); 205 194 void *qbman_swp_mc_result(struct qbman_swp *p); 195 + 196 + int 197 + qbman_swp_enqueue_multiple(struct qbman_swp *s, 198 + const struct qbman_eq_desc *d, 199 + const struct dpaa2_fd *fd, 200 + uint32_t *flags, 201 + int num_frames); 202 + 203 + int 204 + qbman_swp_enqueue_multiple_desc(struct qbman_swp *s, 205 + const struct qbman_eq_desc *d, 206 + const struct dpaa2_fd *fd, 207 + int num_frames); 206 208 207 209 /** 208 210 * qbman_result_is_DQ() - check if the dequeue result is a dequeue response
+5 -1
include/soc/fsl/dpaa2-io.h
··· 1 1 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 2 /* 3 3 * Copyright 2014-2016 Freescale Semiconductor Inc. 4 - * Copyright NXP 4 + * Copyright 2017-2019 NXP 5 5 * 6 6 */ 7 7 #ifndef __FSL_DPAA2_IO_H ··· 109 109 110 110 int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, u32 fqid, 111 111 const struct dpaa2_fd *fd); 112 + int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, u32 fqid, 113 + const struct dpaa2_fd *fd, int number_of_frame); 114 + int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, u32 *fqid, 115 + const struct dpaa2_fd *fd, int number_of_frame); 112 116 int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio, 113 117 u16 qdbin, const struct dpaa2_fd *fd); 114 118 int dpaa2_io_service_release(struct dpaa2_io *d, u16 bpid,