// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. * Copyright 2016-2019 NXP * */ #include <asm/cacheflush.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <soc/fsl/dpaa2-global.h> #include "qbman-portal.h" /* All QBMan command and result structures use this "valid bit" encoding */ #define QB_VALID_BIT … /* QBMan portal management command codes */ #define QBMAN_MC_ACQUIRE … #define QBMAN_WQCHAN_CONFIGURE … /* CINH register offsets */ #define QBMAN_CINH_SWP_EQCR_PI … #define QBMAN_CINH_SWP_EQCR_CI … #define QBMAN_CINH_SWP_EQAR … #define QBMAN_CINH_SWP_CR_RT … #define QBMAN_CINH_SWP_VDQCR_RT … #define QBMAN_CINH_SWP_EQCR_AM_RT … #define QBMAN_CINH_SWP_RCR_AM_RT … #define QBMAN_CINH_SWP_DQPI … #define QBMAN_CINH_SWP_DQRR_ITR … #define QBMAN_CINH_SWP_DCAP … #define QBMAN_CINH_SWP_SDQCR … #define QBMAN_CINH_SWP_EQCR_AM_RT2 … #define QBMAN_CINH_SWP_RCR_PI … #define QBMAN_CINH_SWP_RAR … #define QBMAN_CINH_SWP_ISR … #define QBMAN_CINH_SWP_IER … #define QBMAN_CINH_SWP_ISDR … #define QBMAN_CINH_SWP_IIR … #define QBMAN_CINH_SWP_ITPR … /* CENA register offsets */ #define QBMAN_CENA_SWP_EQCR(n) … #define QBMAN_CENA_SWP_DQRR(n) … #define QBMAN_CENA_SWP_RCR(n) … #define QBMAN_CENA_SWP_CR … #define QBMAN_CENA_SWP_RR(vb) … #define QBMAN_CENA_SWP_VDQCR … #define QBMAN_CENA_SWP_EQCR_CI … #define QBMAN_CENA_SWP_EQCR_CI_MEMBACK … /* CENA register offsets in memory-backed mode */ #define QBMAN_CENA_SWP_DQRR_MEM(n) … #define QBMAN_CENA_SWP_RCR_MEM(n) … #define QBMAN_CENA_SWP_CR_MEM … #define QBMAN_CENA_SWP_RR_MEM … #define QBMAN_CENA_SWP_VDQCR_MEM … /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */ #define QBMAN_IDX_FROM_DQRR(p) … /* Define token used to determine if response written to memory is valid */ #define QMAN_DQ_TOKEN_VALID … /* SDQCR attribute codes */ #define QB_SDQCR_FC_SHIFT … #define QB_SDQCR_FC_MASK … #define QB_SDQCR_DCT_SHIFT … #define QB_SDQCR_DCT_MASK … #define QB_SDQCR_TOK_SHIFT … #define QB_SDQCR_TOK_MASK … #define QB_SDQCR_SRC_SHIFT … #define QB_SDQCR_SRC_MASK … /* opaque token for static dequeues */ #define QMAN_SDQCR_TOKEN … #define QBMAN_EQCR_DCA_IDXMASK … #define QBMAN_ENQUEUE_FLAG_DCA … #define EQ_DESC_SIZE_WITHOUT_FD … #define EQ_DESC_SIZE_FD_START … enum qbman_sdqcr_dct { … }; enum qbman_sdqcr_fc { … }; /* Internal Function declaration */ static int qbman_swp_enqueue_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd); static int qbman_swp_enqueue_mem_back(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd); static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, uint32_t *flags, int num_frames); static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, uint32_t *flags, int num_frames); static int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, int num_frames); static int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, int num_frames); static int qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d); static int qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d); const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s); const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s); static int qbman_swp_release_direct(struct qbman_swp *s, const struct qbman_release_desc *d, const u64 *buffers, unsigned int num_buffers); static int qbman_swp_release_mem_back(struct qbman_swp *s, const struct qbman_release_desc *d, const u64 *buffers, unsigned int num_buffers); /* Function pointers */ int (*qbman_swp_enqueue_ptr)(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd) = …; int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, uint32_t *flags, int num_frames) = …; int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, int num_frames) = …; int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d) = …; const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s) = …; int (*qbman_swp_release_ptr)(struct qbman_swp *s, const struct qbman_release_desc *d, const u64 *buffers, unsigned int num_buffers) = …; /* Portal Access */ static inline u32 qbman_read_register(struct qbman_swp *p, u32 offset) { … } static inline void qbman_write_register(struct qbman_swp *p, u32 offset, u32 value) { … } static inline void *qbman_get_cmd(struct qbman_swp *p, u32 offset) { … } #define QBMAN_CINH_SWP_CFG … #define SWP_CFG_DQRR_MF_SHIFT … #define SWP_CFG_EST_SHIFT … #define SWP_CFG_CPBS_SHIFT … #define SWP_CFG_WN_SHIFT … #define SWP_CFG_RPM_SHIFT … #define SWP_CFG_DCM_SHIFT … #define SWP_CFG_EPM_SHIFT … #define SWP_CFG_VPM_SHIFT … #define SWP_CFG_CPM_SHIFT … #define SWP_CFG_SD_SHIFT … #define SWP_CFG_SP_SHIFT … #define SWP_CFG_SE_SHIFT … #define SWP_CFG_DP_SHIFT … #define SWP_CFG_DE_SHIFT … #define SWP_CFG_EP_SHIFT … static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm, u8 epm, int sd, int sp, int se, int dp, int de, int ep) { … } #define QMAN_RT_MODE … static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last) { … } /** * qbman_swp_init() - Create a functional object representing the given * QBMan portal descriptor. * @d: the given qbman swp descriptor * * Return qbman_swp portal for success, NULL if the object cannot * be created. */ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) { … } /** * qbman_swp_finish() - Create and destroy a functional object representing * the given QBMan portal descriptor. * @p: the qbman_swp object to be destroyed */ void qbman_swp_finish(struct qbman_swp *p) { … } /** * qbman_swp_interrupt_read_status() * @p: the given software portal * * Return the value in the SWP_ISR register. */ u32 qbman_swp_interrupt_read_status(struct qbman_swp *p) { … } /** * qbman_swp_interrupt_clear_status() * @p: the given software portal * @mask: The mask to clear in SWP_ISR register */ void qbman_swp_interrupt_clear_status(struct qbman_swp *p, u32 mask) { … } /** * qbman_swp_interrupt_get_trigger() - read interrupt enable register * @p: the given software portal * * Return the value in the SWP_IER register. */ u32 qbman_swp_interrupt_get_trigger(struct qbman_swp *p) { … } /** * qbman_swp_interrupt_set_trigger() - enable interrupts for a swp * @p: the given software portal * @mask: The mask of bits to enable in SWP_IER */ void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, u32 mask) { … } /** * qbman_swp_interrupt_get_inhibit() - read interrupt mask register * @p: the given software portal object * * Return the value in the SWP_IIR register. */ int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p) { … } /** * qbman_swp_interrupt_set_inhibit() - write interrupt mask register * @p: the given software portal object * @inhibit: whether to inhibit the IRQs */ void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit) { … } /* * Different management commands all use this common base layer of code to issue * commands and poll for results. */ /* * Returns a pointer to where the caller should fill in their management command * (caller should ignore the verb byte) */ void *qbman_swp_mc_start(struct qbman_swp *p) { … } /* * Commits merges in the caller-supplied command verb (which should not include * the valid-bit) and submits the command to hardware */ void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb) { … } /* * Checks for a completed response (returns non-NULL if only if the response * is complete). */ void *qbman_swp_mc_result(struct qbman_swp *p) { … } #define QB_ENQUEUE_CMD_OPTIONS_SHIFT … enum qb_enqueue_commands { … }; #define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT … #define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT … #define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT … #define QB_ENQUEUE_CMD_DCA_EN_SHIFT … /* * qbman_eq_desc_clear() - Clear the contents of a descriptor to * default/starting state. */ void qbman_eq_desc_clear(struct qbman_eq_desc *d) { … } /** * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp * @d: the enqueue descriptor. * @respond_success: 1 = enqueue with response always; 0 = enqueue with * rejections returned on a FQ. */ void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success) { … } /* * Exactly one of the following descriptor "targets" should be set. (Calling any * one of these will replace the effect of any prior call to one of these.) * -enqueue to a frame queue * -enqueue to a queuing destination */ /** * qbman_eq_desc_set_fq() - set the FQ for the enqueue command * @d: the enqueue descriptor * @fqid: the id of the frame queue to be enqueued */ void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid) { … } /** * qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command * @d: the enqueue descriptor * @qdid: the id of the queuing destination to be enqueued * @qd_bin: the queuing destination bin * @qd_prio: the queuing destination priority */ void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid, u32 qd_bin, u32 qd_prio) { … } #define EQAR_IDX(eqar) … #define EQAR_VB(eqar) … #define EQAR_SUCCESS(eqar) … #define QB_RT_BIT … /** * qbman_swp_enqueue_direct() - Issue an enqueue command * @s: the software portal used for enqueue * @d: the enqueue descriptor * @fd: the frame descriptor to be enqueued * * Please note that 'fd' should only be NULL if the "action" of the * descriptor is "orp_hole" or "orp_nesn". * * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. */ static int qbman_swp_enqueue_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd) { … } /** * qbman_swp_enqueue_mem_back() - Issue an enqueue command * @s: the software portal used for enqueue * @d: the enqueue descriptor * @fd: the frame descriptor to be enqueued * * Please note that 'fd' should only be NULL if the "action" of the * descriptor is "orp_hole" or "orp_nesn". * * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. */ static int qbman_swp_enqueue_mem_back(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd) { … } /** * qbman_swp_enqueue_multiple_direct() - Issue a multi enqueue command * using one enqueue descriptor * @s: the software portal used for enqueue * @d: the enqueue descriptor * @fd: table pointer of frame descriptor table to be enqueued * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL * @num_frames: number of fd to be enqueued * * Return the number of fd enqueued, or a negative error number. */ static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, uint32_t *flags, int num_frames) { … } /** * qbman_swp_enqueue_multiple_mem_back() - Issue a multi enqueue command * using one enqueue descriptor * @s: the software portal used for enqueue * @d: the enqueue descriptor * @fd: table pointer of frame descriptor table to be enqueued * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL * @num_frames: number of fd to be enqueued * * Return the number of fd enqueued, or a negative error number. */ static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, uint32_t *flags, int num_frames) { … } /** * qbman_swp_enqueue_multiple_desc_direct() - Issue a multi enqueue command * using multiple enqueue descriptor * @s: the software portal used for enqueue * @d: table of minimal enqueue descriptor * @fd: table pointer of frame descriptor table to be enqueued * @num_frames: number of fd to be enqueued * * Return the number of fd enqueued, or a negative error number. */ static int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, int num_frames) { … } /** * qbman_swp_enqueue_multiple_desc_mem_back() - Issue a multi enqueue command * using multiple enqueue descriptor * @s: the software portal used for enqueue * @d: table of minimal enqueue descriptor * @fd: table pointer of frame descriptor table to be enqueued * @num_frames: number of fd to be enqueued * * Return the number of fd enqueued, or a negative error number. */ static int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct dpaa2_fd *fd, int num_frames) { … } /* Static (push) dequeue */ /** * qbman_swp_push_get() - Get the push dequeue setup * @s: the software portal object * @channel_idx: the channel index to query * @enabled: returned boolean to show whether the push dequeue is enabled * for the given channel */ void qbman_swp_push_get(struct qbman_swp *s, u8 channel_idx, int *enabled) { … } /** * qbman_swp_push_set() - Enable or disable push dequeue * @s: the software portal object * @channel_idx: the channel index (0 to 15) * @enable: enable or disable push dequeue */ void qbman_swp_push_set(struct qbman_swp *s, u8 channel_idx, int enable) { … } #define QB_VDQCR_VERB_DCT_SHIFT … #define QB_VDQCR_VERB_DT_SHIFT … #define QB_VDQCR_VERB_RLS_SHIFT … #define QB_VDQCR_VERB_WAE_SHIFT … enum qb_pull_dt_e { … }; /** * qbman_pull_desc_clear() - Clear the contents of a descriptor to * default/starting state * @d: the pull dequeue descriptor to be cleared */ void qbman_pull_desc_clear(struct qbman_pull_desc *d) { … } /** * qbman_pull_desc_set_storage()- Set the pull dequeue storage * @d: the pull dequeue descriptor to be set * @storage: the pointer of the memory to store the dequeue result * @storage_phys: the physical address of the storage memory * @stash: to indicate whether write allocate is enabled * * If not called, or if called with 'storage' as NULL, the result pull dequeues * will produce results to DQRR. If 'storage' is non-NULL, then results are * produced to the given memory location (using the DMA address which * the caller provides in 'storage_phys'), and 'stash' controls whether or not * those writes to main-memory express a cache-warming attribute. */ void qbman_pull_desc_set_storage(struct qbman_pull_desc *d, struct dpaa2_dq *storage, dma_addr_t storage_phys, int stash) { … } /** * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued * @d: the pull dequeue descriptor to be set * @numframes: number of frames to be set, must be between 1 and 16, inclusive */ void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, u8 numframes) { … } /* * Exactly one of the following descriptor "actions" should be set. (Calling any * one of these will replace the effect of any prior call to one of these.) * - pull dequeue from the given frame queue (FQ) * - pull dequeue from any FQ in the given work queue (WQ) * - pull dequeue from any FQ in any WQ in the given channel */ /** * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues * @d: the pull dequeue descriptor to be set * @fqid: the frame queue index of the given FQ */ void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, u32 fqid) { … } /** * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues * @d: the pull dequeue descriptor to be set * @wqid: composed of channel id and wqid within the channel * @dct: the dequeue command type */ void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid, enum qbman_pull_type_e dct) { … } /** * qbman_pull_desc_set_channel() - Set channelid from which the dequeue command * dequeues * @d: the pull dequeue descriptor to be set * @chid: the channel id to be dequeued * @dct: the dequeue command type */ void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid, enum qbman_pull_type_e dct) { … } /** * qbman_swp_pull_direct() - Issue the pull dequeue command * @s: the software portal object * @d: the software portal descriptor which has been configured with * the set of qbman_pull_desc_set_*() calls * * Return 0 for success, and -EBUSY if the software portal is not ready * to do pull dequeue. */ static int qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d) { … } /** * qbman_swp_pull_mem_back() - Issue the pull dequeue command * @s: the software portal object * @d: the software portal descriptor which has been configured with * the set of qbman_pull_desc_set_*() calls * * Return 0 for success, and -EBUSY if the software portal is not ready * to do pull dequeue. */ static int qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d) { … } #define QMAN_DQRR_PI_MASK … /** * qbman_swp_dqrr_next_direct() - Get an valid DQRR entry * @s: the software portal object * * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry * only once, so repeated calls can return a sequence of DQRR entries, without * requiring they be consumed immediately or in any particular order. */ const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s) { … } /** * qbman_swp_dqrr_next_mem_back() - Get an valid DQRR entry * @s: the software portal object * * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry * only once, so repeated calls can return a sequence of DQRR entries, without * requiring they be consumed immediately or in any particular order. */ const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s) { … } /** * qbman_swp_dqrr_consume() - Consume DQRR entries previously returned from * qbman_swp_dqrr_next(). * @s: the software portal object * @dq: the DQRR entry to be consumed */ void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq) { … } /** * qbman_result_has_new_result() - Check and get the dequeue response from the * dq storage memory set in pull dequeue command * @s: the software portal object * @dq: the dequeue result read from the memory * * Return 1 for getting a valid dequeue result, or 0 for not getting a valid * dequeue result. * * Only used for user-provided storage of dequeue results, not DQRR. For * efficiency purposes, the driver will perform any required endianness * conversion to ensure that the user's dequeue result storage is in host-endian * format. As such, once the user has called qbman_result_has_new_result() and * been returned a valid dequeue result, they should not call it again on * the same memory location (except of course if another dequeue command has * been executed to produce a new result to that location). */ int qbman_result_has_new_result(struct qbman_swp *s, const struct dpaa2_dq *dq) { … } /** * qbman_release_desc_clear() - Clear the contents of a descriptor to * default/starting state. * @d: the pull dequeue descriptor to be cleared */ void qbman_release_desc_clear(struct qbman_release_desc *d) { … } /** * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to * @d: the pull dequeue descriptor to be set * @bpid: the bpid value to be set */ void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid) { … } /** * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI * interrupt source should be asserted after the release command is completed. * @d: the pull dequeue descriptor to be set * @enable: enable (1) or disable (0) value */ void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable) { … } #define RAR_IDX(rar) … #define RAR_VB(rar) … #define RAR_SUCCESS(rar) … /** * qbman_swp_release_direct() - Issue a buffer release command * @s: the software portal object * @d: the release descriptor * @buffers: a pointer pointing to the buffer address to be released * @num_buffers: number of buffers to be released, must be less than 8 * * Return 0 for success, -EBUSY if the release command ring is not ready. */ int qbman_swp_release_direct(struct qbman_swp *s, const struct qbman_release_desc *d, const u64 *buffers, unsigned int num_buffers) { … } /** * qbman_swp_release_mem_back() - Issue a buffer release command * @s: the software portal object * @d: the release descriptor * @buffers: a pointer pointing to the buffer address to be released * @num_buffers: number of buffers to be released, must be less than 8 * * Return 0 for success, -EBUSY if the release command ring is not ready. */ int qbman_swp_release_mem_back(struct qbman_swp *s, const struct qbman_release_desc *d, const u64 *buffers, unsigned int num_buffers) { … } struct qbman_acquire_desc { … }; struct qbman_acquire_rslt { … }; /** * qbman_swp_acquire() - Issue a buffer acquire command * @s: the software portal object * @bpid: the buffer pool index * @buffers: a pointer pointing to the acquired buffer addresses * @num_buffers: number of buffers to be acquired, must be less than 8 * * Return 0 for success, or negative error code if the acquire command * fails. */ int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers, unsigned int num_buffers) { … } struct qbman_alt_fq_state_desc { … }; struct qbman_alt_fq_state_rslt { … }; #define ALT_FQ_FQID_MASK … int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid, u8 alt_fq_verb) { … } struct qbman_cdan_ctrl_desc { … }; struct qbman_cdan_ctrl_rslt { … }; int qbman_swp_CDAN_set(struct qbman_swp *s, u16 channelid, u8 we_mask, u8 cdan_en, u64 ctx) { … } #define QBMAN_RESPONSE_VERB_MASK … #define QBMAN_FQ_QUERY_NP … #define QBMAN_BP_QUERY … struct qbman_fq_query_desc { … }; int qbman_fq_query_state(struct qbman_swp *s, u32 fqid, struct qbman_fq_query_np_rslt *r) { … } u32 qbman_fq_state_frame_count(const struct qbman_fq_query_np_rslt *r) { … } u32 qbman_fq_state_byte_count(const struct qbman_fq_query_np_rslt *r) { … } struct qbman_bp_query_desc { … }; int qbman_bp_query(struct qbman_swp *s, u16 bpid, struct qbman_bp_query_rslt *r) { … } u32 qbman_bp_info_num_free_bufs(struct qbman_bp_query_rslt *a) { … } /** * qbman_swp_set_irq_coalescing() - Set new IRQ coalescing values * @p: the software portal object * @irq_threshold: interrupt threshold * @irq_holdoff: interrupt holdoff (timeout) period in us * * Return 0 for success, or negative error code on error. */ int qbman_swp_set_irq_coalescing(struct qbman_swp *p, u32 irq_threshold, u32 irq_holdoff) { … } /** * qbman_swp_get_irq_coalescing() - Get the current IRQ coalescing parameters * @p: the software portal object * @irq_threshold: interrupt threshold (an IRQ is generated when there are more * DQRR entries in the portal than the threshold) * @irq_holdoff: interrupt holdoff (timeout) period in us */ void qbman_swp_get_irq_coalescing(struct qbman_swp *p, u32 *irq_threshold, u32 *irq_holdoff) { … }