1131a75b6SHemant Agrawal /* SPDX-License-Identifier: BSD-3-Clause 2531b17a7SHemant Agrawal * 3531b17a7SHemant Agrawal * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. 4a116979aSJun Yang * Copyright 2018-2020,2023-2024 NXP 5531b17a7SHemant Agrawal * 6531b17a7SHemant Agrawal */ 7531b17a7SHemant Agrawal 8293c0ca9SNipun Gupta #include "qbman_sys.h" 9531b17a7SHemant Agrawal #include "qbman_portal.h" 10531b17a7SHemant Agrawal 11531b17a7SHemant Agrawal /* QBMan portal management command codes */ 12531b17a7SHemant Agrawal #define QBMAN_MC_ACQUIRE 0x30 13531b17a7SHemant Agrawal #define QBMAN_WQCHAN_CONFIGURE 0x46 14531b17a7SHemant Agrawal 15531b17a7SHemant Agrawal /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */ 16531b17a7SHemant Agrawal #define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6) 17531b17a7SHemant Agrawal 18531b17a7SHemant Agrawal /* QBMan FQ management command codes */ 19531b17a7SHemant Agrawal #define QBMAN_FQ_SCHEDULE 0x48 20531b17a7SHemant Agrawal #define QBMAN_FQ_FORCE 0x49 21531b17a7SHemant Agrawal #define QBMAN_FQ_XON 0x4d 22531b17a7SHemant Agrawal #define QBMAN_FQ_XOFF 0x4e 23531b17a7SHemant Agrawal 24531b17a7SHemant Agrawal /*******************************/ 25531b17a7SHemant Agrawal /* Pre-defined attribute codes */ 26531b17a7SHemant Agrawal /*******************************/ 27531b17a7SHemant Agrawal 2869293c77SHemant Agrawal #define QBMAN_RESPONSE_VERB_MASK 0x7f 29531b17a7SHemant Agrawal 30531b17a7SHemant Agrawal /*************************/ 31531b17a7SHemant Agrawal /* SDQCR attribute codes */ 32531b17a7SHemant Agrawal /*************************/ 3369293c77SHemant Agrawal #define QB_SDQCR_FC_SHIFT 29 3469293c77SHemant Agrawal #define QB_SDQCR_FC_MASK 0x1 3569293c77SHemant Agrawal #define QB_SDQCR_DCT_SHIFT 24 3669293c77SHemant Agrawal #define QB_SDQCR_DCT_MASK 0x3 3769293c77SHemant Agrawal #define QB_SDQCR_TOK_SHIFT 16 3869293c77SHemant Agrawal #define QB_SDQCR_TOK_MASK 0xff 3969293c77SHemant Agrawal #define QB_SDQCR_SRC_SHIFT 0 4069293c77SHemant Agrawal #define QB_SDQCR_SRC_MASK 0xffff 41531b17a7SHemant Agrawal 4269293c77SHemant Agrawal /* opaque token for static dequeues */ 4369293c77SHemant Agrawal #define QMAN_SDQCR_TOKEN 0xbb 4469293c77SHemant Agrawal 45a116979aSJun Yang #define BMAN_VALID_RSLT_NUM_MASK 0x7 46a116979aSJun Yang 47531b17a7SHemant Agrawal enum qbman_sdqcr_dct { 48531b17a7SHemant Agrawal qbman_sdqcr_dct_null = 0, 49531b17a7SHemant Agrawal qbman_sdqcr_dct_prio_ics, 50531b17a7SHemant Agrawal qbman_sdqcr_dct_active_ics, 51531b17a7SHemant Agrawal qbman_sdqcr_dct_active 52531b17a7SHemant Agrawal }; 53531b17a7SHemant Agrawal 54531b17a7SHemant Agrawal enum qbman_sdqcr_fc { 55531b17a7SHemant Agrawal qbman_sdqcr_fc_one = 0, 56531b17a7SHemant Agrawal qbman_sdqcr_fc_up_to_3 = 1 57531b17a7SHemant Agrawal }; 58531b17a7SHemant Agrawal 59531b17a7SHemant Agrawal /* We need to keep track of which SWP triggered a pull command 60531b17a7SHemant Agrawal * so keep an array of portal IDs and use the token field to 61531b17a7SHemant Agrawal * be able to find the proper portal 62531b17a7SHemant Agrawal */ 6369293c77SHemant Agrawal #define MAX_QBMAN_PORTALS 64 64531b17a7SHemant Agrawal static struct qbman_swp *portal_idx_map[MAX_QBMAN_PORTALS]; 65531b17a7SHemant Agrawal 66dc111b5eSFerruh Yigit uint32_t qman_version; 67dc111b5eSFerruh Yigit 68293c0ca9SNipun Gupta /* Internal Function declaration */ 69293c0ca9SNipun Gupta static int 70293c0ca9SNipun Gupta qbman_swp_enqueue_array_mode_direct(struct qbman_swp *s, 71293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 72293c0ca9SNipun Gupta const struct qbman_fd *fd); 73293c0ca9SNipun Gupta static int 74293c0ca9SNipun Gupta qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp *s, 75293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 76293c0ca9SNipun Gupta const struct qbman_fd *fd); 77293c0ca9SNipun Gupta 78293c0ca9SNipun Gupta static int 79293c0ca9SNipun Gupta qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s, 80293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 81293c0ca9SNipun Gupta const struct qbman_fd *fd); 82293c0ca9SNipun Gupta static int 8379e5b5edSNipun Gupta qbman_swp_enqueue_ring_mode_cinh_read_direct(struct qbman_swp *s, 8463d5d0afSNipun Gupta const struct qbman_eq_desc *d, 8563d5d0afSNipun Gupta const struct qbman_fd *fd); 8663d5d0afSNipun Gupta static int 87b3bd7a50SNipun Gupta qbman_swp_enqueue_ring_mode_cinh_direct(struct qbman_swp *s, 88b3bd7a50SNipun Gupta const struct qbman_eq_desc *d, 89b3bd7a50SNipun Gupta const struct qbman_fd *fd); 90b3bd7a50SNipun Gupta static int 91293c0ca9SNipun Gupta qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s, 92293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 93293c0ca9SNipun Gupta const struct qbman_fd *fd); 94293c0ca9SNipun Gupta 95293c0ca9SNipun Gupta static int 96293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, 97293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 98293c0ca9SNipun Gupta const struct qbman_fd *fd, 99293c0ca9SNipun Gupta uint32_t *flags, 100293c0ca9SNipun Gupta int num_frames); 101293c0ca9SNipun Gupta static int 10279e5b5edSNipun Gupta qbman_swp_enqueue_multiple_cinh_read_direct(struct qbman_swp *s, 10363d5d0afSNipun Gupta const struct qbman_eq_desc *d, 10463d5d0afSNipun Gupta const struct qbman_fd *fd, 10563d5d0afSNipun Gupta uint32_t *flags, 10663d5d0afSNipun Gupta int num_frames); 10763d5d0afSNipun Gupta static int 108b3bd7a50SNipun Gupta qbman_swp_enqueue_multiple_cinh_direct(struct qbman_swp *s, 109b3bd7a50SNipun Gupta const struct qbman_eq_desc *d, 110b3bd7a50SNipun Gupta const struct qbman_fd *fd, 111b3bd7a50SNipun Gupta uint32_t *flags, 112b3bd7a50SNipun Gupta int num_frames); 113b3bd7a50SNipun Gupta static int 114293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, 115293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 116293c0ca9SNipun Gupta const struct qbman_fd *fd, 117293c0ca9SNipun Gupta uint32_t *flags, 118293c0ca9SNipun Gupta int num_frames); 119293c0ca9SNipun Gupta 120293c0ca9SNipun Gupta static int 121a3a997f0SHemant Agrawal qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp *s, 122a3a997f0SHemant Agrawal const struct qbman_eq_desc *d, 123a3a997f0SHemant Agrawal struct qbman_fd **fd, 124a3a997f0SHemant Agrawal uint32_t *flags, 125a3a997f0SHemant Agrawal int num_frames); 12663d5d0afSNipun Gupta static int 12779e5b5edSNipun Gupta qbman_swp_enqueue_multiple_fd_cinh_read_direct(struct qbman_swp *s, 12863d5d0afSNipun Gupta const struct qbman_eq_desc *d, 12963d5d0afSNipun Gupta struct qbman_fd **fd, 13063d5d0afSNipun Gupta uint32_t *flags, 13163d5d0afSNipun Gupta int num_frames); 132a3a997f0SHemant Agrawal static int 133b3bd7a50SNipun Gupta qbman_swp_enqueue_multiple_fd_cinh_direct(struct qbman_swp *s, 134b3bd7a50SNipun Gupta const struct qbman_eq_desc *d, 135b3bd7a50SNipun Gupta struct qbman_fd **fd, 136b3bd7a50SNipun Gupta uint32_t *flags, 137b3bd7a50SNipun Gupta int num_frames); 138b3bd7a50SNipun Gupta static int 139a3a997f0SHemant Agrawal qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp *s, 140a3a997f0SHemant Agrawal const struct qbman_eq_desc *d, 141a3a997f0SHemant Agrawal struct qbman_fd **fd, 142a3a997f0SHemant Agrawal uint32_t *flags, 143a3a997f0SHemant Agrawal int num_frames); 144a3a997f0SHemant Agrawal 145a3a997f0SHemant Agrawal static int 146293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, 147293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 148293c0ca9SNipun Gupta const struct qbman_fd *fd, 149293c0ca9SNipun Gupta int num_frames); 150293c0ca9SNipun Gupta static int 15179e5b5edSNipun Gupta qbman_swp_enqueue_multiple_desc_cinh_read_direct(struct qbman_swp *s, 15263d5d0afSNipun Gupta const struct qbman_eq_desc *d, 15363d5d0afSNipun Gupta const struct qbman_fd *fd, 15463d5d0afSNipun Gupta int num_frames); 15563d5d0afSNipun Gupta static int 156b3bd7a50SNipun Gupta qbman_swp_enqueue_multiple_desc_cinh_direct(struct qbman_swp *s, 157b3bd7a50SNipun Gupta const struct qbman_eq_desc *d, 158b3bd7a50SNipun Gupta const struct qbman_fd *fd, 159b3bd7a50SNipun Gupta int num_frames); 160b3bd7a50SNipun Gupta static int 161293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, 162293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 163293c0ca9SNipun Gupta const struct qbman_fd *fd, 164293c0ca9SNipun Gupta int num_frames); 165293c0ca9SNipun Gupta 166293c0ca9SNipun Gupta static int 167293c0ca9SNipun Gupta qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d); 168293c0ca9SNipun Gupta static int 169b3bd7a50SNipun Gupta qbman_swp_pull_cinh_direct(struct qbman_swp *s, struct qbman_pull_desc *d); 170b3bd7a50SNipun Gupta static int 171293c0ca9SNipun Gupta qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d); 172293c0ca9SNipun Gupta 173293c0ca9SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_direct(struct qbman_swp *s); 174b3bd7a50SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_cinh_direct(struct qbman_swp *s); 175293c0ca9SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s); 176293c0ca9SNipun Gupta 177293c0ca9SNipun Gupta static int 178293c0ca9SNipun Gupta qbman_swp_release_direct(struct qbman_swp *s, 179293c0ca9SNipun Gupta const struct qbman_release_desc *d, 180293c0ca9SNipun Gupta const uint64_t *buffers, unsigned int num_buffers); 181293c0ca9SNipun Gupta static int 182b3bd7a50SNipun Gupta qbman_swp_release_cinh_direct(struct qbman_swp *s, 183b3bd7a50SNipun Gupta const struct qbman_release_desc *d, 184b3bd7a50SNipun Gupta const uint64_t *buffers, unsigned int num_buffers); 185b3bd7a50SNipun Gupta static int 186293c0ca9SNipun Gupta qbman_swp_release_mem_back(struct qbman_swp *s, 187293c0ca9SNipun Gupta const struct qbman_release_desc *d, 188293c0ca9SNipun Gupta const uint64_t *buffers, unsigned int num_buffers); 189293c0ca9SNipun Gupta 190293c0ca9SNipun Gupta /* Function pointers */ 191293c0ca9SNipun Gupta static int (*qbman_swp_enqueue_array_mode_ptr)(struct qbman_swp *s, 192293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 193293c0ca9SNipun Gupta const struct qbman_fd *fd) 194293c0ca9SNipun Gupta = qbman_swp_enqueue_array_mode_direct; 195293c0ca9SNipun Gupta 196293c0ca9SNipun Gupta static int (*qbman_swp_enqueue_ring_mode_ptr)(struct qbman_swp *s, 197293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 198293c0ca9SNipun Gupta const struct qbman_fd *fd) 199293c0ca9SNipun Gupta = qbman_swp_enqueue_ring_mode_direct; 200293c0ca9SNipun Gupta 201293c0ca9SNipun Gupta static int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s, 202293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 203293c0ca9SNipun Gupta const struct qbman_fd *fd, 204293c0ca9SNipun Gupta uint32_t *flags, 205293c0ca9SNipun Gupta int num_frames) 206293c0ca9SNipun Gupta = qbman_swp_enqueue_multiple_direct; 207293c0ca9SNipun Gupta 208a3a997f0SHemant Agrawal static int (*qbman_swp_enqueue_multiple_fd_ptr)(struct qbman_swp *s, 209a3a997f0SHemant Agrawal const struct qbman_eq_desc *d, 210a3a997f0SHemant Agrawal struct qbman_fd **fd, 211a3a997f0SHemant Agrawal uint32_t *flags, 212a3a997f0SHemant Agrawal int num_frames) 213a3a997f0SHemant Agrawal = qbman_swp_enqueue_multiple_fd_direct; 214a3a997f0SHemant Agrawal 215293c0ca9SNipun Gupta static int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s, 216293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 217293c0ca9SNipun Gupta const struct qbman_fd *fd, 218293c0ca9SNipun Gupta int num_frames) 219293c0ca9SNipun Gupta = qbman_swp_enqueue_multiple_desc_direct; 220293c0ca9SNipun Gupta 221293c0ca9SNipun Gupta static int (*qbman_swp_pull_ptr)(struct qbman_swp *s, 222293c0ca9SNipun Gupta struct qbman_pull_desc *d) 223293c0ca9SNipun Gupta = qbman_swp_pull_direct; 224293c0ca9SNipun Gupta 225293c0ca9SNipun Gupta const struct qbman_result *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s) 226293c0ca9SNipun Gupta = qbman_swp_dqrr_next_direct; 227293c0ca9SNipun Gupta 228293c0ca9SNipun Gupta static int (*qbman_swp_release_ptr)(struct qbman_swp *s, 229293c0ca9SNipun Gupta const struct qbman_release_desc *d, 230293c0ca9SNipun Gupta const uint64_t *buffers, unsigned int num_buffers) 231293c0ca9SNipun Gupta = qbman_swp_release_direct; 232293c0ca9SNipun Gupta 233531b17a7SHemant Agrawal /*********************************/ 234531b17a7SHemant Agrawal /* Portal constructor/destructor */ 235531b17a7SHemant Agrawal /*********************************/ 236531b17a7SHemant Agrawal 237531b17a7SHemant Agrawal /* Software portals should always be in the power-on state when we initialise, 238531b17a7SHemant Agrawal * due to the CCSR-based portal reset functionality that MC has. 239531b17a7SHemant Agrawal * 240531b17a7SHemant Agrawal * Erk! Turns out that QMan versions prior to 4.1 do not correctly reset DQRR 241531b17a7SHemant Agrawal * valid-bits, so we need to support a workaround where we don't trust 242531b17a7SHemant Agrawal * valid-bits when detecting new entries until any stale ring entries have been 243531b17a7SHemant Agrawal * overwritten at least once. The idea is that we read PI for the first few 244531b17a7SHemant Agrawal * entries, then switch to valid-bit after that. The trick is to clear the 245531b17a7SHemant Agrawal * bug-work-around boolean once the PI wraps around the ring for the first time. 246531b17a7SHemant Agrawal * 247531b17a7SHemant Agrawal * Note: this still carries a slight additional cost once the decrementer hits 248531b17a7SHemant Agrawal * zero. 249531b17a7SHemant Agrawal */ 250531b17a7SHemant Agrawal struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) 251531b17a7SHemant Agrawal { 252531b17a7SHemant Agrawal int ret; 253531b17a7SHemant Agrawal uint32_t eqcr_pi; 254293c0ca9SNipun Gupta uint32_t mask_size; 255d95bdc09SHemant Agrawal struct qbman_swp *p = malloc(sizeof(*p)); 256531b17a7SHemant Agrawal 257531b17a7SHemant Agrawal if (!p) 258531b17a7SHemant Agrawal return NULL; 259293c0ca9SNipun Gupta 260293c0ca9SNipun Gupta memset(p, 0, sizeof(struct qbman_swp)); 261293c0ca9SNipun Gupta 262531b17a7SHemant Agrawal p->desc = *d; 263531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING 264531b17a7SHemant Agrawal p->mc.check = swp_mc_can_start; 265531b17a7SHemant Agrawal #endif 266531b17a7SHemant Agrawal p->mc.valid_bit = QB_VALID_BIT; 26769293c77SHemant Agrawal p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT; 26869293c77SHemant Agrawal p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT; 26969293c77SHemant Agrawal p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT; 2703f28677aSHemant Agrawal if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 2713f28677aSHemant Agrawal && (d->cena_access_mode == qman_cena_fastest_access)) 272293c0ca9SNipun Gupta p->mr.valid_bit = QB_VALID_BIT; 27369293c77SHemant Agrawal 274531b17a7SHemant Agrawal atomic_set(&p->vdq.busy, 1); 275531b17a7SHemant Agrawal p->vdq.valid_bit = QB_VALID_BIT; 276531b17a7SHemant Agrawal p->dqrr.valid_bit = QB_VALID_BIT; 277293c0ca9SNipun Gupta qman_version = p->desc.qman_version; 278ff8e5f10SHemant Agrawal if ((qman_version & QMAN_REV_MASK) < QMAN_REV_4100) { 279531b17a7SHemant Agrawal p->dqrr.dqrr_size = 4; 280531b17a7SHemant Agrawal p->dqrr.reset_bug = 1; 281531b17a7SHemant Agrawal } else { 282531b17a7SHemant Agrawal p->dqrr.dqrr_size = 8; 283531b17a7SHemant Agrawal p->dqrr.reset_bug = 0; 284531b17a7SHemant Agrawal } 285531b17a7SHemant Agrawal 286531b17a7SHemant Agrawal ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size); 287531b17a7SHemant Agrawal if (ret) { 288d95bdc09SHemant Agrawal free(p); 289531b17a7SHemant Agrawal pr_err("qbman_swp_sys_init() failed %d\n", ret); 290531b17a7SHemant Agrawal return NULL; 291531b17a7SHemant Agrawal } 292293c0ca9SNipun Gupta 293293c0ca9SNipun Gupta /* Verify that the DQRRPI is 0 - if it is not the portal isn't 294293c0ca9SNipun Gupta * in default state which is an error 295293c0ca9SNipun Gupta */ 296293c0ca9SNipun Gupta if (qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_DQPI) & 0xF) { 297293c0ca9SNipun Gupta pr_err("qbman DQRR PI is not zero, portal is not clean\n"); 298293c0ca9SNipun Gupta free(p); 299293c0ca9SNipun Gupta return NULL; 300293c0ca9SNipun Gupta } 301293c0ca9SNipun Gupta 302531b17a7SHemant Agrawal /* SDQCR needs to be initialized to 0 when no channels are 303531b17a7SHemant Agrawal * being dequeued from or else the QMan HW will indicate an 304531b17a7SHemant Agrawal * error. The values that were calculated above will be 30569293c77SHemant Agrawal * applied when dequeues from a specific channel are enabled. 306531b17a7SHemant Agrawal */ 307531b17a7SHemant Agrawal qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0); 308293c0ca9SNipun Gupta 309293c0ca9SNipun Gupta p->eqcr.pi_ring_size = 8; 3103f28677aSHemant Agrawal if ((qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 3113f28677aSHemant Agrawal && (d->cena_access_mode == qman_cena_fastest_access)) { 312293c0ca9SNipun Gupta p->eqcr.pi_ring_size = 32; 313293c0ca9SNipun Gupta qbman_swp_enqueue_array_mode_ptr = 314293c0ca9SNipun Gupta qbman_swp_enqueue_array_mode_mem_back; 315293c0ca9SNipun Gupta qbman_swp_enqueue_ring_mode_ptr = 316293c0ca9SNipun Gupta qbman_swp_enqueue_ring_mode_mem_back; 317293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_ptr = 318293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_mem_back; 319a3a997f0SHemant Agrawal qbman_swp_enqueue_multiple_fd_ptr = 320a3a997f0SHemant Agrawal qbman_swp_enqueue_multiple_fd_mem_back; 321293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_desc_ptr = 322293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_desc_mem_back; 323293c0ca9SNipun Gupta qbman_swp_pull_ptr = qbman_swp_pull_mem_back; 324293c0ca9SNipun Gupta qbman_swp_dqrr_next_ptr = qbman_swp_dqrr_next_mem_back; 325293c0ca9SNipun Gupta qbman_swp_release_ptr = qbman_swp_release_mem_back; 326293c0ca9SNipun Gupta } 327293c0ca9SNipun Gupta 32863d5d0afSNipun Gupta if (dpaa2_svr_family == SVR_LS1080A) { 32963d5d0afSNipun Gupta qbman_swp_enqueue_ring_mode_ptr = 33079e5b5edSNipun Gupta qbman_swp_enqueue_ring_mode_cinh_read_direct; 33163d5d0afSNipun Gupta qbman_swp_enqueue_multiple_ptr = 33279e5b5edSNipun Gupta qbman_swp_enqueue_multiple_cinh_read_direct; 33363d5d0afSNipun Gupta qbman_swp_enqueue_multiple_fd_ptr = 33479e5b5edSNipun Gupta qbman_swp_enqueue_multiple_fd_cinh_read_direct; 33563d5d0afSNipun Gupta qbman_swp_enqueue_multiple_desc_ptr = 33679e5b5edSNipun Gupta qbman_swp_enqueue_multiple_desc_cinh_read_direct; 33763d5d0afSNipun Gupta } 33863d5d0afSNipun Gupta 339293c0ca9SNipun Gupta for (mask_size = p->eqcr.pi_ring_size; mask_size > 0; mask_size >>= 1) 3401b49352fSHemant Agrawal p->eqcr.pi_ci_mask = (p->eqcr.pi_ci_mask<<1) + 1; 341531b17a7SHemant Agrawal eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI); 3421b49352fSHemant Agrawal p->eqcr.pi = eqcr_pi & p->eqcr.pi_ci_mask; 343531b17a7SHemant Agrawal p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT; 3441b49352fSHemant Agrawal p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) 3451b49352fSHemant Agrawal & p->eqcr.pi_ci_mask; 346a675f35dSYouri Querry p->eqcr.available = p->eqcr.pi_ring_size; 347531b17a7SHemant Agrawal 348531b17a7SHemant Agrawal portal_idx_map[p->desc.idx] = p; 349531b17a7SHemant Agrawal return p; 350531b17a7SHemant Agrawal } 351531b17a7SHemant Agrawal 352b3bd7a50SNipun Gupta int qbman_swp_update(struct qbman_swp *p, int stash_off) 353b3bd7a50SNipun Gupta { 354b3bd7a50SNipun Gupta const struct qbman_swp_desc *d = &p->desc; 355b3bd7a50SNipun Gupta struct qbman_swp_sys *s = &p->sys; 356b3bd7a50SNipun Gupta int ret; 357b3bd7a50SNipun Gupta 358b3bd7a50SNipun Gupta /* Nothing needs to be done for QBMAN rev > 5000 with fast access */ 359b3bd7a50SNipun Gupta if ((qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 360b3bd7a50SNipun Gupta && (d->cena_access_mode == qman_cena_fastest_access)) 361b3bd7a50SNipun Gupta return 0; 362b3bd7a50SNipun Gupta 363b3bd7a50SNipun Gupta ret = qbman_swp_sys_update(s, d, p->dqrr.dqrr_size, stash_off); 364b3bd7a50SNipun Gupta if (ret) { 365b3bd7a50SNipun Gupta pr_err("qbman_swp_sys_init() failed %d\n", ret); 366b3bd7a50SNipun Gupta return ret; 367b3bd7a50SNipun Gupta } 368b3bd7a50SNipun Gupta 369b3bd7a50SNipun Gupta p->stash_off = stash_off; 370b3bd7a50SNipun Gupta 371b3bd7a50SNipun Gupta return 0; 372b3bd7a50SNipun Gupta } 373b3bd7a50SNipun Gupta 374531b17a7SHemant Agrawal void qbman_swp_finish(struct qbman_swp *p) 375531b17a7SHemant Agrawal { 376531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING 377531b17a7SHemant Agrawal QBMAN_BUG_ON(p->mc.check != swp_mc_can_start); 378531b17a7SHemant Agrawal #endif 379531b17a7SHemant Agrawal qbman_swp_sys_finish(&p->sys); 380531b17a7SHemant Agrawal portal_idx_map[p->desc.idx] = NULL; 381d95bdc09SHemant Agrawal free(p); 382531b17a7SHemant Agrawal } 383531b17a7SHemant Agrawal 384531b17a7SHemant Agrawal const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p) 385531b17a7SHemant Agrawal { 386531b17a7SHemant Agrawal return &p->desc; 387531b17a7SHemant Agrawal } 388531b17a7SHemant Agrawal 389531b17a7SHemant Agrawal /**************/ 390531b17a7SHemant Agrawal /* Interrupts */ 391531b17a7SHemant Agrawal /**************/ 392531b17a7SHemant Agrawal 393531b17a7SHemant Agrawal uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p) 394531b17a7SHemant Agrawal { 395531b17a7SHemant Agrawal return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISDR); 396531b17a7SHemant Agrawal } 397531b17a7SHemant Agrawal 398531b17a7SHemant Agrawal void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask) 399531b17a7SHemant Agrawal { 400531b17a7SHemant Agrawal qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISDR, mask); 401531b17a7SHemant Agrawal } 402531b17a7SHemant Agrawal 403531b17a7SHemant Agrawal uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p) 404531b17a7SHemant Agrawal { 405531b17a7SHemant Agrawal return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISR); 406531b17a7SHemant Agrawal } 407531b17a7SHemant Agrawal 408531b17a7SHemant Agrawal void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask) 409531b17a7SHemant Agrawal { 410531b17a7SHemant Agrawal qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask); 411531b17a7SHemant Agrawal } 412531b17a7SHemant Agrawal 4139ccb76b2SNipun Gupta uint32_t qbman_swp_dqrr_thrshld_read_status(struct qbman_swp *p) 4149ccb76b2SNipun Gupta { 4159ccb76b2SNipun Gupta return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_DQRR_ITR); 4169ccb76b2SNipun Gupta } 4179ccb76b2SNipun Gupta 4189ccb76b2SNipun Gupta void qbman_swp_dqrr_thrshld_write(struct qbman_swp *p, uint32_t mask) 4199ccb76b2SNipun Gupta { 4209ccb76b2SNipun Gupta qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_DQRR_ITR, mask); 4219ccb76b2SNipun Gupta } 4229ccb76b2SNipun Gupta 4239ccb76b2SNipun Gupta uint32_t qbman_swp_intr_timeout_read_status(struct qbman_swp *p) 4249ccb76b2SNipun Gupta { 4259ccb76b2SNipun Gupta return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ITPR); 4269ccb76b2SNipun Gupta } 4279ccb76b2SNipun Gupta 4289ccb76b2SNipun Gupta void qbman_swp_intr_timeout_write(struct qbman_swp *p, uint32_t mask) 4299ccb76b2SNipun Gupta { 4309ccb76b2SNipun Gupta qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ITPR, mask); 4319ccb76b2SNipun Gupta } 4329ccb76b2SNipun Gupta 433531b17a7SHemant Agrawal uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p) 434531b17a7SHemant Agrawal { 435531b17a7SHemant Agrawal return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER); 436531b17a7SHemant Agrawal } 437531b17a7SHemant Agrawal 438531b17a7SHemant Agrawal void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask) 439531b17a7SHemant Agrawal { 440531b17a7SHemant Agrawal qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IER, mask); 441531b17a7SHemant Agrawal } 442531b17a7SHemant Agrawal 443531b17a7SHemant Agrawal int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p) 444531b17a7SHemant Agrawal { 445531b17a7SHemant Agrawal return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IIR); 446531b17a7SHemant Agrawal } 447531b17a7SHemant Agrawal 448531b17a7SHemant Agrawal void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit) 449531b17a7SHemant Agrawal { 450293c0ca9SNipun Gupta qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR, 451293c0ca9SNipun Gupta inhibit ? 0xffffffff : 0); 452531b17a7SHemant Agrawal } 453531b17a7SHemant Agrawal 454531b17a7SHemant Agrawal /***********************/ 455531b17a7SHemant Agrawal /* Management commands */ 456531b17a7SHemant Agrawal /***********************/ 457531b17a7SHemant Agrawal 458531b17a7SHemant Agrawal /* 459531b17a7SHemant Agrawal * Internal code common to all types of management commands. 460531b17a7SHemant Agrawal */ 461531b17a7SHemant Agrawal 462531b17a7SHemant Agrawal void *qbman_swp_mc_start(struct qbman_swp *p) 463531b17a7SHemant Agrawal { 464531b17a7SHemant Agrawal void *ret; 465531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING 466531b17a7SHemant Agrawal QBMAN_BUG_ON(p->mc.check != swp_mc_can_start); 467531b17a7SHemant Agrawal #endif 4683f28677aSHemant Agrawal if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 4693f28677aSHemant Agrawal && (p->desc.cena_access_mode == qman_cena_fastest_access)) 470293c0ca9SNipun Gupta ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR_MEM); 4713f28677aSHemant Agrawal else 4723f28677aSHemant Agrawal ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR); 473531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING 474531b17a7SHemant Agrawal if (!ret) 475531b17a7SHemant Agrawal p->mc.check = swp_mc_can_submit; 476531b17a7SHemant Agrawal #endif 477531b17a7SHemant Agrawal return ret; 478531b17a7SHemant Agrawal } 479531b17a7SHemant Agrawal 48069293c77SHemant Agrawal void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint8_t cmd_verb) 481531b17a7SHemant Agrawal { 48269293c77SHemant Agrawal uint8_t *v = cmd; 483531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING 484531b17a7SHemant Agrawal QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit)); 485531b17a7SHemant Agrawal #endif 486531b17a7SHemant Agrawal /* TBD: "|=" is going to hurt performance. Need to move as many fields 487531b17a7SHemant Agrawal * out of word zero, and for those that remain, the "OR" needs to occur 488531b17a7SHemant Agrawal * at the caller side. This debug check helps to catch cases where the 489531b17a7SHemant Agrawal * caller wants to OR but has forgotten to do so. 490531b17a7SHemant Agrawal */ 491531b17a7SHemant Agrawal QBMAN_BUG_ON((*v & cmd_verb) != *v); 4923f28677aSHemant Agrawal if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 4933f28677aSHemant Agrawal && (p->desc.cena_access_mode == qman_cena_fastest_access)) { 494293c0ca9SNipun Gupta *v = cmd_verb | p->mr.valid_bit; 495293c0ca9SNipun Gupta qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR_MEM, cmd); 496293c0ca9SNipun Gupta dma_wmb(); 497293c0ca9SNipun Gupta qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_CR_RT, QMAN_RT_MODE); 4983f28677aSHemant Agrawal } else { 4993f28677aSHemant Agrawal dma_wmb(); 5003f28677aSHemant Agrawal *v = cmd_verb | p->mc.valid_bit; 5013f28677aSHemant Agrawal qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd); 5023f28677aSHemant Agrawal clean(cmd); 503293c0ca9SNipun Gupta } 504531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING 505531b17a7SHemant Agrawal p->mc.check = swp_mc_can_poll; 506531b17a7SHemant Agrawal #endif 507531b17a7SHemant Agrawal } 508531b17a7SHemant Agrawal 509b3bd7a50SNipun Gupta void qbman_swp_mc_submit_cinh(struct qbman_swp *p, void *cmd, uint8_t cmd_verb) 510b3bd7a50SNipun Gupta { 511b3bd7a50SNipun Gupta uint8_t *v = cmd; 512b3bd7a50SNipun Gupta #ifdef QBMAN_CHECKING 513b3bd7a50SNipun Gupta QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit)); 514b3bd7a50SNipun Gupta #endif 515b3bd7a50SNipun Gupta /* TBD: "|=" is going to hurt performance. Need to move as many fields 516b3bd7a50SNipun Gupta * out of word zero, and for those that remain, the "OR" needs to occur 517b3bd7a50SNipun Gupta * at the caller side. This debug check helps to catch cases where the 518b3bd7a50SNipun Gupta * caller wants to OR but has forgotten to do so. 519b3bd7a50SNipun Gupta */ 520b3bd7a50SNipun Gupta QBMAN_BUG_ON((*v & cmd_verb) != *v); 521b3bd7a50SNipun Gupta dma_wmb(); 522b3bd7a50SNipun Gupta *v = cmd_verb | p->mc.valid_bit; 523b3bd7a50SNipun Gupta qbman_cinh_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd); 524b3bd7a50SNipun Gupta clean(cmd); 525b3bd7a50SNipun Gupta #ifdef QBMAN_CHECKING 526b3bd7a50SNipun Gupta p->mc.check = swp_mc_can_poll; 527b3bd7a50SNipun Gupta #endif 528b3bd7a50SNipun Gupta } 529b3bd7a50SNipun Gupta 530531b17a7SHemant Agrawal void *qbman_swp_mc_result(struct qbman_swp *p) 531531b17a7SHemant Agrawal { 532531b17a7SHemant Agrawal uint32_t *ret, verb; 533531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING 534531b17a7SHemant Agrawal QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll); 535531b17a7SHemant Agrawal #endif 5363f28677aSHemant Agrawal if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 5373f28677aSHemant Agrawal && (p->desc.cena_access_mode == qman_cena_fastest_access)) { 538293c0ca9SNipun Gupta ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR_MEM); 539293c0ca9SNipun Gupta /* Command completed if the valid bit is toggled */ 540293c0ca9SNipun Gupta if (p->mr.valid_bit != (ret[0] & QB_VALID_BIT)) 541293c0ca9SNipun Gupta return NULL; 542293c0ca9SNipun Gupta /* Remove the valid-bit - 543293c0ca9SNipun Gupta * command completed iff the rest is non-zero 544293c0ca9SNipun Gupta */ 545293c0ca9SNipun Gupta verb = ret[0] & ~QB_VALID_BIT; 546293c0ca9SNipun Gupta if (!verb) 547293c0ca9SNipun Gupta return NULL; 548293c0ca9SNipun Gupta p->mr.valid_bit ^= QB_VALID_BIT; 5493f28677aSHemant Agrawal } else { 5503f28677aSHemant Agrawal qbman_cena_invalidate_prefetch(&p->sys, 5513f28677aSHemant Agrawal QBMAN_CENA_SWP_RR(p->mc.valid_bit)); 5523f28677aSHemant Agrawal ret = qbman_cena_read(&p->sys, 5533f28677aSHemant Agrawal QBMAN_CENA_SWP_RR(p->mc.valid_bit)); 5543f28677aSHemant Agrawal /* Remove the valid-bit - 5553f28677aSHemant Agrawal * command completed iff the rest is non-zero 5563f28677aSHemant Agrawal */ 5573f28677aSHemant Agrawal verb = ret[0] & ~QB_VALID_BIT; 5583f28677aSHemant Agrawal if (!verb) 5593f28677aSHemant Agrawal return NULL; 5603f28677aSHemant Agrawal p->mc.valid_bit ^= QB_VALID_BIT; 561293c0ca9SNipun Gupta } 562531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING 563531b17a7SHemant Agrawal p->mc.check = swp_mc_can_start; 564531b17a7SHemant Agrawal #endif 565531b17a7SHemant Agrawal return ret; 566531b17a7SHemant Agrawal } 567531b17a7SHemant Agrawal 568b3bd7a50SNipun Gupta void *qbman_swp_mc_result_cinh(struct qbman_swp *p) 569b3bd7a50SNipun Gupta { 570b3bd7a50SNipun Gupta uint32_t *ret, verb; 571b3bd7a50SNipun Gupta #ifdef QBMAN_CHECKING 572b3bd7a50SNipun Gupta QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll); 573b3bd7a50SNipun Gupta #endif 574b3bd7a50SNipun Gupta ret = qbman_cinh_read_shadow(&p->sys, 575b3bd7a50SNipun Gupta QBMAN_CENA_SWP_RR(p->mc.valid_bit)); 576b3bd7a50SNipun Gupta /* Remove the valid-bit - 577b3bd7a50SNipun Gupta * command completed iff the rest is non-zero 578b3bd7a50SNipun Gupta */ 579b3bd7a50SNipun Gupta verb = ret[0] & ~QB_VALID_BIT; 580b3bd7a50SNipun Gupta if (!verb) 581b3bd7a50SNipun Gupta return NULL; 582b3bd7a50SNipun Gupta p->mc.valid_bit ^= QB_VALID_BIT; 583b3bd7a50SNipun Gupta #ifdef QBMAN_CHECKING 584b3bd7a50SNipun Gupta p->mc.check = swp_mc_can_start; 585b3bd7a50SNipun Gupta #endif 586b3bd7a50SNipun Gupta return ret; 587b3bd7a50SNipun Gupta } 588b3bd7a50SNipun Gupta 589531b17a7SHemant Agrawal /***********/ 590531b17a7SHemant Agrawal /* Enqueue */ 591531b17a7SHemant Agrawal /***********/ 592531b17a7SHemant Agrawal 59369293c77SHemant Agrawal #define QB_ENQUEUE_CMD_OPTIONS_SHIFT 0 59469293c77SHemant Agrawal enum qb_enqueue_commands { 59569293c77SHemant Agrawal enqueue_empty = 0, 59669293c77SHemant Agrawal enqueue_response_always = 1, 59769293c77SHemant Agrawal enqueue_rejects_to_fq = 2 598531b17a7SHemant Agrawal }; 599531b17a7SHemant Agrawal 60069293c77SHemant Agrawal #define QB_ENQUEUE_CMD_EC_OPTION_MASK 0x3 60169293c77SHemant Agrawal #define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2 60269293c77SHemant Agrawal #define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3 60369293c77SHemant Agrawal #define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4 60469293c77SHemant Agrawal #define QB_ENQUEUE_CMD_DCA_PK_SHIFT 6 60569293c77SHemant Agrawal #define QB_ENQUEUE_CMD_DCA_EN_SHIFT 7 60669293c77SHemant Agrawal #define QB_ENQUEUE_CMD_NLIS_SHIFT 14 60769293c77SHemant Agrawal #define QB_ENQUEUE_CMD_IS_NESN_SHIFT 15 60869293c77SHemant Agrawal 609531b17a7SHemant Agrawal void qbman_eq_desc_clear(struct qbman_eq_desc *d) 610531b17a7SHemant Agrawal { 611531b17a7SHemant Agrawal memset(d, 0, sizeof(*d)); 612531b17a7SHemant Agrawal } 613531b17a7SHemant Agrawal 614531b17a7SHemant Agrawal void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success) 615531b17a7SHemant Agrawal { 61669293c77SHemant Agrawal d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT); 61769293c77SHemant Agrawal if (respond_success) 61869293c77SHemant Agrawal d->eq.verb |= enqueue_response_always; 61969293c77SHemant Agrawal else 62069293c77SHemant Agrawal d->eq.verb |= enqueue_rejects_to_fq; 621531b17a7SHemant Agrawal } 622531b17a7SHemant Agrawal 623531b17a7SHemant Agrawal void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success, 62469293c77SHemant Agrawal uint16_t opr_id, uint16_t seqnum, int incomplete) 625531b17a7SHemant Agrawal { 62669293c77SHemant Agrawal d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT; 62769293c77SHemant Agrawal if (respond_success) 62869293c77SHemant Agrawal d->eq.verb |= enqueue_response_always; 62969293c77SHemant Agrawal else 63069293c77SHemant Agrawal d->eq.verb |= enqueue_rejects_to_fq; 631531b17a7SHemant Agrawal 63269293c77SHemant Agrawal d->eq.orpid = opr_id; 63369293c77SHemant Agrawal d->eq.seqnum = seqnum; 63469293c77SHemant Agrawal if (incomplete) 63569293c77SHemant Agrawal d->eq.seqnum |= 1 << QB_ENQUEUE_CMD_NLIS_SHIFT; 63669293c77SHemant Agrawal else 63769293c77SHemant Agrawal d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT); 638531b17a7SHemant Agrawal } 639531b17a7SHemant Agrawal 64069293c77SHemant Agrawal void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint16_t opr_id, 64169293c77SHemant Agrawal uint16_t seqnum) 642531b17a7SHemant Agrawal { 64369293c77SHemant Agrawal d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT; 64469293c77SHemant Agrawal d->eq.verb &= ~QB_ENQUEUE_CMD_EC_OPTION_MASK; 64569293c77SHemant Agrawal d->eq.orpid = opr_id; 64669293c77SHemant Agrawal d->eq.seqnum = seqnum; 64769293c77SHemant Agrawal d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT); 64869293c77SHemant Agrawal d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_IS_NESN_SHIFT); 649531b17a7SHemant Agrawal } 650531b17a7SHemant Agrawal 65169293c77SHemant Agrawal void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint16_t opr_id, 65269293c77SHemant Agrawal uint16_t seqnum) 653531b17a7SHemant Agrawal { 65469293c77SHemant Agrawal d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT; 65569293c77SHemant Agrawal d->eq.verb &= ~QB_ENQUEUE_CMD_EC_OPTION_MASK; 65669293c77SHemant Agrawal d->eq.orpid = opr_id; 65769293c77SHemant Agrawal d->eq.seqnum = seqnum; 65869293c77SHemant Agrawal d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT); 65969293c77SHemant Agrawal d->eq.seqnum |= 1 << QB_ENQUEUE_CMD_IS_NESN_SHIFT; 660531b17a7SHemant Agrawal } 661531b17a7SHemant Agrawal 662531b17a7SHemant Agrawal void qbman_eq_desc_set_response(struct qbman_eq_desc *d, 663531b17a7SHemant Agrawal dma_addr_t storage_phys, 664531b17a7SHemant Agrawal int stash) 665531b17a7SHemant Agrawal { 66669293c77SHemant Agrawal d->eq.rsp_addr = storage_phys; 66769293c77SHemant Agrawal d->eq.wae = stash; 668531b17a7SHemant Agrawal } 669531b17a7SHemant Agrawal 670531b17a7SHemant Agrawal void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token) 671531b17a7SHemant Agrawal { 67269293c77SHemant Agrawal d->eq.rspid = token; 673531b17a7SHemant Agrawal } 674531b17a7SHemant Agrawal 675531b17a7SHemant Agrawal void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid) 676531b17a7SHemant Agrawal { 67769293c77SHemant Agrawal d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT); 67869293c77SHemant Agrawal d->eq.tgtid = fqid; 679531b17a7SHemant Agrawal } 680531b17a7SHemant Agrawal 681531b17a7SHemant Agrawal void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid, 68269293c77SHemant Agrawal uint16_t qd_bin, uint8_t qd_prio) 683531b17a7SHemant Agrawal { 68469293c77SHemant Agrawal d->eq.verb |= 1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT; 68569293c77SHemant Agrawal d->eq.tgtid = qdid; 68669293c77SHemant Agrawal d->eq.qdbin = qd_bin; 68769293c77SHemant Agrawal d->eq.qpri = qd_prio; 688531b17a7SHemant Agrawal } 689531b17a7SHemant Agrawal 690531b17a7SHemant Agrawal void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable) 691531b17a7SHemant Agrawal { 69269293c77SHemant Agrawal if (enable) 69369293c77SHemant Agrawal d->eq.verb |= 1 << QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT; 69469293c77SHemant Agrawal else 69569293c77SHemant Agrawal d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT); 696531b17a7SHemant Agrawal } 697531b17a7SHemant Agrawal 698531b17a7SHemant Agrawal void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable, 69969293c77SHemant Agrawal uint8_t dqrr_idx, int park) 700531b17a7SHemant Agrawal { 701531b17a7SHemant Agrawal if (enable) { 70269293c77SHemant Agrawal d->eq.dca = dqrr_idx; 70369293c77SHemant Agrawal if (park) 70469293c77SHemant Agrawal d->eq.dca |= 1 << QB_ENQUEUE_CMD_DCA_PK_SHIFT; 70569293c77SHemant Agrawal else 70669293c77SHemant Agrawal d->eq.dca &= ~(1 << QB_ENQUEUE_CMD_DCA_PK_SHIFT); 70769293c77SHemant Agrawal d->eq.dca |= 1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT; 70869293c77SHemant Agrawal } else { 70969293c77SHemant Agrawal d->eq.dca &= ~(1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT); 710531b17a7SHemant Agrawal } 711531b17a7SHemant Agrawal } 712531b17a7SHemant Agrawal 713293c0ca9SNipun Gupta #define EQAR_IDX(eqar) ((eqar) & 0x1f) 714531b17a7SHemant Agrawal #define EQAR_VB(eqar) ((eqar) & 0x80) 715531b17a7SHemant Agrawal #define EQAR_SUCCESS(eqar) ((eqar) & 0x100) 71669293c77SHemant Agrawal 717293c0ca9SNipun Gupta static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p, 718293c0ca9SNipun Gupta uint8_t idx) 719293c0ca9SNipun Gupta { 720293c0ca9SNipun Gupta if (idx < 16) 721293c0ca9SNipun Gupta qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_EQCR_AM_RT + idx * 4, 722293c0ca9SNipun Gupta QMAN_RT_MODE); 723293c0ca9SNipun Gupta else 724293c0ca9SNipun Gupta qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_EQCR_AM_RT2 + 725293c0ca9SNipun Gupta (idx - 16) * 4, 726293c0ca9SNipun Gupta QMAN_RT_MODE); 727293c0ca9SNipun Gupta } 728293c0ca9SNipun Gupta 729b3bd7a50SNipun Gupta static void memcpy_byte_by_byte(void *to, const void *from, size_t n) 730b3bd7a50SNipun Gupta { 731b3bd7a50SNipun Gupta const uint8_t *src = from; 732b3bd7a50SNipun Gupta volatile uint8_t *dest = to; 733b3bd7a50SNipun Gupta size_t i; 734b3bd7a50SNipun Gupta 735b3bd7a50SNipun Gupta for (i = 0; i < n; i++) 736b3bd7a50SNipun Gupta dest[i] = src[i]; 737b3bd7a50SNipun Gupta } 738b3bd7a50SNipun Gupta 739293c0ca9SNipun Gupta 740293c0ca9SNipun Gupta static int qbman_swp_enqueue_array_mode_direct(struct qbman_swp *s, 741531b17a7SHemant Agrawal const struct qbman_eq_desc *d, 742531b17a7SHemant Agrawal const struct qbman_fd *fd) 743531b17a7SHemant Agrawal { 744531b17a7SHemant Agrawal uint32_t *p; 745531b17a7SHemant Agrawal const uint32_t *cl = qb_cl(d); 746531b17a7SHemant Agrawal uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR); 747531b17a7SHemant Agrawal 748531b17a7SHemant Agrawal pr_debug("EQAR=%08x\n", eqar); 749531b17a7SHemant Agrawal if (!EQAR_SUCCESS(eqar)) 750531b17a7SHemant Agrawal return -EBUSY; 751531b17a7SHemant Agrawal p = qbman_cena_write_start_wo_shadow(&s->sys, 752531b17a7SHemant Agrawal QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); 7538b870905SHaiying Wang memcpy(&p[1], &cl[1], 28); 7548b870905SHaiying Wang memcpy(&p[8], fd, sizeof(*fd)); 755293c0ca9SNipun Gupta 756531b17a7SHemant Agrawal /* Set the verb byte, have to substitute in the valid-bit */ 757293c0ca9SNipun Gupta dma_wmb(); 758531b17a7SHemant Agrawal p[0] = cl[0] | EQAR_VB(eqar); 759531b17a7SHemant Agrawal qbman_cena_write_complete_wo_shadow(&s->sys, 760531b17a7SHemant Agrawal QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); 761531b17a7SHemant Agrawal return 0; 762531b17a7SHemant Agrawal } 763293c0ca9SNipun Gupta static int qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp *s, 764531b17a7SHemant Agrawal const struct qbman_eq_desc *d, 765531b17a7SHemant Agrawal const struct qbman_fd *fd) 766531b17a7SHemant Agrawal { 767531b17a7SHemant Agrawal uint32_t *p; 768531b17a7SHemant Agrawal const uint32_t *cl = qb_cl(d); 769293c0ca9SNipun Gupta uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR); 770531b17a7SHemant Agrawal 771293c0ca9SNipun Gupta pr_debug("EQAR=%08x\n", eqar); 772293c0ca9SNipun Gupta if (!EQAR_SUCCESS(eqar)) 773293c0ca9SNipun Gupta return -EBUSY; 774293c0ca9SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 775293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); 776293c0ca9SNipun Gupta memcpy(&p[1], &cl[1], 28); 777293c0ca9SNipun Gupta memcpy(&p[8], fd, sizeof(*fd)); 778293c0ca9SNipun Gupta 779293c0ca9SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 780293c0ca9SNipun Gupta p[0] = cl[0] | EQAR_VB(eqar); 781293c0ca9SNipun Gupta dma_wmb(); 782293c0ca9SNipun Gupta qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar)); 783293c0ca9SNipun Gupta return 0; 784293c0ca9SNipun Gupta } 785293c0ca9SNipun Gupta 786293c0ca9SNipun Gupta static inline int qbman_swp_enqueue_array_mode(struct qbman_swp *s, 787293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 788293c0ca9SNipun Gupta const struct qbman_fd *fd) 789293c0ca9SNipun Gupta { 790293c0ca9SNipun Gupta return qbman_swp_enqueue_array_mode_ptr(s, d, fd); 791293c0ca9SNipun Gupta } 792293c0ca9SNipun Gupta 793293c0ca9SNipun Gupta static int qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s, 794293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 795293c0ca9SNipun Gupta const struct qbman_fd *fd) 796293c0ca9SNipun Gupta { 797293c0ca9SNipun Gupta uint32_t *p; 798293c0ca9SNipun Gupta const uint32_t *cl = qb_cl(d); 799293c0ca9SNipun Gupta uint32_t eqcr_ci, full_mask, half_mask; 800293c0ca9SNipun Gupta 8011b49352fSHemant Agrawal half_mask = (s->eqcr.pi_ci_mask>>1); 8021b49352fSHemant Agrawal full_mask = s->eqcr.pi_ci_mask; 803531b17a7SHemant Agrawal if (!s->eqcr.available) { 804531b17a7SHemant Agrawal eqcr_ci = s->eqcr.ci; 805531b17a7SHemant Agrawal s->eqcr.ci = qbman_cena_read_reg(&s->sys, 806293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR_CI) & full_mask; 807293c0ca9SNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 808531b17a7SHemant Agrawal eqcr_ci, s->eqcr.ci); 809293c0ca9SNipun Gupta if (!s->eqcr.available) 810531b17a7SHemant Agrawal return -EBUSY; 811531b17a7SHemant Agrawal } 812531b17a7SHemant Agrawal 813531b17a7SHemant Agrawal p = qbman_cena_write_start_wo_shadow(&s->sys, 814293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask)); 8158b870905SHaiying Wang memcpy(&p[1], &cl[1], 28); 8168b870905SHaiying Wang memcpy(&p[8], fd, sizeof(*fd)); 817531b17a7SHemant Agrawal lwsync(); 81869293c77SHemant Agrawal 819531b17a7SHemant Agrawal /* Set the verb byte, have to substitute in the valid-bit */ 820531b17a7SHemant Agrawal p[0] = cl[0] | s->eqcr.pi_vb; 821531b17a7SHemant Agrawal qbman_cena_write_complete_wo_shadow(&s->sys, 822293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask)); 823531b17a7SHemant Agrawal s->eqcr.pi++; 824293c0ca9SNipun Gupta s->eqcr.pi &= full_mask; 825531b17a7SHemant Agrawal s->eqcr.available--; 826293c0ca9SNipun Gupta if (!(s->eqcr.pi & half_mask)) 827531b17a7SHemant Agrawal s->eqcr.pi_vb ^= QB_VALID_BIT; 82869293c77SHemant Agrawal 829531b17a7SHemant Agrawal return 0; 830531b17a7SHemant Agrawal } 831531b17a7SHemant Agrawal 83279e5b5edSNipun Gupta static int qbman_swp_enqueue_ring_mode_cinh_read_direct( 83363d5d0afSNipun Gupta struct qbman_swp *s, 83463d5d0afSNipun Gupta const struct qbman_eq_desc *d, 83563d5d0afSNipun Gupta const struct qbman_fd *fd) 83663d5d0afSNipun Gupta { 83763d5d0afSNipun Gupta uint32_t *p; 83863d5d0afSNipun Gupta const uint32_t *cl = qb_cl(d); 83963d5d0afSNipun Gupta uint32_t eqcr_ci, full_mask, half_mask; 84063d5d0afSNipun Gupta 84163d5d0afSNipun Gupta half_mask = (s->eqcr.pi_ci_mask>>1); 84263d5d0afSNipun Gupta full_mask = s->eqcr.pi_ci_mask; 84363d5d0afSNipun Gupta if (!s->eqcr.available) { 84463d5d0afSNipun Gupta eqcr_ci = s->eqcr.ci; 84563d5d0afSNipun Gupta s->eqcr.ci = qbman_cinh_read(&s->sys, 84663d5d0afSNipun Gupta QBMAN_CINH_SWP_EQCR_CI) & full_mask; 84763d5d0afSNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 84863d5d0afSNipun Gupta eqcr_ci, s->eqcr.ci); 84963d5d0afSNipun Gupta if (!s->eqcr.available) 85063d5d0afSNipun Gupta return -EBUSY; 85163d5d0afSNipun Gupta } 85263d5d0afSNipun Gupta 853b3bd7a50SNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 85463d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask)); 85563d5d0afSNipun Gupta memcpy(&p[1], &cl[1], 28); 85663d5d0afSNipun Gupta memcpy(&p[8], fd, sizeof(*fd)); 85763d5d0afSNipun Gupta lwsync(); 85863d5d0afSNipun Gupta 85963d5d0afSNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 86063d5d0afSNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 86163d5d0afSNipun Gupta s->eqcr.pi++; 86263d5d0afSNipun Gupta s->eqcr.pi &= full_mask; 86363d5d0afSNipun Gupta s->eqcr.available--; 86463d5d0afSNipun Gupta if (!(s->eqcr.pi & half_mask)) 86563d5d0afSNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 86663d5d0afSNipun Gupta 86763d5d0afSNipun Gupta return 0; 86863d5d0afSNipun Gupta } 86963d5d0afSNipun Gupta 87079e5b5edSNipun Gupta static int qbman_swp_enqueue_ring_mode_cinh_direct( 87179e5b5edSNipun Gupta struct qbman_swp *s, 87279e5b5edSNipun Gupta const struct qbman_eq_desc *d, 87379e5b5edSNipun Gupta const struct qbman_fd *fd) 87479e5b5edSNipun Gupta { 87579e5b5edSNipun Gupta uint32_t *p; 87679e5b5edSNipun Gupta const uint32_t *cl = qb_cl(d); 87779e5b5edSNipun Gupta uint32_t eqcr_ci, full_mask, half_mask; 87879e5b5edSNipun Gupta 87979e5b5edSNipun Gupta half_mask = (s->eqcr.pi_ci_mask>>1); 88079e5b5edSNipun Gupta full_mask = s->eqcr.pi_ci_mask; 88179e5b5edSNipun Gupta if (!s->eqcr.available) { 88279e5b5edSNipun Gupta eqcr_ci = s->eqcr.ci; 88379e5b5edSNipun Gupta s->eqcr.ci = qbman_cinh_read(&s->sys, 88479e5b5edSNipun Gupta QBMAN_CINH_SWP_EQCR_CI) & full_mask; 88579e5b5edSNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 88679e5b5edSNipun Gupta eqcr_ci, s->eqcr.ci); 88779e5b5edSNipun Gupta if (!s->eqcr.available) 88879e5b5edSNipun Gupta return -EBUSY; 88979e5b5edSNipun Gupta } 89079e5b5edSNipun Gupta 89179e5b5edSNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 89279e5b5edSNipun Gupta QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask)); 89379e5b5edSNipun Gupta memcpy_byte_by_byte(&p[1], &cl[1], 28); 89479e5b5edSNipun Gupta memcpy_byte_by_byte(&p[8], fd, sizeof(*fd)); 89579e5b5edSNipun Gupta lwsync(); 89679e5b5edSNipun Gupta 89779e5b5edSNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 89879e5b5edSNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 89979e5b5edSNipun Gupta s->eqcr.pi++; 90079e5b5edSNipun Gupta s->eqcr.pi &= full_mask; 90179e5b5edSNipun Gupta s->eqcr.available--; 90279e5b5edSNipun Gupta if (!(s->eqcr.pi & half_mask)) 90379e5b5edSNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 90479e5b5edSNipun Gupta 90579e5b5edSNipun Gupta return 0; 90679e5b5edSNipun Gupta } 90779e5b5edSNipun Gupta 908293c0ca9SNipun Gupta static int qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s, 909293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 910293c0ca9SNipun Gupta const struct qbman_fd *fd) 911293c0ca9SNipun Gupta { 912293c0ca9SNipun Gupta uint32_t *p; 913293c0ca9SNipun Gupta const uint32_t *cl = qb_cl(d); 914293c0ca9SNipun Gupta uint32_t eqcr_ci, full_mask, half_mask; 915293c0ca9SNipun Gupta 9161b49352fSHemant Agrawal half_mask = (s->eqcr.pi_ci_mask>>1); 9171b49352fSHemant Agrawal full_mask = s->eqcr.pi_ci_mask; 918293c0ca9SNipun Gupta if (!s->eqcr.available) { 919293c0ca9SNipun Gupta eqcr_ci = s->eqcr.ci; 9202557cf8fSYouri Querry s->eqcr.ci = qbman_cena_read_reg(&s->sys, 9212557cf8fSYouri Querry QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask; 922293c0ca9SNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 923293c0ca9SNipun Gupta eqcr_ci, s->eqcr.ci); 924293c0ca9SNipun Gupta if (!s->eqcr.available) 925293c0ca9SNipun Gupta return -EBUSY; 926293c0ca9SNipun Gupta } 927293c0ca9SNipun Gupta 928293c0ca9SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 929293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask)); 930293c0ca9SNipun Gupta memcpy(&p[1], &cl[1], 28); 931293c0ca9SNipun Gupta memcpy(&p[8], fd, sizeof(*fd)); 932293c0ca9SNipun Gupta 933293c0ca9SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 934293c0ca9SNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 935293c0ca9SNipun Gupta s->eqcr.pi++; 936293c0ca9SNipun Gupta s->eqcr.pi &= full_mask; 937293c0ca9SNipun Gupta s->eqcr.available--; 938293c0ca9SNipun Gupta if (!(s->eqcr.pi & half_mask)) 939293c0ca9SNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 940293c0ca9SNipun Gupta dma_wmb(); 941293c0ca9SNipun Gupta qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI, 942293c0ca9SNipun Gupta (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); 943293c0ca9SNipun Gupta return 0; 944293c0ca9SNipun Gupta } 945293c0ca9SNipun Gupta 946293c0ca9SNipun Gupta static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s, 947293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 948293c0ca9SNipun Gupta const struct qbman_fd *fd) 949293c0ca9SNipun Gupta { 950b3bd7a50SNipun Gupta if (!s->stash_off) 951293c0ca9SNipun Gupta return qbman_swp_enqueue_ring_mode_ptr(s, d, fd); 952b3bd7a50SNipun Gupta else 953b3bd7a50SNipun Gupta return qbman_swp_enqueue_ring_mode_cinh_direct(s, d, fd); 954293c0ca9SNipun Gupta } 955293c0ca9SNipun Gupta 956531b17a7SHemant Agrawal int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, 957531b17a7SHemant Agrawal const struct qbman_fd *fd) 958531b17a7SHemant Agrawal { 959531b17a7SHemant Agrawal if (s->sys.eqcr_mode == qman_eqcr_vb_array) 960531b17a7SHemant Agrawal return qbman_swp_enqueue_array_mode(s, d, fd); 961531b17a7SHemant Agrawal else /* Use ring mode by default */ 962531b17a7SHemant Agrawal return qbman_swp_enqueue_ring_mode(s, d, fd); 963531b17a7SHemant Agrawal } 964531b17a7SHemant Agrawal 965293c0ca9SNipun Gupta static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, 96633ae0a29SNipun Gupta const struct qbman_eq_desc *d, 96733ae0a29SNipun Gupta const struct qbman_fd *fd, 968496324d2SNipun Gupta uint32_t *flags, 96933ae0a29SNipun Gupta int num_frames) 97033ae0a29SNipun Gupta { 971293c0ca9SNipun Gupta uint32_t *p = NULL; 97233ae0a29SNipun Gupta const uint32_t *cl = qb_cl(d); 973293c0ca9SNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 97433ae0a29SNipun Gupta int i, num_enqueued = 0; 97533ae0a29SNipun Gupta uint64_t addr_cena; 97633ae0a29SNipun Gupta 9771b49352fSHemant Agrawal half_mask = (s->eqcr.pi_ci_mask>>1); 9781b49352fSHemant Agrawal full_mask = s->eqcr.pi_ci_mask; 97933ae0a29SNipun Gupta if (!s->eqcr.available) { 98033ae0a29SNipun Gupta eqcr_ci = s->eqcr.ci; 98133ae0a29SNipun Gupta s->eqcr.ci = qbman_cena_read_reg(&s->sys, 982293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR_CI) & full_mask; 983293c0ca9SNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 98433ae0a29SNipun Gupta eqcr_ci, s->eqcr.ci); 985293c0ca9SNipun Gupta if (!s->eqcr.available) 98633ae0a29SNipun Gupta return 0; 98733ae0a29SNipun Gupta } 98833ae0a29SNipun Gupta 98933ae0a29SNipun Gupta eqcr_pi = s->eqcr.pi; 99033ae0a29SNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 99133ae0a29SNipun Gupta s->eqcr.available : num_frames; 99233ae0a29SNipun Gupta s->eqcr.available -= num_enqueued; 99333ae0a29SNipun Gupta /* Fill in the EQCR ring */ 99433ae0a29SNipun Gupta for (i = 0; i < num_enqueued; i++) { 99533ae0a29SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 996293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 99733ae0a29SNipun Gupta memcpy(&p[1], &cl[1], 28); 99833ae0a29SNipun Gupta memcpy(&p[8], &fd[i], sizeof(*fd)); 99933ae0a29SNipun Gupta eqcr_pi++; 100033ae0a29SNipun Gupta } 100133ae0a29SNipun Gupta 100233ae0a29SNipun Gupta lwsync(); 100333ae0a29SNipun Gupta 100433ae0a29SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 100533ae0a29SNipun Gupta eqcr_pi = s->eqcr.pi; 100633ae0a29SNipun Gupta for (i = 0; i < num_enqueued; i++) { 100733ae0a29SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 1008293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 100933ae0a29SNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 1010496324d2SNipun Gupta if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 1011*98cfbbbeSRohit Raj struct qbman_eq_desc *desc = (struct qbman_eq_desc *)p; 1012496324d2SNipun Gupta 1013*98cfbbbeSRohit Raj desc->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 1014496324d2SNipun Gupta ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 1015496324d2SNipun Gupta } 101633ae0a29SNipun Gupta eqcr_pi++; 1017293c0ca9SNipun Gupta if (!(eqcr_pi & half_mask)) 101833ae0a29SNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 101943f7ff9dSHaiying Wang } 102043f7ff9dSHaiying Wang 102143f7ff9dSHaiying Wang /* Flush all the cacheline without load/store in between */ 102243f7ff9dSHaiying Wang eqcr_pi = s->eqcr.pi; 10235ae1edffSHemant Agrawal addr_cena = (size_t)s->sys.addr_cena; 102443f7ff9dSHaiying Wang for (i = 0; i < num_enqueued; i++) { 1025293c0ca9SNipun Gupta dcbf((uintptr_t)(addr_cena + 1026293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask))); 102743f7ff9dSHaiying Wang eqcr_pi++; 102843f7ff9dSHaiying Wang } 1029293c0ca9SNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 103043f7ff9dSHaiying Wang 103143f7ff9dSHaiying Wang return num_enqueued; 103243f7ff9dSHaiying Wang } 103343f7ff9dSHaiying Wang 103479e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_cinh_read_direct( 103563d5d0afSNipun Gupta struct qbman_swp *s, 103663d5d0afSNipun Gupta const struct qbman_eq_desc *d, 103763d5d0afSNipun Gupta const struct qbman_fd *fd, 103863d5d0afSNipun Gupta uint32_t *flags, 103963d5d0afSNipun Gupta int num_frames) 104063d5d0afSNipun Gupta { 104163d5d0afSNipun Gupta uint32_t *p = NULL; 104263d5d0afSNipun Gupta const uint32_t *cl = qb_cl(d); 104363d5d0afSNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 104463d5d0afSNipun Gupta int i, num_enqueued = 0; 104563d5d0afSNipun Gupta uint64_t addr_cena; 104663d5d0afSNipun Gupta 104763d5d0afSNipun Gupta half_mask = (s->eqcr.pi_ci_mask>>1); 104863d5d0afSNipun Gupta full_mask = s->eqcr.pi_ci_mask; 104963d5d0afSNipun Gupta if (!s->eqcr.available) { 105063d5d0afSNipun Gupta eqcr_ci = s->eqcr.ci; 105163d5d0afSNipun Gupta s->eqcr.ci = qbman_cinh_read(&s->sys, 105263d5d0afSNipun Gupta QBMAN_CINH_SWP_EQCR_CI) & full_mask; 105363d5d0afSNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 105463d5d0afSNipun Gupta eqcr_ci, s->eqcr.ci); 105563d5d0afSNipun Gupta if (!s->eqcr.available) 105663d5d0afSNipun Gupta return 0; 105763d5d0afSNipun Gupta } 105863d5d0afSNipun Gupta 105963d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 106063d5d0afSNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 106163d5d0afSNipun Gupta s->eqcr.available : num_frames; 106263d5d0afSNipun Gupta s->eqcr.available -= num_enqueued; 106363d5d0afSNipun Gupta /* Fill in the EQCR ring */ 106463d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 106563d5d0afSNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 106663d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 106763d5d0afSNipun Gupta memcpy(&p[1], &cl[1], 28); 106863d5d0afSNipun Gupta memcpy(&p[8], &fd[i], sizeof(*fd)); 106963d5d0afSNipun Gupta eqcr_pi++; 107063d5d0afSNipun Gupta } 107163d5d0afSNipun Gupta 107263d5d0afSNipun Gupta lwsync(); 107363d5d0afSNipun Gupta 107463d5d0afSNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 107563d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 107663d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 107763d5d0afSNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 107863d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 107963d5d0afSNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 108063d5d0afSNipun Gupta if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 108163d5d0afSNipun Gupta struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 108263d5d0afSNipun Gupta 108363d5d0afSNipun Gupta d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 108463d5d0afSNipun Gupta ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 108563d5d0afSNipun Gupta } 108663d5d0afSNipun Gupta eqcr_pi++; 108763d5d0afSNipun Gupta if (!(eqcr_pi & half_mask)) 108863d5d0afSNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 108963d5d0afSNipun Gupta } 109063d5d0afSNipun Gupta 109163d5d0afSNipun Gupta /* Flush all the cacheline without load/store in between */ 109263d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 109363d5d0afSNipun Gupta addr_cena = (size_t)s->sys.addr_cena; 109463d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 109563d5d0afSNipun Gupta dcbf(addr_cena + 109663d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 109763d5d0afSNipun Gupta eqcr_pi++; 109863d5d0afSNipun Gupta } 109963d5d0afSNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 110063d5d0afSNipun Gupta 110163d5d0afSNipun Gupta return num_enqueued; 110263d5d0afSNipun Gupta } 110363d5d0afSNipun Gupta 110479e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_cinh_direct( 110579e5b5edSNipun Gupta struct qbman_swp *s, 110679e5b5edSNipun Gupta const struct qbman_eq_desc *d, 110779e5b5edSNipun Gupta const struct qbman_fd *fd, 110879e5b5edSNipun Gupta uint32_t *flags, 110979e5b5edSNipun Gupta int num_frames) 111079e5b5edSNipun Gupta { 111179e5b5edSNipun Gupta uint32_t *p = NULL; 111279e5b5edSNipun Gupta const uint32_t *cl = qb_cl(d); 111379e5b5edSNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 111479e5b5edSNipun Gupta int i, num_enqueued = 0; 111579e5b5edSNipun Gupta 111679e5b5edSNipun Gupta half_mask = (s->eqcr.pi_ci_mask>>1); 111779e5b5edSNipun Gupta full_mask = s->eqcr.pi_ci_mask; 111879e5b5edSNipun Gupta if (!s->eqcr.available) { 111979e5b5edSNipun Gupta eqcr_ci = s->eqcr.ci; 112079e5b5edSNipun Gupta s->eqcr.ci = qbman_cinh_read(&s->sys, 112179e5b5edSNipun Gupta QBMAN_CINH_SWP_EQCR_CI) & full_mask; 112279e5b5edSNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 112379e5b5edSNipun Gupta eqcr_ci, s->eqcr.ci); 112479e5b5edSNipun Gupta if (!s->eqcr.available) 112579e5b5edSNipun Gupta return 0; 112679e5b5edSNipun Gupta } 112779e5b5edSNipun Gupta 112879e5b5edSNipun Gupta eqcr_pi = s->eqcr.pi; 112979e5b5edSNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 113079e5b5edSNipun Gupta s->eqcr.available : num_frames; 113179e5b5edSNipun Gupta s->eqcr.available -= num_enqueued; 113279e5b5edSNipun Gupta /* Fill in the EQCR ring */ 113379e5b5edSNipun Gupta for (i = 0; i < num_enqueued; i++) { 113479e5b5edSNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 113579e5b5edSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 113679e5b5edSNipun Gupta memcpy_byte_by_byte(&p[1], &cl[1], 28); 113779e5b5edSNipun Gupta memcpy_byte_by_byte(&p[8], &fd[i], sizeof(*fd)); 113879e5b5edSNipun Gupta eqcr_pi++; 113979e5b5edSNipun Gupta } 114079e5b5edSNipun Gupta 114179e5b5edSNipun Gupta lwsync(); 114279e5b5edSNipun Gupta 114379e5b5edSNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 114479e5b5edSNipun Gupta eqcr_pi = s->eqcr.pi; 114579e5b5edSNipun Gupta for (i = 0; i < num_enqueued; i++) { 114679e5b5edSNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 114779e5b5edSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 114879e5b5edSNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 114979e5b5edSNipun Gupta if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 115079e5b5edSNipun Gupta struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 115179e5b5edSNipun Gupta 115279e5b5edSNipun Gupta d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 115379e5b5edSNipun Gupta ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 115479e5b5edSNipun Gupta } 115579e5b5edSNipun Gupta eqcr_pi++; 115679e5b5edSNipun Gupta if (!(eqcr_pi & half_mask)) 115779e5b5edSNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 115879e5b5edSNipun Gupta } 115979e5b5edSNipun Gupta 116079e5b5edSNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 116179e5b5edSNipun Gupta 116279e5b5edSNipun Gupta return num_enqueued; 116379e5b5edSNipun Gupta } 116479e5b5edSNipun Gupta 1165293c0ca9SNipun Gupta static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, 116643f7ff9dSHaiying Wang const struct qbman_eq_desc *d, 116743f7ff9dSHaiying Wang const struct qbman_fd *fd, 1168293c0ca9SNipun Gupta uint32_t *flags, 116943f7ff9dSHaiying Wang int num_frames) 117043f7ff9dSHaiying Wang { 1171293c0ca9SNipun Gupta uint32_t *p = NULL; 1172293c0ca9SNipun Gupta const uint32_t *cl = qb_cl(d); 1173293c0ca9SNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 117443f7ff9dSHaiying Wang int i, num_enqueued = 0; 117543f7ff9dSHaiying Wang 11761b49352fSHemant Agrawal half_mask = (s->eqcr.pi_ci_mask>>1); 11771b49352fSHemant Agrawal full_mask = s->eqcr.pi_ci_mask; 117843f7ff9dSHaiying Wang if (!s->eqcr.available) { 117943f7ff9dSHaiying Wang eqcr_ci = s->eqcr.ci; 11802557cf8fSYouri Querry s->eqcr.ci = qbman_cena_read_reg(&s->sys, 11812557cf8fSYouri Querry QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask; 1182293c0ca9SNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 118343f7ff9dSHaiying Wang eqcr_ci, s->eqcr.ci); 1184293c0ca9SNipun Gupta if (!s->eqcr.available) 118543f7ff9dSHaiying Wang return 0; 118643f7ff9dSHaiying Wang } 118743f7ff9dSHaiying Wang 118843f7ff9dSHaiying Wang eqcr_pi = s->eqcr.pi; 118943f7ff9dSHaiying Wang num_enqueued = (s->eqcr.available < num_frames) ? 119043f7ff9dSHaiying Wang s->eqcr.available : num_frames; 119143f7ff9dSHaiying Wang s->eqcr.available -= num_enqueued; 119243f7ff9dSHaiying Wang /* Fill in the EQCR ring */ 119343f7ff9dSHaiying Wang for (i = 0; i < num_enqueued; i++) { 119443f7ff9dSHaiying Wang p = qbman_cena_write_start_wo_shadow(&s->sys, 1195293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 1196293c0ca9SNipun Gupta memcpy(&p[1], &cl[1], 28); 1197293c0ca9SNipun Gupta memcpy(&p[8], &fd[i], sizeof(*fd)); 11988bd11d45SYouri Querry p[0] = cl[0] | s->eqcr.pi_vb; 11998bd11d45SYouri Querry 1200293c0ca9SNipun Gupta if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 1201293c0ca9SNipun Gupta struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 1202293c0ca9SNipun Gupta 1203293c0ca9SNipun Gupta d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 1204293c0ca9SNipun Gupta ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 1205293c0ca9SNipun Gupta } 1206293c0ca9SNipun Gupta eqcr_pi++; 12071b49352fSHemant Agrawal 1208293c0ca9SNipun Gupta if (!(eqcr_pi & half_mask)) 1209293c0ca9SNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 1210293c0ca9SNipun Gupta } 1211293c0ca9SNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 1212293c0ca9SNipun Gupta 1213293c0ca9SNipun Gupta dma_wmb(); 1214293c0ca9SNipun Gupta qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI, 1215293c0ca9SNipun Gupta (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); 1216293c0ca9SNipun Gupta return num_enqueued; 1217293c0ca9SNipun Gupta } 1218293c0ca9SNipun Gupta 12190ff708edSFerruh Yigit int qbman_swp_enqueue_multiple(struct qbman_swp *s, 1220293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 1221293c0ca9SNipun Gupta const struct qbman_fd *fd, 1222293c0ca9SNipun Gupta uint32_t *flags, 1223293c0ca9SNipun Gupta int num_frames) 1224293c0ca9SNipun Gupta { 1225b3bd7a50SNipun Gupta if (!s->stash_off) 1226b3bd7a50SNipun Gupta return qbman_swp_enqueue_multiple_ptr(s, d, fd, flags, 1227b3bd7a50SNipun Gupta num_frames); 1228b3bd7a50SNipun Gupta else 1229b3bd7a50SNipun Gupta return qbman_swp_enqueue_multiple_cinh_direct(s, d, fd, flags, 1230b3bd7a50SNipun Gupta num_frames); 1231293c0ca9SNipun Gupta } 1232293c0ca9SNipun Gupta 1233a3a997f0SHemant Agrawal static int qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp *s, 1234a3a997f0SHemant Agrawal const struct qbman_eq_desc *d, 1235a3a997f0SHemant Agrawal struct qbman_fd **fd, 1236a3a997f0SHemant Agrawal uint32_t *flags, 1237a3a997f0SHemant Agrawal int num_frames) 1238a3a997f0SHemant Agrawal { 1239a3a997f0SHemant Agrawal uint32_t *p = NULL; 1240a3a997f0SHemant Agrawal const uint32_t *cl = qb_cl(d); 1241a3a997f0SHemant Agrawal uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 1242a3a997f0SHemant Agrawal int i, num_enqueued = 0; 1243a3a997f0SHemant Agrawal uint64_t addr_cena; 1244a3a997f0SHemant Agrawal 1245a3a997f0SHemant Agrawal half_mask = (s->eqcr.pi_ci_mask>>1); 1246a3a997f0SHemant Agrawal full_mask = s->eqcr.pi_ci_mask; 1247a3a997f0SHemant Agrawal if (!s->eqcr.available) { 1248a3a997f0SHemant Agrawal eqcr_ci = s->eqcr.ci; 1249a3a997f0SHemant Agrawal s->eqcr.ci = qbman_cena_read_reg(&s->sys, 1250a3a997f0SHemant Agrawal QBMAN_CENA_SWP_EQCR_CI) & full_mask; 1251a3a997f0SHemant Agrawal s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 1252a3a997f0SHemant Agrawal eqcr_ci, s->eqcr.ci); 1253a3a997f0SHemant Agrawal if (!s->eqcr.available) 1254a3a997f0SHemant Agrawal return 0; 1255a3a997f0SHemant Agrawal } 1256a3a997f0SHemant Agrawal 1257a3a997f0SHemant Agrawal eqcr_pi = s->eqcr.pi; 1258a3a997f0SHemant Agrawal num_enqueued = (s->eqcr.available < num_frames) ? 1259a3a997f0SHemant Agrawal s->eqcr.available : num_frames; 1260a3a997f0SHemant Agrawal s->eqcr.available -= num_enqueued; 1261a3a997f0SHemant Agrawal /* Fill in the EQCR ring */ 1262a3a997f0SHemant Agrawal for (i = 0; i < num_enqueued; i++) { 1263a3a997f0SHemant Agrawal p = qbman_cena_write_start_wo_shadow(&s->sys, 1264a3a997f0SHemant Agrawal QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 1265a3a997f0SHemant Agrawal memcpy(&p[1], &cl[1], 28); 1266a3a997f0SHemant Agrawal memcpy(&p[8], fd[i], sizeof(struct qbman_fd)); 1267a3a997f0SHemant Agrawal eqcr_pi++; 1268a3a997f0SHemant Agrawal } 1269a3a997f0SHemant Agrawal 1270a3a997f0SHemant Agrawal lwsync(); 1271a3a997f0SHemant Agrawal 1272a3a997f0SHemant Agrawal /* Set the verb byte, have to substitute in the valid-bit */ 1273a3a997f0SHemant Agrawal eqcr_pi = s->eqcr.pi; 1274a3a997f0SHemant Agrawal for (i = 0; i < num_enqueued; i++) { 1275a3a997f0SHemant Agrawal p = qbman_cena_write_start_wo_shadow(&s->sys, 1276a3a997f0SHemant Agrawal QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 1277a3a997f0SHemant Agrawal p[0] = cl[0] | s->eqcr.pi_vb; 1278a3a997f0SHemant Agrawal if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 1279a3a997f0SHemant Agrawal struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 1280a3a997f0SHemant Agrawal 1281a3a997f0SHemant Agrawal d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 1282a3a997f0SHemant Agrawal ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 1283a3a997f0SHemant Agrawal } 1284a3a997f0SHemant Agrawal eqcr_pi++; 1285a3a997f0SHemant Agrawal if (!(eqcr_pi & half_mask)) 1286a3a997f0SHemant Agrawal s->eqcr.pi_vb ^= QB_VALID_BIT; 1287a3a997f0SHemant Agrawal } 1288a3a997f0SHemant Agrawal 1289a3a997f0SHemant Agrawal /* Flush all the cacheline without load/store in between */ 1290a3a997f0SHemant Agrawal eqcr_pi = s->eqcr.pi; 1291a3a997f0SHemant Agrawal addr_cena = (size_t)s->sys.addr_cena; 1292a3a997f0SHemant Agrawal for (i = 0; i < num_enqueued; i++) { 1293a3a997f0SHemant Agrawal dcbf(addr_cena + 1294a3a997f0SHemant Agrawal QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 1295a3a997f0SHemant Agrawal eqcr_pi++; 1296a3a997f0SHemant Agrawal } 1297a3a997f0SHemant Agrawal s->eqcr.pi = eqcr_pi & full_mask; 1298a3a997f0SHemant Agrawal 1299a3a997f0SHemant Agrawal return num_enqueued; 1300a3a997f0SHemant Agrawal } 1301a3a997f0SHemant Agrawal 130279e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_fd_cinh_read_direct( 130363d5d0afSNipun Gupta struct qbman_swp *s, 130463d5d0afSNipun Gupta const struct qbman_eq_desc *d, 130563d5d0afSNipun Gupta struct qbman_fd **fd, 130663d5d0afSNipun Gupta uint32_t *flags, 130763d5d0afSNipun Gupta int num_frames) 130863d5d0afSNipun Gupta { 130963d5d0afSNipun Gupta uint32_t *p = NULL; 131063d5d0afSNipun Gupta const uint32_t *cl = qb_cl(d); 131163d5d0afSNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 131263d5d0afSNipun Gupta int i, num_enqueued = 0; 131363d5d0afSNipun Gupta uint64_t addr_cena; 131463d5d0afSNipun Gupta 131563d5d0afSNipun Gupta half_mask = (s->eqcr.pi_ci_mask>>1); 131663d5d0afSNipun Gupta full_mask = s->eqcr.pi_ci_mask; 131763d5d0afSNipun Gupta if (!s->eqcr.available) { 131863d5d0afSNipun Gupta eqcr_ci = s->eqcr.ci; 131963d5d0afSNipun Gupta s->eqcr.ci = qbman_cinh_read(&s->sys, 132063d5d0afSNipun Gupta QBMAN_CINH_SWP_EQCR_CI) & full_mask; 132163d5d0afSNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 132263d5d0afSNipun Gupta eqcr_ci, s->eqcr.ci); 132363d5d0afSNipun Gupta if (!s->eqcr.available) 132463d5d0afSNipun Gupta return 0; 132563d5d0afSNipun Gupta } 132663d5d0afSNipun Gupta 132763d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 132863d5d0afSNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 132963d5d0afSNipun Gupta s->eqcr.available : num_frames; 133063d5d0afSNipun Gupta s->eqcr.available -= num_enqueued; 133163d5d0afSNipun Gupta /* Fill in the EQCR ring */ 133263d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 133363d5d0afSNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 133463d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 133563d5d0afSNipun Gupta memcpy(&p[1], &cl[1], 28); 133663d5d0afSNipun Gupta memcpy(&p[8], fd[i], sizeof(struct qbman_fd)); 133763d5d0afSNipun Gupta eqcr_pi++; 133863d5d0afSNipun Gupta } 133963d5d0afSNipun Gupta 134063d5d0afSNipun Gupta lwsync(); 134163d5d0afSNipun Gupta 134263d5d0afSNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 134363d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 134463d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 134563d5d0afSNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 134663d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 134763d5d0afSNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 134863d5d0afSNipun Gupta if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 134963d5d0afSNipun Gupta struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 135063d5d0afSNipun Gupta 135163d5d0afSNipun Gupta d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 135263d5d0afSNipun Gupta ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 135363d5d0afSNipun Gupta } 135463d5d0afSNipun Gupta eqcr_pi++; 135563d5d0afSNipun Gupta if (!(eqcr_pi & half_mask)) 135663d5d0afSNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 135763d5d0afSNipun Gupta } 135863d5d0afSNipun Gupta 135963d5d0afSNipun Gupta /* Flush all the cacheline without load/store in between */ 136063d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 136163d5d0afSNipun Gupta addr_cena = (size_t)s->sys.addr_cena; 136263d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 136363d5d0afSNipun Gupta dcbf(addr_cena + 136463d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 136563d5d0afSNipun Gupta eqcr_pi++; 136663d5d0afSNipun Gupta } 136763d5d0afSNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 136863d5d0afSNipun Gupta 136963d5d0afSNipun Gupta return num_enqueued; 137063d5d0afSNipun Gupta } 137163d5d0afSNipun Gupta 137279e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_fd_cinh_direct( 137379e5b5edSNipun Gupta struct qbman_swp *s, 137479e5b5edSNipun Gupta const struct qbman_eq_desc *d, 137579e5b5edSNipun Gupta struct qbman_fd **fd, 137679e5b5edSNipun Gupta uint32_t *flags, 137779e5b5edSNipun Gupta int num_frames) 137879e5b5edSNipun Gupta { 137979e5b5edSNipun Gupta uint32_t *p = NULL; 138079e5b5edSNipun Gupta const uint32_t *cl = qb_cl(d); 138179e5b5edSNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 138279e5b5edSNipun Gupta int i, num_enqueued = 0; 138379e5b5edSNipun Gupta 138479e5b5edSNipun Gupta half_mask = (s->eqcr.pi_ci_mask>>1); 138579e5b5edSNipun Gupta full_mask = s->eqcr.pi_ci_mask; 138679e5b5edSNipun Gupta if (!s->eqcr.available) { 138779e5b5edSNipun Gupta eqcr_ci = s->eqcr.ci; 138879e5b5edSNipun Gupta s->eqcr.ci = qbman_cinh_read(&s->sys, 138979e5b5edSNipun Gupta QBMAN_CINH_SWP_EQCR_CI) & full_mask; 139079e5b5edSNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 139179e5b5edSNipun Gupta eqcr_ci, s->eqcr.ci); 139279e5b5edSNipun Gupta if (!s->eqcr.available) 139379e5b5edSNipun Gupta return 0; 139479e5b5edSNipun Gupta } 139579e5b5edSNipun Gupta 139679e5b5edSNipun Gupta eqcr_pi = s->eqcr.pi; 139779e5b5edSNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 139879e5b5edSNipun Gupta s->eqcr.available : num_frames; 139979e5b5edSNipun Gupta s->eqcr.available -= num_enqueued; 140079e5b5edSNipun Gupta /* Fill in the EQCR ring */ 140179e5b5edSNipun Gupta for (i = 0; i < num_enqueued; i++) { 140279e5b5edSNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 140379e5b5edSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 140479e5b5edSNipun Gupta memcpy_byte_by_byte(&p[1], &cl[1], 28); 140579e5b5edSNipun Gupta memcpy_byte_by_byte(&p[8], fd[i], sizeof(struct qbman_fd)); 140679e5b5edSNipun Gupta eqcr_pi++; 140779e5b5edSNipun Gupta } 140879e5b5edSNipun Gupta 140979e5b5edSNipun Gupta lwsync(); 141079e5b5edSNipun Gupta 141179e5b5edSNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 141279e5b5edSNipun Gupta eqcr_pi = s->eqcr.pi; 141379e5b5edSNipun Gupta for (i = 0; i < num_enqueued; i++) { 141479e5b5edSNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 141579e5b5edSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 141679e5b5edSNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 141779e5b5edSNipun Gupta if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 141879e5b5edSNipun Gupta struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 141979e5b5edSNipun Gupta 142079e5b5edSNipun Gupta d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 142179e5b5edSNipun Gupta ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 142279e5b5edSNipun Gupta } 142379e5b5edSNipun Gupta eqcr_pi++; 142479e5b5edSNipun Gupta if (!(eqcr_pi & half_mask)) 142579e5b5edSNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 142679e5b5edSNipun Gupta } 142779e5b5edSNipun Gupta 142879e5b5edSNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 142979e5b5edSNipun Gupta 143079e5b5edSNipun Gupta return num_enqueued; 143179e5b5edSNipun Gupta } 143279e5b5edSNipun Gupta 1433a3a997f0SHemant Agrawal static int qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp *s, 1434a3a997f0SHemant Agrawal const struct qbman_eq_desc *d, 1435a3a997f0SHemant Agrawal struct qbman_fd **fd, 1436a3a997f0SHemant Agrawal uint32_t *flags, 1437a3a997f0SHemant Agrawal int num_frames) 1438a3a997f0SHemant Agrawal { 1439a3a997f0SHemant Agrawal uint32_t *p = NULL; 1440a3a997f0SHemant Agrawal const uint32_t *cl = qb_cl(d); 1441a3a997f0SHemant Agrawal uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 1442a3a997f0SHemant Agrawal int i, num_enqueued = 0; 1443a3a997f0SHemant Agrawal 1444a3a997f0SHemant Agrawal half_mask = (s->eqcr.pi_ci_mask>>1); 1445a3a997f0SHemant Agrawal full_mask = s->eqcr.pi_ci_mask; 1446a3a997f0SHemant Agrawal if (!s->eqcr.available) { 1447a3a997f0SHemant Agrawal eqcr_ci = s->eqcr.ci; 1448a3a997f0SHemant Agrawal s->eqcr.ci = qbman_cena_read_reg(&s->sys, 1449a3a997f0SHemant Agrawal QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask; 1450a3a997f0SHemant Agrawal s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 1451a3a997f0SHemant Agrawal eqcr_ci, s->eqcr.ci); 1452a3a997f0SHemant Agrawal if (!s->eqcr.available) 1453a3a997f0SHemant Agrawal return 0; 1454a3a997f0SHemant Agrawal } 1455a3a997f0SHemant Agrawal 1456a3a997f0SHemant Agrawal eqcr_pi = s->eqcr.pi; 1457a3a997f0SHemant Agrawal num_enqueued = (s->eqcr.available < num_frames) ? 1458a3a997f0SHemant Agrawal s->eqcr.available : num_frames; 1459a3a997f0SHemant Agrawal s->eqcr.available -= num_enqueued; 1460a3a997f0SHemant Agrawal /* Fill in the EQCR ring */ 1461a3a997f0SHemant Agrawal for (i = 0; i < num_enqueued; i++) { 1462a3a997f0SHemant Agrawal p = qbman_cena_write_start_wo_shadow(&s->sys, 1463a3a997f0SHemant Agrawal QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 1464a3a997f0SHemant Agrawal memcpy(&p[1], &cl[1], 28); 1465a3a997f0SHemant Agrawal memcpy(&p[8], fd[i], sizeof(struct qbman_fd)); 1466a3a997f0SHemant Agrawal eqcr_pi++; 1467a3a997f0SHemant Agrawal } 1468a3a997f0SHemant Agrawal 1469a3a997f0SHemant Agrawal /* Set the verb byte, have to substitute in the valid-bit */ 1470a3a997f0SHemant Agrawal eqcr_pi = s->eqcr.pi; 1471a3a997f0SHemant Agrawal for (i = 0; i < num_enqueued; i++) { 1472a3a997f0SHemant Agrawal p = qbman_cena_write_start_wo_shadow(&s->sys, 1473a3a997f0SHemant Agrawal QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 1474a3a997f0SHemant Agrawal p[0] = cl[0] | s->eqcr.pi_vb; 1475a3a997f0SHemant Agrawal if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 1476a3a997f0SHemant Agrawal struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 1477a3a997f0SHemant Agrawal 1478a3a997f0SHemant Agrawal d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 1479a3a997f0SHemant Agrawal ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 1480a3a997f0SHemant Agrawal } 1481a3a997f0SHemant Agrawal eqcr_pi++; 1482a3a997f0SHemant Agrawal if (!(eqcr_pi & half_mask)) 1483a3a997f0SHemant Agrawal s->eqcr.pi_vb ^= QB_VALID_BIT; 1484a3a997f0SHemant Agrawal } 1485a3a997f0SHemant Agrawal s->eqcr.pi = eqcr_pi & full_mask; 1486a3a997f0SHemant Agrawal 1487a3a997f0SHemant Agrawal dma_wmb(); 1488a3a997f0SHemant Agrawal qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI, 1489a3a997f0SHemant Agrawal (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); 1490a3a997f0SHemant Agrawal return num_enqueued; 1491a3a997f0SHemant Agrawal } 1492a3a997f0SHemant Agrawal 14930ff708edSFerruh Yigit int qbman_swp_enqueue_multiple_fd(struct qbman_swp *s, 1494a3a997f0SHemant Agrawal const struct qbman_eq_desc *d, 1495a3a997f0SHemant Agrawal struct qbman_fd **fd, 1496a3a997f0SHemant Agrawal uint32_t *flags, 1497a3a997f0SHemant Agrawal int num_frames) 1498a3a997f0SHemant Agrawal { 1499b3bd7a50SNipun Gupta if (!s->stash_off) 1500b3bd7a50SNipun Gupta return qbman_swp_enqueue_multiple_fd_ptr(s, d, fd, flags, 1501b3bd7a50SNipun Gupta num_frames); 1502b3bd7a50SNipun Gupta else 1503b3bd7a50SNipun Gupta return qbman_swp_enqueue_multiple_fd_cinh_direct(s, d, fd, 1504b3bd7a50SNipun Gupta flags, num_frames); 1505a3a997f0SHemant Agrawal } 1506a3a997f0SHemant Agrawal 1507293c0ca9SNipun Gupta static int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, 1508293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 1509293c0ca9SNipun Gupta const struct qbman_fd *fd, 1510293c0ca9SNipun Gupta int num_frames) 1511293c0ca9SNipun Gupta { 1512293c0ca9SNipun Gupta uint32_t *p; 1513293c0ca9SNipun Gupta const uint32_t *cl; 1514293c0ca9SNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 1515293c0ca9SNipun Gupta int i, num_enqueued = 0; 1516293c0ca9SNipun Gupta uint64_t addr_cena; 1517293c0ca9SNipun Gupta 15181b49352fSHemant Agrawal half_mask = (s->eqcr.pi_ci_mask>>1); 15191b49352fSHemant Agrawal full_mask = s->eqcr.pi_ci_mask; 1520293c0ca9SNipun Gupta if (!s->eqcr.available) { 1521293c0ca9SNipun Gupta eqcr_ci = s->eqcr.ci; 1522293c0ca9SNipun Gupta s->eqcr.ci = qbman_cena_read_reg(&s->sys, 1523293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR_CI) & full_mask; 1524293c0ca9SNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 1525293c0ca9SNipun Gupta eqcr_ci, s->eqcr.ci); 1526293c0ca9SNipun Gupta if (!s->eqcr.available) 1527293c0ca9SNipun Gupta return 0; 1528293c0ca9SNipun Gupta } 1529293c0ca9SNipun Gupta 1530293c0ca9SNipun Gupta eqcr_pi = s->eqcr.pi; 1531293c0ca9SNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 1532293c0ca9SNipun Gupta s->eqcr.available : num_frames; 1533293c0ca9SNipun Gupta s->eqcr.available -= num_enqueued; 1534293c0ca9SNipun Gupta /* Fill in the EQCR ring */ 1535293c0ca9SNipun Gupta for (i = 0; i < num_enqueued; i++) { 1536293c0ca9SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 1537293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 153843f7ff9dSHaiying Wang cl = qb_cl(&d[i]); 153943f7ff9dSHaiying Wang memcpy(&p[1], &cl[1], 28); 154043f7ff9dSHaiying Wang memcpy(&p[8], &fd[i], sizeof(*fd)); 154143f7ff9dSHaiying Wang eqcr_pi++; 154243f7ff9dSHaiying Wang } 154343f7ff9dSHaiying Wang 154443f7ff9dSHaiying Wang lwsync(); 154543f7ff9dSHaiying Wang 154643f7ff9dSHaiying Wang /* Set the verb byte, have to substitute in the valid-bit */ 154743f7ff9dSHaiying Wang eqcr_pi = s->eqcr.pi; 154843f7ff9dSHaiying Wang for (i = 0; i < num_enqueued; i++) { 154943f7ff9dSHaiying Wang p = qbman_cena_write_start_wo_shadow(&s->sys, 1550293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 155143f7ff9dSHaiying Wang cl = qb_cl(&d[i]); 155243f7ff9dSHaiying Wang p[0] = cl[0] | s->eqcr.pi_vb; 155343f7ff9dSHaiying Wang eqcr_pi++; 1554293c0ca9SNipun Gupta if (!(eqcr_pi & half_mask)) 155543f7ff9dSHaiying Wang s->eqcr.pi_vb ^= QB_VALID_BIT; 155633ae0a29SNipun Gupta } 155733ae0a29SNipun Gupta 155833ae0a29SNipun Gupta /* Flush all the cacheline without load/store in between */ 155933ae0a29SNipun Gupta eqcr_pi = s->eqcr.pi; 15605ae1edffSHemant Agrawal addr_cena = (size_t)s->sys.addr_cena; 156133ae0a29SNipun Gupta for (i = 0; i < num_enqueued; i++) { 1562293c0ca9SNipun Gupta dcbf((uintptr_t)(addr_cena + 1563293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask))); 156433ae0a29SNipun Gupta eqcr_pi++; 156533ae0a29SNipun Gupta } 1566293c0ca9SNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 156733ae0a29SNipun Gupta 156833ae0a29SNipun Gupta return num_enqueued; 156933ae0a29SNipun Gupta } 157033ae0a29SNipun Gupta 157179e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_desc_cinh_read_direct( 157263d5d0afSNipun Gupta struct qbman_swp *s, 157363d5d0afSNipun Gupta const struct qbman_eq_desc *d, 157463d5d0afSNipun Gupta const struct qbman_fd *fd, 157563d5d0afSNipun Gupta int num_frames) 157663d5d0afSNipun Gupta { 157763d5d0afSNipun Gupta uint32_t *p; 157863d5d0afSNipun Gupta const uint32_t *cl; 157963d5d0afSNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 158063d5d0afSNipun Gupta int i, num_enqueued = 0; 158163d5d0afSNipun Gupta uint64_t addr_cena; 158263d5d0afSNipun Gupta 158363d5d0afSNipun Gupta half_mask = (s->eqcr.pi_ci_mask>>1); 158463d5d0afSNipun Gupta full_mask = s->eqcr.pi_ci_mask; 158563d5d0afSNipun Gupta if (!s->eqcr.available) { 158663d5d0afSNipun Gupta eqcr_ci = s->eqcr.ci; 158763d5d0afSNipun Gupta s->eqcr.ci = qbman_cinh_read(&s->sys, 158863d5d0afSNipun Gupta QBMAN_CINH_SWP_EQCR_CI) & full_mask; 158963d5d0afSNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 159063d5d0afSNipun Gupta eqcr_ci, s->eqcr.ci); 159163d5d0afSNipun Gupta if (!s->eqcr.available) 159263d5d0afSNipun Gupta return 0; 159363d5d0afSNipun Gupta } 159463d5d0afSNipun Gupta 159563d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 159663d5d0afSNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 159763d5d0afSNipun Gupta s->eqcr.available : num_frames; 159863d5d0afSNipun Gupta s->eqcr.available -= num_enqueued; 159963d5d0afSNipun Gupta /* Fill in the EQCR ring */ 160063d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 160163d5d0afSNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 160263d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 160363d5d0afSNipun Gupta cl = qb_cl(&d[i]); 160463d5d0afSNipun Gupta memcpy(&p[1], &cl[1], 28); 160563d5d0afSNipun Gupta memcpy(&p[8], &fd[i], sizeof(*fd)); 160663d5d0afSNipun Gupta eqcr_pi++; 160763d5d0afSNipun Gupta } 160863d5d0afSNipun Gupta 160963d5d0afSNipun Gupta lwsync(); 161063d5d0afSNipun Gupta 161163d5d0afSNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 161263d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 161363d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 161463d5d0afSNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 161563d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 161663d5d0afSNipun Gupta cl = qb_cl(&d[i]); 161763d5d0afSNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 161863d5d0afSNipun Gupta eqcr_pi++; 161963d5d0afSNipun Gupta if (!(eqcr_pi & half_mask)) 162063d5d0afSNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 162163d5d0afSNipun Gupta } 162263d5d0afSNipun Gupta 162363d5d0afSNipun Gupta /* Flush all the cacheline without load/store in between */ 162463d5d0afSNipun Gupta eqcr_pi = s->eqcr.pi; 162563d5d0afSNipun Gupta addr_cena = (size_t)s->sys.addr_cena; 162663d5d0afSNipun Gupta for (i = 0; i < num_enqueued; i++) { 162763d5d0afSNipun Gupta dcbf(addr_cena + 162863d5d0afSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 162963d5d0afSNipun Gupta eqcr_pi++; 163063d5d0afSNipun Gupta } 163163d5d0afSNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 163263d5d0afSNipun Gupta 163363d5d0afSNipun Gupta return num_enqueued; 163463d5d0afSNipun Gupta } 163563d5d0afSNipun Gupta 163679e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_desc_cinh_direct( 163779e5b5edSNipun Gupta struct qbman_swp *s, 163879e5b5edSNipun Gupta const struct qbman_eq_desc *d, 163979e5b5edSNipun Gupta const struct qbman_fd *fd, 164079e5b5edSNipun Gupta int num_frames) 164179e5b5edSNipun Gupta { 164279e5b5edSNipun Gupta uint32_t *p; 164379e5b5edSNipun Gupta const uint32_t *cl; 164479e5b5edSNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 164579e5b5edSNipun Gupta int i, num_enqueued = 0; 164679e5b5edSNipun Gupta 164779e5b5edSNipun Gupta half_mask = (s->eqcr.pi_ci_mask>>1); 164879e5b5edSNipun Gupta full_mask = s->eqcr.pi_ci_mask; 164979e5b5edSNipun Gupta if (!s->eqcr.available) { 165079e5b5edSNipun Gupta eqcr_ci = s->eqcr.ci; 165179e5b5edSNipun Gupta s->eqcr.ci = qbman_cinh_read(&s->sys, 165279e5b5edSNipun Gupta QBMAN_CINH_SWP_EQCR_CI) & full_mask; 165379e5b5edSNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 165479e5b5edSNipun Gupta eqcr_ci, s->eqcr.ci); 165579e5b5edSNipun Gupta if (!s->eqcr.available) 165679e5b5edSNipun Gupta return 0; 165779e5b5edSNipun Gupta } 165879e5b5edSNipun Gupta 165979e5b5edSNipun Gupta eqcr_pi = s->eqcr.pi; 166079e5b5edSNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 166179e5b5edSNipun Gupta s->eqcr.available : num_frames; 166279e5b5edSNipun Gupta s->eqcr.available -= num_enqueued; 166379e5b5edSNipun Gupta /* Fill in the EQCR ring */ 166479e5b5edSNipun Gupta for (i = 0; i < num_enqueued; i++) { 166579e5b5edSNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 166679e5b5edSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 166779e5b5edSNipun Gupta cl = qb_cl(&d[i]); 166879e5b5edSNipun Gupta memcpy_byte_by_byte(&p[1], &cl[1], 28); 166979e5b5edSNipun Gupta memcpy_byte_by_byte(&p[8], &fd[i], sizeof(*fd)); 167079e5b5edSNipun Gupta eqcr_pi++; 167179e5b5edSNipun Gupta } 167279e5b5edSNipun Gupta 167379e5b5edSNipun Gupta lwsync(); 167479e5b5edSNipun Gupta 167579e5b5edSNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 167679e5b5edSNipun Gupta eqcr_pi = s->eqcr.pi; 167779e5b5edSNipun Gupta for (i = 0; i < num_enqueued; i++) { 167879e5b5edSNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 167979e5b5edSNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 168079e5b5edSNipun Gupta cl = qb_cl(&d[i]); 168179e5b5edSNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 168279e5b5edSNipun Gupta eqcr_pi++; 168379e5b5edSNipun Gupta if (!(eqcr_pi & half_mask)) 168479e5b5edSNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 168579e5b5edSNipun Gupta } 168679e5b5edSNipun Gupta 168779e5b5edSNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 168879e5b5edSNipun Gupta 168979e5b5edSNipun Gupta return num_enqueued; 169079e5b5edSNipun Gupta } 169179e5b5edSNipun Gupta 1692293c0ca9SNipun Gupta static int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, 1693293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 1694293c0ca9SNipun Gupta const struct qbman_fd *fd, 1695293c0ca9SNipun Gupta int num_frames) 1696293c0ca9SNipun Gupta { 1697293c0ca9SNipun Gupta uint32_t *p; 1698293c0ca9SNipun Gupta const uint32_t *cl; 1699293c0ca9SNipun Gupta uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 1700293c0ca9SNipun Gupta int i, num_enqueued = 0; 1701293c0ca9SNipun Gupta 17021b49352fSHemant Agrawal half_mask = (s->eqcr.pi_ci_mask>>1); 17031b49352fSHemant Agrawal full_mask = s->eqcr.pi_ci_mask; 1704293c0ca9SNipun Gupta if (!s->eqcr.available) { 1705293c0ca9SNipun Gupta eqcr_ci = s->eqcr.ci; 17062557cf8fSYouri Querry s->eqcr.ci = qbman_cena_read_reg(&s->sys, 17072557cf8fSYouri Querry QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask; 1708293c0ca9SNipun Gupta s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 1709293c0ca9SNipun Gupta eqcr_ci, s->eqcr.ci); 1710293c0ca9SNipun Gupta if (!s->eqcr.available) 1711293c0ca9SNipun Gupta return 0; 1712293c0ca9SNipun Gupta } 1713293c0ca9SNipun Gupta 1714293c0ca9SNipun Gupta eqcr_pi = s->eqcr.pi; 1715293c0ca9SNipun Gupta num_enqueued = (s->eqcr.available < num_frames) ? 1716293c0ca9SNipun Gupta s->eqcr.available : num_frames; 1717293c0ca9SNipun Gupta s->eqcr.available -= num_enqueued; 1718293c0ca9SNipun Gupta /* Fill in the EQCR ring */ 1719293c0ca9SNipun Gupta for (i = 0; i < num_enqueued; i++) { 1720293c0ca9SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 1721293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 1722293c0ca9SNipun Gupta cl = qb_cl(&d[i]); 1723293c0ca9SNipun Gupta memcpy(&p[1], &cl[1], 28); 1724293c0ca9SNipun Gupta memcpy(&p[8], &fd[i], sizeof(*fd)); 1725293c0ca9SNipun Gupta eqcr_pi++; 1726293c0ca9SNipun Gupta } 1727293c0ca9SNipun Gupta 1728293c0ca9SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 1729293c0ca9SNipun Gupta eqcr_pi = s->eqcr.pi; 1730293c0ca9SNipun Gupta for (i = 0; i < num_enqueued; i++) { 1731293c0ca9SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 1732293c0ca9SNipun Gupta QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 1733293c0ca9SNipun Gupta cl = qb_cl(&d[i]); 1734293c0ca9SNipun Gupta p[0] = cl[0] | s->eqcr.pi_vb; 1735293c0ca9SNipun Gupta eqcr_pi++; 1736293c0ca9SNipun Gupta if (!(eqcr_pi & half_mask)) 1737293c0ca9SNipun Gupta s->eqcr.pi_vb ^= QB_VALID_BIT; 1738293c0ca9SNipun Gupta } 1739293c0ca9SNipun Gupta 1740293c0ca9SNipun Gupta s->eqcr.pi = eqcr_pi & full_mask; 1741293c0ca9SNipun Gupta 1742293c0ca9SNipun Gupta dma_wmb(); 1743293c0ca9SNipun Gupta qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI, 1744293c0ca9SNipun Gupta (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); 1745293c0ca9SNipun Gupta 1746293c0ca9SNipun Gupta return num_enqueued; 1747293c0ca9SNipun Gupta } 17480ff708edSFerruh Yigit int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s, 1749293c0ca9SNipun Gupta const struct qbman_eq_desc *d, 1750293c0ca9SNipun Gupta const struct qbman_fd *fd, 1751293c0ca9SNipun Gupta int num_frames) 1752293c0ca9SNipun Gupta { 1753b3bd7a50SNipun Gupta if (!s->stash_off) 1754b3bd7a50SNipun Gupta return qbman_swp_enqueue_multiple_desc_ptr(s, d, fd, 1755b3bd7a50SNipun Gupta num_frames); 1756b3bd7a50SNipun Gupta else 1757b3bd7a50SNipun Gupta return qbman_swp_enqueue_multiple_desc_cinh_direct(s, d, fd, 1758b3bd7a50SNipun Gupta num_frames); 1759b3bd7a50SNipun Gupta 1760293c0ca9SNipun Gupta } 1761293c0ca9SNipun Gupta 1762531b17a7SHemant Agrawal /*************************/ 1763531b17a7SHemant Agrawal /* Static (push) dequeue */ 1764531b17a7SHemant Agrawal /*************************/ 1765531b17a7SHemant Agrawal 1766531b17a7SHemant Agrawal void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled) 1767531b17a7SHemant Agrawal { 176869293c77SHemant Agrawal uint16_t src = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK; 1769531b17a7SHemant Agrawal 1770531b17a7SHemant Agrawal QBMAN_BUG_ON(channel_idx > 15); 177169293c77SHemant Agrawal *enabled = src | (1 << channel_idx); 1772531b17a7SHemant Agrawal } 1773531b17a7SHemant Agrawal 1774531b17a7SHemant Agrawal void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable) 1775531b17a7SHemant Agrawal { 1776531b17a7SHemant Agrawal uint16_t dqsrc; 1777531b17a7SHemant Agrawal 1778531b17a7SHemant Agrawal QBMAN_BUG_ON(channel_idx > 15); 177969293c77SHemant Agrawal if (enable) 178069293c77SHemant Agrawal s->sdq |= 1 << channel_idx; 178169293c77SHemant Agrawal else 178269293c77SHemant Agrawal s->sdq &= ~(1 << channel_idx); 178369293c77SHemant Agrawal 1784531b17a7SHemant Agrawal /* Read make the complete src map. If no channels are enabled 1785531b17a7SHemant Agrawal * the SDQCR must be 0 or else QMan will assert errors 1786531b17a7SHemant Agrawal */ 178769293c77SHemant Agrawal dqsrc = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK; 1788531b17a7SHemant Agrawal if (dqsrc != 0) 1789531b17a7SHemant Agrawal qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, s->sdq); 1790531b17a7SHemant Agrawal else 1791531b17a7SHemant Agrawal qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, 0); 1792531b17a7SHemant Agrawal } 1793531b17a7SHemant Agrawal 1794531b17a7SHemant Agrawal /***************************/ 1795531b17a7SHemant Agrawal /* Volatile (pull) dequeue */ 1796531b17a7SHemant Agrawal /***************************/ 1797531b17a7SHemant Agrawal 1798531b17a7SHemant Agrawal /* These should be const, eventually */ 179969293c77SHemant Agrawal #define QB_VDQCR_VERB_DCT_SHIFT 0 180069293c77SHemant Agrawal #define QB_VDQCR_VERB_DT_SHIFT 2 180169293c77SHemant Agrawal #define QB_VDQCR_VERB_RLS_SHIFT 4 180269293c77SHemant Agrawal #define QB_VDQCR_VERB_WAE_SHIFT 5 1803293c0ca9SNipun Gupta #define QB_VDQCR_VERB_RAD_SHIFT 6 1804531b17a7SHemant Agrawal 1805531b17a7SHemant Agrawal enum qb_pull_dt_e { 1806531b17a7SHemant Agrawal qb_pull_dt_channel, 1807531b17a7SHemant Agrawal qb_pull_dt_workqueue, 1808531b17a7SHemant Agrawal qb_pull_dt_framequeue 1809531b17a7SHemant Agrawal }; 1810531b17a7SHemant Agrawal 1811531b17a7SHemant Agrawal void qbman_pull_desc_clear(struct qbman_pull_desc *d) 1812531b17a7SHemant Agrawal { 1813531b17a7SHemant Agrawal memset(d, 0, sizeof(*d)); 1814531b17a7SHemant Agrawal } 1815531b17a7SHemant Agrawal 1816531b17a7SHemant Agrawal void qbman_pull_desc_set_storage(struct qbman_pull_desc *d, 1817531b17a7SHemant Agrawal struct qbman_result *storage, 1818531b17a7SHemant Agrawal dma_addr_t storage_phys, 1819531b17a7SHemant Agrawal int stash) 1820531b17a7SHemant Agrawal { 18215ae1edffSHemant Agrawal d->pull.rsp_addr_virt = (size_t)storage; 182269293c77SHemant Agrawal 1823531b17a7SHemant Agrawal if (!storage) { 182469293c77SHemant Agrawal d->pull.verb &= ~(1 << QB_VDQCR_VERB_RLS_SHIFT); 1825531b17a7SHemant Agrawal return; 1826531b17a7SHemant Agrawal } 182769293c77SHemant Agrawal d->pull.verb |= 1 << QB_VDQCR_VERB_RLS_SHIFT; 182869293c77SHemant Agrawal if (stash) 182969293c77SHemant Agrawal d->pull.verb |= 1 << QB_VDQCR_VERB_WAE_SHIFT; 183069293c77SHemant Agrawal else 183169293c77SHemant Agrawal d->pull.verb &= ~(1 << QB_VDQCR_VERB_WAE_SHIFT); 183269293c77SHemant Agrawal 183369293c77SHemant Agrawal d->pull.rsp_addr = storage_phys; 1834531b17a7SHemant Agrawal } 1835531b17a7SHemant Agrawal 1836293c0ca9SNipun Gupta void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, 1837293c0ca9SNipun Gupta uint8_t numframes) 1838531b17a7SHemant Agrawal { 183969293c77SHemant Agrawal d->pull.numf = numframes - 1; 1840531b17a7SHemant Agrawal } 1841531b17a7SHemant Agrawal 1842531b17a7SHemant Agrawal void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token) 1843531b17a7SHemant Agrawal { 184469293c77SHemant Agrawal d->pull.tok = token; 1845531b17a7SHemant Agrawal } 1846531b17a7SHemant Agrawal 1847531b17a7SHemant Agrawal void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid) 1848531b17a7SHemant Agrawal { 184969293c77SHemant Agrawal d->pull.verb |= 1 << QB_VDQCR_VERB_DCT_SHIFT; 185069293c77SHemant Agrawal d->pull.verb |= qb_pull_dt_framequeue << QB_VDQCR_VERB_DT_SHIFT; 185169293c77SHemant Agrawal d->pull.dq_src = fqid; 1852531b17a7SHemant Agrawal } 1853531b17a7SHemant Agrawal 1854531b17a7SHemant Agrawal void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid, 1855531b17a7SHemant Agrawal enum qbman_pull_type_e dct) 1856531b17a7SHemant Agrawal { 185769293c77SHemant Agrawal d->pull.verb |= dct << QB_VDQCR_VERB_DCT_SHIFT; 185869293c77SHemant Agrawal d->pull.verb |= qb_pull_dt_workqueue << QB_VDQCR_VERB_DT_SHIFT; 185969293c77SHemant Agrawal d->pull.dq_src = wqid; 1860531b17a7SHemant Agrawal } 1861531b17a7SHemant Agrawal 1862531b17a7SHemant Agrawal void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid, 1863531b17a7SHemant Agrawal enum qbman_pull_type_e dct) 1864531b17a7SHemant Agrawal { 186569293c77SHemant Agrawal d->pull.verb |= dct << QB_VDQCR_VERB_DCT_SHIFT; 186669293c77SHemant Agrawal d->pull.verb |= qb_pull_dt_channel << QB_VDQCR_VERB_DT_SHIFT; 186769293c77SHemant Agrawal d->pull.dq_src = chid; 1868531b17a7SHemant Agrawal } 1869531b17a7SHemant Agrawal 187064f131a8SHemant Agrawal /** 187164f131a8SHemant Agrawal * qbman_pull_desc_set_rad() - Decide whether reschedule the fq after dequeue 187264f131a8SHemant Agrawal * 187364f131a8SHemant Agrawal * @rad: 1 = Reschedule the FQ after dequeue. 187464f131a8SHemant Agrawal * 0 = Allow the FQ to remain active after dequeue. 187564f131a8SHemant Agrawal */ 1876293c0ca9SNipun Gupta void qbman_pull_desc_set_rad(struct qbman_pull_desc *d, int rad) 1877293c0ca9SNipun Gupta { 1878293c0ca9SNipun Gupta if (d->pull.verb & (1 << QB_VDQCR_VERB_RLS_SHIFT)) { 1879293c0ca9SNipun Gupta if (rad) 1880293c0ca9SNipun Gupta d->pull.verb |= 1 << QB_VDQCR_VERB_RAD_SHIFT; 1881293c0ca9SNipun Gupta else 1882293c0ca9SNipun Gupta d->pull.verb &= ~(1 << QB_VDQCR_VERB_RAD_SHIFT); 1883293c0ca9SNipun Gupta } else { 18840fcdbde0SHemant Agrawal pr_warn("The RAD feature is not valid when RLS = 0\n"); 1885293c0ca9SNipun Gupta } 1886293c0ca9SNipun Gupta } 1887293c0ca9SNipun Gupta 1888293c0ca9SNipun Gupta static int qbman_swp_pull_direct(struct qbman_swp *s, 1889293c0ca9SNipun Gupta struct qbman_pull_desc *d) 1890531b17a7SHemant Agrawal { 1891531b17a7SHemant Agrawal uint32_t *p; 1892531b17a7SHemant Agrawal uint32_t *cl = qb_cl(d); 1893531b17a7SHemant Agrawal 1894531b17a7SHemant Agrawal if (!atomic_dec_and_test(&s->vdq.busy)) { 1895531b17a7SHemant Agrawal atomic_inc(&s->vdq.busy); 1896531b17a7SHemant Agrawal return -EBUSY; 1897531b17a7SHemant Agrawal } 189869293c77SHemant Agrawal 189969293c77SHemant Agrawal d->pull.tok = s->sys.idx + 1; 19005ae1edffSHemant Agrawal s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt; 1901531b17a7SHemant Agrawal p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR); 19028b870905SHaiying Wang memcpy(&p[1], &cl[1], 12); 190369293c77SHemant Agrawal 1904531b17a7SHemant Agrawal /* Set the verb byte, have to substitute in the valid-bit */ 1905531b17a7SHemant Agrawal lwsync(); 1906531b17a7SHemant Agrawal p[0] = cl[0] | s->vdq.valid_bit; 1907531b17a7SHemant Agrawal s->vdq.valid_bit ^= QB_VALID_BIT; 1908531b17a7SHemant Agrawal qbman_cena_write_complete_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR); 190969293c77SHemant Agrawal 1910531b17a7SHemant Agrawal return 0; 1911531b17a7SHemant Agrawal } 1912531b17a7SHemant Agrawal 1913b3bd7a50SNipun Gupta static int qbman_swp_pull_cinh_direct(struct qbman_swp *s, 1914b3bd7a50SNipun Gupta struct qbman_pull_desc *d) 1915b3bd7a50SNipun Gupta { 1916b3bd7a50SNipun Gupta uint32_t *p; 1917b3bd7a50SNipun Gupta uint32_t *cl = qb_cl(d); 1918b3bd7a50SNipun Gupta 1919b3bd7a50SNipun Gupta if (!atomic_dec_and_test(&s->vdq.busy)) { 1920b3bd7a50SNipun Gupta atomic_inc(&s->vdq.busy); 1921b3bd7a50SNipun Gupta return -EBUSY; 1922b3bd7a50SNipun Gupta } 1923b3bd7a50SNipun Gupta 1924b3bd7a50SNipun Gupta d->pull.tok = s->sys.idx + 1; 1925b3bd7a50SNipun Gupta s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt; 1926b3bd7a50SNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR); 1927b3bd7a50SNipun Gupta memcpy_byte_by_byte(&p[1], &cl[1], 12); 1928b3bd7a50SNipun Gupta 1929b3bd7a50SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 1930b3bd7a50SNipun Gupta lwsync(); 1931b3bd7a50SNipun Gupta p[0] = cl[0] | s->vdq.valid_bit; 1932b3bd7a50SNipun Gupta s->vdq.valid_bit ^= QB_VALID_BIT; 1933b3bd7a50SNipun Gupta 1934b3bd7a50SNipun Gupta return 0; 1935b3bd7a50SNipun Gupta } 1936b3bd7a50SNipun Gupta 1937293c0ca9SNipun Gupta static int qbman_swp_pull_mem_back(struct qbman_swp *s, 1938293c0ca9SNipun Gupta struct qbman_pull_desc *d) 1939293c0ca9SNipun Gupta { 1940293c0ca9SNipun Gupta uint32_t *p; 1941293c0ca9SNipun Gupta uint32_t *cl = qb_cl(d); 1942293c0ca9SNipun Gupta 1943293c0ca9SNipun Gupta if (!atomic_dec_and_test(&s->vdq.busy)) { 1944293c0ca9SNipun Gupta atomic_inc(&s->vdq.busy); 1945293c0ca9SNipun Gupta return -EBUSY; 1946293c0ca9SNipun Gupta } 1947293c0ca9SNipun Gupta 1948293c0ca9SNipun Gupta d->pull.tok = s->sys.idx + 1; 1949293c0ca9SNipun Gupta s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt; 1950293c0ca9SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR_MEM); 1951293c0ca9SNipun Gupta memcpy(&p[1], &cl[1], 12); 1952293c0ca9SNipun Gupta 1953293c0ca9SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit */ 1954293c0ca9SNipun Gupta p[0] = cl[0] | s->vdq.valid_bit; 1955293c0ca9SNipun Gupta s->vdq.valid_bit ^= QB_VALID_BIT; 1956293c0ca9SNipun Gupta dma_wmb(); 1957293c0ca9SNipun Gupta qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE); 1958293c0ca9SNipun Gupta 1959293c0ca9SNipun Gupta return 0; 1960293c0ca9SNipun Gupta } 1961293c0ca9SNipun Gupta 19620ff708edSFerruh Yigit int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d) 1963293c0ca9SNipun Gupta { 1964b3bd7a50SNipun Gupta if (!s->stash_off) 1965293c0ca9SNipun Gupta return qbman_swp_pull_ptr(s, d); 1966b3bd7a50SNipun Gupta else 1967b3bd7a50SNipun Gupta return qbman_swp_pull_cinh_direct(s, d); 1968293c0ca9SNipun Gupta } 1969293c0ca9SNipun Gupta 1970531b17a7SHemant Agrawal /****************/ 1971531b17a7SHemant Agrawal /* Polling DQRR */ 1972531b17a7SHemant Agrawal /****************/ 1973531b17a7SHemant Agrawal 197469293c77SHemant Agrawal #define QMAN_DQRR_PI_MASK 0xf 1975531b17a7SHemant Agrawal 1976531b17a7SHemant Agrawal #define QBMAN_RESULT_DQ 0x60 1977531b17a7SHemant Agrawal #define QBMAN_RESULT_FQRN 0x21 1978531b17a7SHemant Agrawal #define QBMAN_RESULT_FQRNI 0x22 1979531b17a7SHemant Agrawal #define QBMAN_RESULT_FQPN 0x24 1980531b17a7SHemant Agrawal #define QBMAN_RESULT_FQDAN 0x25 1981531b17a7SHemant Agrawal #define QBMAN_RESULT_CDAN 0x26 1982531b17a7SHemant Agrawal #define QBMAN_RESULT_CSCN_MEM 0x27 1983531b17a7SHemant Agrawal #define QBMAN_RESULT_CGCU 0x28 1984531b17a7SHemant Agrawal #define QBMAN_RESULT_BPSCN 0x29 1985531b17a7SHemant Agrawal #define QBMAN_RESULT_CSCN_WQ 0x2a 1986531b17a7SHemant Agrawal 19878a7833e1SNipun Gupta #include <rte_prefetch.h> 19888a7833e1SNipun Gupta 19898a7833e1SNipun Gupta void qbman_swp_prefetch_dqrr_next(struct qbman_swp *s) 19908a7833e1SNipun Gupta { 19918a7833e1SNipun Gupta const struct qbman_result *p; 19928a7833e1SNipun Gupta 19938a7833e1SNipun Gupta p = qbman_cena_read_wo_shadow(&s->sys, 19948a7833e1SNipun Gupta QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); 19958a7833e1SNipun Gupta rte_prefetch0(p); 19968a7833e1SNipun Gupta } 19978a7833e1SNipun Gupta 1998531b17a7SHemant Agrawal /* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry 1999531b17a7SHemant Agrawal * only once, so repeated calls can return a sequence of DQRR entries, without 2000531b17a7SHemant Agrawal * requiring they be consumed immediately or in any particular order. 2001531b17a7SHemant Agrawal */ 20020ff708edSFerruh Yigit const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s) 2003293c0ca9SNipun Gupta { 2004b3bd7a50SNipun Gupta if (!s->stash_off) 2005293c0ca9SNipun Gupta return qbman_swp_dqrr_next_ptr(s); 2006b3bd7a50SNipun Gupta else 2007b3bd7a50SNipun Gupta return qbman_swp_dqrr_next_cinh_direct(s); 2008293c0ca9SNipun Gupta } 2009293c0ca9SNipun Gupta 2010293c0ca9SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_direct(struct qbman_swp *s) 2011531b17a7SHemant Agrawal { 2012531b17a7SHemant Agrawal uint32_t verb; 2013531b17a7SHemant Agrawal uint32_t response_verb; 2014531b17a7SHemant Agrawal uint32_t flags; 201569293c77SHemant Agrawal const struct qbman_result *p; 2016531b17a7SHemant Agrawal 2017531b17a7SHemant Agrawal /* Before using valid-bit to detect if something is there, we have to 2018531b17a7SHemant Agrawal * handle the case of the DQRR reset bug... 2019531b17a7SHemant Agrawal */ 2020293c0ca9SNipun Gupta if (s->dqrr.reset_bug) { 2021531b17a7SHemant Agrawal /* We pick up new entries by cache-inhibited producer index, 2022531b17a7SHemant Agrawal * which means that a non-coherent mapping would require us to 2023531b17a7SHemant Agrawal * invalidate and read *only* once that PI has indicated that 2024531b17a7SHemant Agrawal * there's an entry here. The first trip around the DQRR ring 2025531b17a7SHemant Agrawal * will be much less efficient than all subsequent trips around 2026531b17a7SHemant Agrawal * it... 2027531b17a7SHemant Agrawal */ 202869293c77SHemant Agrawal uint8_t pi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI) & 202969293c77SHemant Agrawal QMAN_DQRR_PI_MASK; 203069293c77SHemant Agrawal 203198a7ea33SJerin Jacob /* there are new entries if pi != next_idx */ 2032531b17a7SHemant Agrawal if (pi == s->dqrr.next_idx) 2033531b17a7SHemant Agrawal return NULL; 203469293c77SHemant Agrawal 2035531b17a7SHemant Agrawal /* if next_idx is/was the last ring index, and 'pi' is 2036531b17a7SHemant Agrawal * different, we can disable the workaround as all the ring 2037531b17a7SHemant Agrawal * entries have now been DMA'd to so valid-bit checking is 2038531b17a7SHemant Agrawal * repaired. Note: this logic needs to be based on next_idx 2039531b17a7SHemant Agrawal * (which increments one at a time), rather than on pi (which 2040531b17a7SHemant Agrawal * can burst and wrap-around between our snapshots of it). 2041531b17a7SHemant Agrawal */ 2042531b17a7SHemant Agrawal QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0); 2043531b17a7SHemant Agrawal if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) { 2044531b17a7SHemant Agrawal pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n", 2045531b17a7SHemant Agrawal s->dqrr.next_idx, pi); 2046531b17a7SHemant Agrawal s->dqrr.reset_bug = 0; 2047531b17a7SHemant Agrawal } 2048531b17a7SHemant Agrawal qbman_cena_invalidate_prefetch(&s->sys, 2049531b17a7SHemant Agrawal QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); 2050531b17a7SHemant Agrawal } 205169293c77SHemant Agrawal p = qbman_cena_read_wo_shadow(&s->sys, 2052531b17a7SHemant Agrawal QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); 2053293c0ca9SNipun Gupta 205469293c77SHemant Agrawal verb = p->dq.verb; 205569293c77SHemant Agrawal 2056531b17a7SHemant Agrawal /* If the valid-bit isn't of the expected polarity, nothing there. Note, 2057531b17a7SHemant Agrawal * in the DQRR reset bug workaround, we shouldn't need to skip these 2058531b17a7SHemant Agrawal * check, because we've already determined that a new entry is available 2059531b17a7SHemant Agrawal * and we've invalidated the cacheline before reading it, so the 2060531b17a7SHemant Agrawal * valid-bit behaviour is repaired and should tell us what we already 2061531b17a7SHemant Agrawal * knew from reading PI. 2062531b17a7SHemant Agrawal */ 2063531b17a7SHemant Agrawal if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) 2064531b17a7SHemant Agrawal return NULL; 2065531b17a7SHemant Agrawal 2066531b17a7SHemant Agrawal /* There's something there. Move "next_idx" attention to the next ring 2067531b17a7SHemant Agrawal * entry (and prefetch it) before returning what we found. 2068531b17a7SHemant Agrawal */ 2069531b17a7SHemant Agrawal s->dqrr.next_idx++; 2070531b17a7SHemant Agrawal if (s->dqrr.next_idx == s->dqrr.dqrr_size) { 2071531b17a7SHemant Agrawal s->dqrr.next_idx = 0; 2072531b17a7SHemant Agrawal s->dqrr.valid_bit ^= QB_VALID_BIT; 2073531b17a7SHemant Agrawal } 2074531b17a7SHemant Agrawal /* If this is the final response to a volatile dequeue command 207569293c77SHemant Agrawal * indicate that the vdq is no longer busy 2076531b17a7SHemant Agrawal */ 207769293c77SHemant Agrawal flags = p->dq.stat; 207869293c77SHemant Agrawal response_verb = verb & QBMAN_RESPONSE_VERB_MASK; 2079531b17a7SHemant Agrawal if ((response_verb == QBMAN_RESULT_DQ) && 2080531b17a7SHemant Agrawal (flags & QBMAN_DQ_STAT_VOLATILE) && 2081531b17a7SHemant Agrawal (flags & QBMAN_DQ_STAT_EXPIRED)) 2082531b17a7SHemant Agrawal atomic_inc(&s->vdq.busy); 2083531b17a7SHemant Agrawal 208469293c77SHemant Agrawal return p; 2085531b17a7SHemant Agrawal } 2086531b17a7SHemant Agrawal 2087b3bd7a50SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_cinh_direct(struct qbman_swp *s) 2088b3bd7a50SNipun Gupta { 2089b3bd7a50SNipun Gupta uint32_t verb; 2090b3bd7a50SNipun Gupta uint32_t response_verb; 2091b3bd7a50SNipun Gupta uint32_t flags; 2092b3bd7a50SNipun Gupta const struct qbman_result *p; 2093b3bd7a50SNipun Gupta 2094b3bd7a50SNipun Gupta /* Before using valid-bit to detect if something is there, we have to 2095b3bd7a50SNipun Gupta * handle the case of the DQRR reset bug... 2096b3bd7a50SNipun Gupta */ 2097b3bd7a50SNipun Gupta if (s->dqrr.reset_bug) { 2098b3bd7a50SNipun Gupta /* We pick up new entries by cache-inhibited producer index, 2099b3bd7a50SNipun Gupta * which means that a non-coherent mapping would require us to 2100b3bd7a50SNipun Gupta * invalidate and read *only* once that PI has indicated that 2101b3bd7a50SNipun Gupta * there's an entry here. The first trip around the DQRR ring 2102b3bd7a50SNipun Gupta * will be much less efficient than all subsequent trips around 2103b3bd7a50SNipun Gupta * it... 2104b3bd7a50SNipun Gupta */ 2105b3bd7a50SNipun Gupta uint8_t pi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI) & 2106b3bd7a50SNipun Gupta QMAN_DQRR_PI_MASK; 2107b3bd7a50SNipun Gupta 2108b3bd7a50SNipun Gupta /* there are new entries if pi != next_idx */ 2109b3bd7a50SNipun Gupta if (pi == s->dqrr.next_idx) 2110b3bd7a50SNipun Gupta return NULL; 2111b3bd7a50SNipun Gupta 2112b3bd7a50SNipun Gupta /* if next_idx is/was the last ring index, and 'pi' is 2113b3bd7a50SNipun Gupta * different, we can disable the workaround as all the ring 2114b3bd7a50SNipun Gupta * entries have now been DMA'd to so valid-bit checking is 2115b3bd7a50SNipun Gupta * repaired. Note: this logic needs to be based on next_idx 2116b3bd7a50SNipun Gupta * (which increments one at a time), rather than on pi (which 2117b3bd7a50SNipun Gupta * can burst and wrap-around between our snapshots of it). 2118b3bd7a50SNipun Gupta */ 2119b3bd7a50SNipun Gupta QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0); 2120b3bd7a50SNipun Gupta if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) { 2121b3bd7a50SNipun Gupta pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n", 2122b3bd7a50SNipun Gupta s->dqrr.next_idx, pi); 2123b3bd7a50SNipun Gupta s->dqrr.reset_bug = 0; 2124b3bd7a50SNipun Gupta } 2125b3bd7a50SNipun Gupta } 2126b3bd7a50SNipun Gupta p = qbman_cinh_read_wo_shadow(&s->sys, 2127b3bd7a50SNipun Gupta QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); 2128b3bd7a50SNipun Gupta 2129b3bd7a50SNipun Gupta verb = p->dq.verb; 2130b3bd7a50SNipun Gupta 2131b3bd7a50SNipun Gupta /* If the valid-bit isn't of the expected polarity, nothing there. Note, 2132b3bd7a50SNipun Gupta * in the DQRR reset bug workaround, we shouldn't need to skip these 2133b3bd7a50SNipun Gupta * check, because we've already determined that a new entry is available 2134b3bd7a50SNipun Gupta * and we've invalidated the cacheline before reading it, so the 2135b3bd7a50SNipun Gupta * valid-bit behaviour is repaired and should tell us what we already 2136b3bd7a50SNipun Gupta * knew from reading PI. 2137b3bd7a50SNipun Gupta */ 2138b3bd7a50SNipun Gupta if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) 2139b3bd7a50SNipun Gupta return NULL; 2140b3bd7a50SNipun Gupta 2141b3bd7a50SNipun Gupta /* There's something there. Move "next_idx" attention to the next ring 2142b3bd7a50SNipun Gupta * entry (and prefetch it) before returning what we found. 2143b3bd7a50SNipun Gupta */ 2144b3bd7a50SNipun Gupta s->dqrr.next_idx++; 2145b3bd7a50SNipun Gupta if (s->dqrr.next_idx == s->dqrr.dqrr_size) { 2146b3bd7a50SNipun Gupta s->dqrr.next_idx = 0; 2147b3bd7a50SNipun Gupta s->dqrr.valid_bit ^= QB_VALID_BIT; 2148b3bd7a50SNipun Gupta } 2149b3bd7a50SNipun Gupta /* If this is the final response to a volatile dequeue command 2150b3bd7a50SNipun Gupta * indicate that the vdq is no longer busy 2151b3bd7a50SNipun Gupta */ 2152b3bd7a50SNipun Gupta flags = p->dq.stat; 2153b3bd7a50SNipun Gupta response_verb = verb & QBMAN_RESPONSE_VERB_MASK; 2154b3bd7a50SNipun Gupta if ((response_verb == QBMAN_RESULT_DQ) && 2155b3bd7a50SNipun Gupta (flags & QBMAN_DQ_STAT_VOLATILE) && 2156b3bd7a50SNipun Gupta (flags & QBMAN_DQ_STAT_EXPIRED)) 2157b3bd7a50SNipun Gupta atomic_inc(&s->vdq.busy); 2158b3bd7a50SNipun Gupta 2159b3bd7a50SNipun Gupta return p; 2160b3bd7a50SNipun Gupta } 2161b3bd7a50SNipun Gupta 2162293c0ca9SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s) 2163293c0ca9SNipun Gupta { 2164293c0ca9SNipun Gupta uint32_t verb; 2165293c0ca9SNipun Gupta uint32_t response_verb; 2166293c0ca9SNipun Gupta uint32_t flags; 2167293c0ca9SNipun Gupta const struct qbman_result *p; 2168293c0ca9SNipun Gupta 2169293c0ca9SNipun Gupta p = qbman_cena_read_wo_shadow(&s->sys, 2170293c0ca9SNipun Gupta QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx)); 2171293c0ca9SNipun Gupta 2172293c0ca9SNipun Gupta verb = p->dq.verb; 2173293c0ca9SNipun Gupta 2174293c0ca9SNipun Gupta /* If the valid-bit isn't of the expected polarity, nothing there. Note, 2175293c0ca9SNipun Gupta * in the DQRR reset bug workaround, we shouldn't need to skip these 2176293c0ca9SNipun Gupta * check, because we've already determined that a new entry is available 2177293c0ca9SNipun Gupta * and we've invalidated the cacheline before reading it, so the 2178293c0ca9SNipun Gupta * valid-bit behaviour is repaired and should tell us what we already 2179293c0ca9SNipun Gupta * knew from reading PI. 2180293c0ca9SNipun Gupta */ 2181293c0ca9SNipun Gupta if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) 2182293c0ca9SNipun Gupta return NULL; 2183293c0ca9SNipun Gupta 2184293c0ca9SNipun Gupta /* There's something there. Move "next_idx" attention to the next ring 2185293c0ca9SNipun Gupta * entry (and prefetch it) before returning what we found. 2186293c0ca9SNipun Gupta */ 2187293c0ca9SNipun Gupta s->dqrr.next_idx++; 2188293c0ca9SNipun Gupta if (s->dqrr.next_idx == s->dqrr.dqrr_size) { 2189293c0ca9SNipun Gupta s->dqrr.next_idx = 0; 2190293c0ca9SNipun Gupta s->dqrr.valid_bit ^= QB_VALID_BIT; 2191293c0ca9SNipun Gupta } 2192293c0ca9SNipun Gupta /* If this is the final response to a volatile dequeue command 2193293c0ca9SNipun Gupta * indicate that the vdq is no longer busy 2194293c0ca9SNipun Gupta */ 2195293c0ca9SNipun Gupta flags = p->dq.stat; 2196293c0ca9SNipun Gupta response_verb = verb & QBMAN_RESPONSE_VERB_MASK; 2197ff8e5f10SHemant Agrawal if ((response_verb == QBMAN_RESULT_DQ) 2198ff8e5f10SHemant Agrawal && (flags & QBMAN_DQ_STAT_VOLATILE) 2199ff8e5f10SHemant Agrawal && (flags & QBMAN_DQ_STAT_EXPIRED)) 2200293c0ca9SNipun Gupta atomic_inc(&s->vdq.busy); 2201293c0ca9SNipun Gupta return p; 2202293c0ca9SNipun Gupta } 2203293c0ca9SNipun Gupta 2204531b17a7SHemant Agrawal /* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */ 2205531b17a7SHemant Agrawal void qbman_swp_dqrr_consume(struct qbman_swp *s, 2206531b17a7SHemant Agrawal const struct qbman_result *dq) 2207531b17a7SHemant Agrawal { 2208293c0ca9SNipun Gupta qbman_cinh_write(&s->sys, 2209293c0ca9SNipun Gupta QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq)); 2210531b17a7SHemant Agrawal } 2211531b17a7SHemant Agrawal 22124170dbe2SNipun Gupta /* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */ 22134170dbe2SNipun Gupta void qbman_swp_dqrr_idx_consume(struct qbman_swp *s, 22144170dbe2SNipun Gupta uint8_t dqrr_index) 22154170dbe2SNipun Gupta { 22164170dbe2SNipun Gupta qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, dqrr_index); 22174170dbe2SNipun Gupta } 22184170dbe2SNipun Gupta 2219531b17a7SHemant Agrawal /*********************************/ 2220531b17a7SHemant Agrawal /* Polling user-provided storage */ 2221531b17a7SHemant Agrawal /*********************************/ 2222293c0ca9SNipun Gupta 222369293c77SHemant Agrawal int qbman_result_has_new_result(struct qbman_swp *s, 222469293c77SHemant Agrawal struct qbman_result *dq) 2225531b17a7SHemant Agrawal { 222669293c77SHemant Agrawal if (dq->dq.tok == 0) 2227531b17a7SHemant Agrawal return 0; 2228531b17a7SHemant Agrawal 222969293c77SHemant Agrawal /* 223069293c77SHemant Agrawal * Set token to be 0 so we will detect change back to 1 223169293c77SHemant Agrawal * next time the looping is traversed. Const is cast away here 223269293c77SHemant Agrawal * as we want users to treat the dequeue responses as read only. 2233531b17a7SHemant Agrawal */ 223469293c77SHemant Agrawal ((struct qbman_result *)dq)->dq.tok = 0; 2235531b17a7SHemant Agrawal 223669293c77SHemant Agrawal /* 2237293c0ca9SNipun Gupta * VDQCR "no longer busy" hook - not quite the same as DQRR, because 2238293c0ca9SNipun Gupta * the fact "VDQCR" shows busy doesn't mean that we hold the result 2239293c0ca9SNipun Gupta * that makes it available. Eg. we may be looking at our 10th dequeue 2240293c0ca9SNipun Gupta * result, having released VDQCR after the 1st result and it is now 2241293c0ca9SNipun Gupta * busy due to some other command! 2242531b17a7SHemant Agrawal */ 2243531b17a7SHemant Agrawal if (s->vdq.storage == dq) { 2244531b17a7SHemant Agrawal s->vdq.storage = NULL; 2245531b17a7SHemant Agrawal atomic_inc(&s->vdq.busy); 2246531b17a7SHemant Agrawal } 224769293c77SHemant Agrawal 224869293c77SHemant Agrawal return 1; 224969293c77SHemant Agrawal } 225069293c77SHemant Agrawal 225169293c77SHemant Agrawal int qbman_check_new_result(struct qbman_result *dq) 225269293c77SHemant Agrawal { 225369293c77SHemant Agrawal if (dq->dq.tok == 0) 225469293c77SHemant Agrawal return 0; 225569293c77SHemant Agrawal 225669293c77SHemant Agrawal /* 225769293c77SHemant Agrawal * Set token to be 0 so we will detect change back to 1 225869293c77SHemant Agrawal * next time the looping is traversed. Const is cast away here 225969293c77SHemant Agrawal * as we want users to treat the dequeue responses as read only. 226069293c77SHemant Agrawal */ 226169293c77SHemant Agrawal ((struct qbman_result *)dq)->dq.tok = 0; 226269293c77SHemant Agrawal 226369293c77SHemant Agrawal return 1; 226469293c77SHemant Agrawal } 226569293c77SHemant Agrawal 226669293c77SHemant Agrawal int qbman_check_command_complete(struct qbman_result *dq) 226769293c77SHemant Agrawal { 226869293c77SHemant Agrawal struct qbman_swp *s; 226969293c77SHemant Agrawal 227069293c77SHemant Agrawal if (dq->dq.tok == 0) 227169293c77SHemant Agrawal return 0; 227269293c77SHemant Agrawal 227369293c77SHemant Agrawal s = portal_idx_map[dq->dq.tok - 1]; 227469293c77SHemant Agrawal /* 2275293c0ca9SNipun Gupta * VDQCR "no longer busy" hook - not quite the same as DQRR, because 2276293c0ca9SNipun Gupta * the fact "VDQCR" shows busy doesn't mean that we hold the result 2277293c0ca9SNipun Gupta * that makes it available. Eg. we may be looking at our 10th dequeue 2278293c0ca9SNipun Gupta * result, having released VDQCR after the 1st result and it is now 2279293c0ca9SNipun Gupta * busy due to some other command! 228069293c77SHemant Agrawal */ 228169293c77SHemant Agrawal if (s->vdq.storage == dq) { 228269293c77SHemant Agrawal s->vdq.storage = NULL; 228369293c77SHemant Agrawal atomic_inc(&s->vdq.busy); 228469293c77SHemant Agrawal } 228569293c77SHemant Agrawal 2286531b17a7SHemant Agrawal return 1; 2287531b17a7SHemant Agrawal } 2288531b17a7SHemant Agrawal 2289531b17a7SHemant Agrawal /********************************/ 2290531b17a7SHemant Agrawal /* Categorising qbman results */ 2291531b17a7SHemant Agrawal /********************************/ 2292531b17a7SHemant Agrawal 2293531b17a7SHemant Agrawal static inline int __qbman_result_is_x(const struct qbman_result *dq, 229469293c77SHemant Agrawal uint8_t x) 2295531b17a7SHemant Agrawal { 229669293c77SHemant Agrawal uint8_t response_verb = dq->dq.verb & QBMAN_RESPONSE_VERB_MASK; 2297531b17a7SHemant Agrawal 2298531b17a7SHemant Agrawal return (response_verb == x); 2299531b17a7SHemant Agrawal } 2300531b17a7SHemant Agrawal 2301531b17a7SHemant Agrawal int qbman_result_is_DQ(const struct qbman_result *dq) 2302531b17a7SHemant Agrawal { 2303531b17a7SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_DQ); 2304531b17a7SHemant Agrawal } 2305531b17a7SHemant Agrawal 2306531b17a7SHemant Agrawal int qbman_result_is_FQDAN(const struct qbman_result *dq) 2307531b17a7SHemant Agrawal { 2308531b17a7SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_FQDAN); 2309531b17a7SHemant Agrawal } 2310531b17a7SHemant Agrawal 2311531b17a7SHemant Agrawal int qbman_result_is_CDAN(const struct qbman_result *dq) 2312531b17a7SHemant Agrawal { 2313531b17a7SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_CDAN); 2314531b17a7SHemant Agrawal } 2315531b17a7SHemant Agrawal 2316531b17a7SHemant Agrawal int qbman_result_is_CSCN(const struct qbman_result *dq) 2317531b17a7SHemant Agrawal { 231869293c77SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_MEM) || 2319531b17a7SHemant Agrawal __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_WQ); 2320531b17a7SHemant Agrawal } 2321531b17a7SHemant Agrawal 2322531b17a7SHemant Agrawal int qbman_result_is_BPSCN(const struct qbman_result *dq) 2323531b17a7SHemant Agrawal { 232469293c77SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_BPSCN); 2325531b17a7SHemant Agrawal } 2326531b17a7SHemant Agrawal 2327531b17a7SHemant Agrawal int qbman_result_is_CGCU(const struct qbman_result *dq) 2328531b17a7SHemant Agrawal { 232969293c77SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_CGCU); 2330531b17a7SHemant Agrawal } 2331531b17a7SHemant Agrawal 2332531b17a7SHemant Agrawal int qbman_result_is_FQRN(const struct qbman_result *dq) 2333531b17a7SHemant Agrawal { 233469293c77SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_FQRN); 2335531b17a7SHemant Agrawal } 2336531b17a7SHemant Agrawal 2337531b17a7SHemant Agrawal int qbman_result_is_FQRNI(const struct qbman_result *dq) 2338531b17a7SHemant Agrawal { 233969293c77SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_FQRNI); 2340531b17a7SHemant Agrawal } 2341531b17a7SHemant Agrawal 2342531b17a7SHemant Agrawal int qbman_result_is_FQPN(const struct qbman_result *dq) 2343531b17a7SHemant Agrawal { 2344531b17a7SHemant Agrawal return __qbman_result_is_x(dq, QBMAN_RESULT_FQPN); 2345531b17a7SHemant Agrawal } 2346531b17a7SHemant Agrawal 2347531b17a7SHemant Agrawal /*********************************/ 2348531b17a7SHemant Agrawal /* Parsing frame dequeue results */ 2349531b17a7SHemant Agrawal /*********************************/ 2350531b17a7SHemant Agrawal 2351531b17a7SHemant Agrawal /* These APIs assume qbman_result_is_DQ() is TRUE */ 2352531b17a7SHemant Agrawal 235369293c77SHemant Agrawal uint8_t qbman_result_DQ_flags(const struct qbman_result *dq) 2354531b17a7SHemant Agrawal { 235569293c77SHemant Agrawal return dq->dq.stat; 2356531b17a7SHemant Agrawal } 2357531b17a7SHemant Agrawal 2358531b17a7SHemant Agrawal uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq) 2359531b17a7SHemant Agrawal { 236069293c77SHemant Agrawal return dq->dq.seqnum; 2361531b17a7SHemant Agrawal } 2362531b17a7SHemant Agrawal 2363531b17a7SHemant Agrawal uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq) 2364531b17a7SHemant Agrawal { 236569293c77SHemant Agrawal return dq->dq.oprid; 2366531b17a7SHemant Agrawal } 2367531b17a7SHemant Agrawal 2368531b17a7SHemant Agrawal uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq) 2369531b17a7SHemant Agrawal { 237069293c77SHemant Agrawal return dq->dq.fqid; 2371531b17a7SHemant Agrawal } 2372531b17a7SHemant Agrawal 2373531b17a7SHemant Agrawal uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq) 2374531b17a7SHemant Agrawal { 237569293c77SHemant Agrawal return dq->dq.fq_byte_cnt; 2376531b17a7SHemant Agrawal } 2377531b17a7SHemant Agrawal 2378531b17a7SHemant Agrawal uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq) 2379531b17a7SHemant Agrawal { 238069293c77SHemant Agrawal return dq->dq.fq_frm_cnt; 2381531b17a7SHemant Agrawal } 2382531b17a7SHemant Agrawal 2383531b17a7SHemant Agrawal uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq) 2384531b17a7SHemant Agrawal { 238569293c77SHemant Agrawal return dq->dq.fqd_ctx; 2386531b17a7SHemant Agrawal } 2387531b17a7SHemant Agrawal 2388531b17a7SHemant Agrawal const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq) 2389531b17a7SHemant Agrawal { 239069293c77SHemant Agrawal return (const struct qbman_fd *)&dq->dq.fd[0]; 2391531b17a7SHemant Agrawal } 2392531b17a7SHemant Agrawal 2393531b17a7SHemant Agrawal /**************************************/ 2394531b17a7SHemant Agrawal /* Parsing state-change notifications */ 2395531b17a7SHemant Agrawal /**************************************/ 2396531b17a7SHemant Agrawal uint8_t qbman_result_SCN_state(const struct qbman_result *scn) 2397531b17a7SHemant Agrawal { 239869293c77SHemant Agrawal return scn->scn.state; 2399531b17a7SHemant Agrawal } 2400531b17a7SHemant Agrawal 2401531b17a7SHemant Agrawal uint32_t qbman_result_SCN_rid(const struct qbman_result *scn) 2402531b17a7SHemant Agrawal { 240369293c77SHemant Agrawal return scn->scn.rid_tok; 2404531b17a7SHemant Agrawal } 2405531b17a7SHemant Agrawal 2406531b17a7SHemant Agrawal uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn) 2407531b17a7SHemant Agrawal { 240869293c77SHemant Agrawal return scn->scn.ctx; 2409531b17a7SHemant Agrawal } 2410531b17a7SHemant Agrawal 2411531b17a7SHemant Agrawal /*****************/ 2412531b17a7SHemant Agrawal /* Parsing BPSCN */ 2413531b17a7SHemant Agrawal /*****************/ 2414531b17a7SHemant Agrawal uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn) 2415531b17a7SHemant Agrawal { 241669293c77SHemant Agrawal return (uint16_t)qbman_result_SCN_rid(scn) & 0x3FFF; 2417531b17a7SHemant Agrawal } 2418531b17a7SHemant Agrawal 2419531b17a7SHemant Agrawal int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn) 2420531b17a7SHemant Agrawal { 242169293c77SHemant Agrawal return !(int)(qbman_result_SCN_state(scn) & 0x1); 2422531b17a7SHemant Agrawal } 2423531b17a7SHemant Agrawal 2424531b17a7SHemant Agrawal int qbman_result_bpscn_is_depleted(const struct qbman_result *scn) 2425531b17a7SHemant Agrawal { 242669293c77SHemant Agrawal return (int)(qbman_result_SCN_state(scn) & 0x2); 2427531b17a7SHemant Agrawal } 2428531b17a7SHemant Agrawal 2429531b17a7SHemant Agrawal int qbman_result_bpscn_is_surplus(const struct qbman_result *scn) 2430531b17a7SHemant Agrawal { 243169293c77SHemant Agrawal return (int)(qbman_result_SCN_state(scn) & 0x4); 2432531b17a7SHemant Agrawal } 2433531b17a7SHemant Agrawal 2434531b17a7SHemant Agrawal uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn) 2435531b17a7SHemant Agrawal { 2436d95bdc09SHemant Agrawal return qbman_result_SCN_ctx(scn); 2437531b17a7SHemant Agrawal } 2438531b17a7SHemant Agrawal 2439531b17a7SHemant Agrawal /*****************/ 2440531b17a7SHemant Agrawal /* Parsing CGCU */ 2441531b17a7SHemant Agrawal /*****************/ 2442531b17a7SHemant Agrawal uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn) 2443531b17a7SHemant Agrawal { 244469293c77SHemant Agrawal return (uint16_t)qbman_result_SCN_rid(scn) & 0xFFFF; 2445531b17a7SHemant Agrawal } 2446531b17a7SHemant Agrawal 2447531b17a7SHemant Agrawal uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn) 2448531b17a7SHemant Agrawal { 2449d95bdc09SHemant Agrawal return qbman_result_SCN_ctx(scn); 2450531b17a7SHemant Agrawal } 2451531b17a7SHemant Agrawal 245216c4a3c4SNipun Gupta /********************/ 245316c4a3c4SNipun Gupta /* Parsing EQ RESP */ 245416c4a3c4SNipun Gupta /********************/ 245516c4a3c4SNipun Gupta struct qbman_fd *qbman_result_eqresp_fd(struct qbman_result *eqresp) 245616c4a3c4SNipun Gupta { 245716c4a3c4SNipun Gupta return (struct qbman_fd *)&eqresp->eq_resp.fd[0]; 245816c4a3c4SNipun Gupta } 245916c4a3c4SNipun Gupta 246016c4a3c4SNipun Gupta void qbman_result_eqresp_set_rspid(struct qbman_result *eqresp, uint8_t val) 246116c4a3c4SNipun Gupta { 246216c4a3c4SNipun Gupta eqresp->eq_resp.rspid = val; 246316c4a3c4SNipun Gupta } 246416c4a3c4SNipun Gupta 246516c4a3c4SNipun Gupta uint8_t qbman_result_eqresp_rspid(struct qbman_result *eqresp) 246616c4a3c4SNipun Gupta { 246716c4a3c4SNipun Gupta return eqresp->eq_resp.rspid; 246816c4a3c4SNipun Gupta } 246916c4a3c4SNipun Gupta 247016c4a3c4SNipun Gupta uint8_t qbman_result_eqresp_rc(struct qbman_result *eqresp) 247116c4a3c4SNipun Gupta { 247216c4a3c4SNipun Gupta if (eqresp->eq_resp.rc == 0xE) 247316c4a3c4SNipun Gupta return 0; 247416c4a3c4SNipun Gupta else 247516c4a3c4SNipun Gupta return -1; 247616c4a3c4SNipun Gupta } 247716c4a3c4SNipun Gupta 2478531b17a7SHemant Agrawal /******************/ 2479531b17a7SHemant Agrawal /* Buffer release */ 2480531b17a7SHemant Agrawal /******************/ 248169293c77SHemant Agrawal #define QB_BR_RC_VALID_SHIFT 5 248269293c77SHemant Agrawal #define QB_BR_RCDI_SHIFT 6 2483531b17a7SHemant Agrawal 2484531b17a7SHemant Agrawal void qbman_release_desc_clear(struct qbman_release_desc *d) 2485531b17a7SHemant Agrawal { 2486531b17a7SHemant Agrawal memset(d, 0, sizeof(*d)); 248769293c77SHemant Agrawal d->br.verb = 1 << QB_BR_RC_VALID_SHIFT; 2488531b17a7SHemant Agrawal } 2489531b17a7SHemant Agrawal 249069293c77SHemant Agrawal void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint16_t bpid) 2491531b17a7SHemant Agrawal { 249269293c77SHemant Agrawal d->br.bpid = bpid; 2493531b17a7SHemant Agrawal } 2494531b17a7SHemant Agrawal 2495531b17a7SHemant Agrawal void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable) 2496531b17a7SHemant Agrawal { 249769293c77SHemant Agrawal if (enable) 249869293c77SHemant Agrawal d->br.verb |= 1 << QB_BR_RCDI_SHIFT; 249969293c77SHemant Agrawal else 250069293c77SHemant Agrawal d->br.verb &= ~(1 << QB_BR_RCDI_SHIFT); 2501531b17a7SHemant Agrawal } 2502531b17a7SHemant Agrawal 2503531b17a7SHemant Agrawal #define RAR_IDX(rar) ((rar) & 0x7) 2504531b17a7SHemant Agrawal #define RAR_VB(rar) ((rar) & 0x80) 2505531b17a7SHemant Agrawal #define RAR_SUCCESS(rar) ((rar) & 0x100) 2506531b17a7SHemant Agrawal 2507293c0ca9SNipun Gupta static int qbman_swp_release_direct(struct qbman_swp *s, 2508293c0ca9SNipun Gupta const struct qbman_release_desc *d, 2509293c0ca9SNipun Gupta const uint64_t *buffers, 2510293c0ca9SNipun Gupta unsigned int num_buffers) 2511531b17a7SHemant Agrawal { 2512531b17a7SHemant Agrawal uint32_t *p; 2513531b17a7SHemant Agrawal const uint32_t *cl = qb_cl(d); 2514531b17a7SHemant Agrawal uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR); 2515531b17a7SHemant Agrawal 2516531b17a7SHemant Agrawal pr_debug("RAR=%08x\n", rar); 2517531b17a7SHemant Agrawal if (!RAR_SUCCESS(rar)) 2518531b17a7SHemant Agrawal return -EBUSY; 251969293c77SHemant Agrawal 2520531b17a7SHemant Agrawal QBMAN_BUG_ON(!num_buffers || (num_buffers > 7)); 252169293c77SHemant Agrawal 2522531b17a7SHemant Agrawal /* Start the release command */ 2523531b17a7SHemant Agrawal p = qbman_cena_write_start_wo_shadow(&s->sys, 2524531b17a7SHemant Agrawal QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); 252569293c77SHemant Agrawal 2526531b17a7SHemant Agrawal /* Copy the caller's buffer pointers to the command */ 2527531b17a7SHemant Agrawal u64_to_le32_copy(&p[2], buffers, num_buffers); 252869293c77SHemant Agrawal 2529293c0ca9SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit and the 2530293c0ca9SNipun Gupta * number of buffers. 2531531b17a7SHemant Agrawal */ 2532531b17a7SHemant Agrawal lwsync(); 2533531b17a7SHemant Agrawal p[0] = cl[0] | RAR_VB(rar) | num_buffers; 2534531b17a7SHemant Agrawal qbman_cena_write_complete_wo_shadow(&s->sys, 2535531b17a7SHemant Agrawal QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); 253669293c77SHemant Agrawal 2537531b17a7SHemant Agrawal return 0; 2538531b17a7SHemant Agrawal } 2539531b17a7SHemant Agrawal 2540b3bd7a50SNipun Gupta static int qbman_swp_release_cinh_direct(struct qbman_swp *s, 2541b3bd7a50SNipun Gupta const struct qbman_release_desc *d, 2542b3bd7a50SNipun Gupta const uint64_t *buffers, 2543b3bd7a50SNipun Gupta unsigned int num_buffers) 2544b3bd7a50SNipun Gupta { 2545b3bd7a50SNipun Gupta uint32_t *p; 2546b3bd7a50SNipun Gupta const uint32_t *cl = qb_cl(d); 2547b3bd7a50SNipun Gupta uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR); 2548b3bd7a50SNipun Gupta 2549b3bd7a50SNipun Gupta pr_debug("RAR=%08x\n", rar); 2550b3bd7a50SNipun Gupta if (!RAR_SUCCESS(rar)) 2551b3bd7a50SNipun Gupta return -EBUSY; 2552b3bd7a50SNipun Gupta 2553b3bd7a50SNipun Gupta QBMAN_BUG_ON(!num_buffers || (num_buffers > 7)); 2554b3bd7a50SNipun Gupta 2555b3bd7a50SNipun Gupta /* Start the release command */ 2556b3bd7a50SNipun Gupta p = qbman_cinh_write_start_wo_shadow(&s->sys, 2557b3bd7a50SNipun Gupta QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); 2558b3bd7a50SNipun Gupta 2559b3bd7a50SNipun Gupta /* Copy the caller's buffer pointers to the command */ 2560b3bd7a50SNipun Gupta memcpy_byte_by_byte(&p[2], buffers, num_buffers * sizeof(uint64_t)); 2561b3bd7a50SNipun Gupta 2562b3bd7a50SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit and the 2563b3bd7a50SNipun Gupta * number of buffers. 2564b3bd7a50SNipun Gupta */ 2565b3bd7a50SNipun Gupta lwsync(); 2566b3bd7a50SNipun Gupta p[0] = cl[0] | RAR_VB(rar) | num_buffers; 2567b3bd7a50SNipun Gupta 2568b3bd7a50SNipun Gupta return 0; 2569b3bd7a50SNipun Gupta } 2570b3bd7a50SNipun Gupta 2571293c0ca9SNipun Gupta static int qbman_swp_release_mem_back(struct qbman_swp *s, 2572293c0ca9SNipun Gupta const struct qbman_release_desc *d, 2573293c0ca9SNipun Gupta const uint64_t *buffers, 2574293c0ca9SNipun Gupta unsigned int num_buffers) 2575293c0ca9SNipun Gupta { 2576293c0ca9SNipun Gupta uint32_t *p; 2577293c0ca9SNipun Gupta const uint32_t *cl = qb_cl(d); 2578293c0ca9SNipun Gupta uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR); 2579293c0ca9SNipun Gupta 2580293c0ca9SNipun Gupta pr_debug("RAR=%08x\n", rar); 2581293c0ca9SNipun Gupta if (!RAR_SUCCESS(rar)) 2582293c0ca9SNipun Gupta return -EBUSY; 2583293c0ca9SNipun Gupta 2584293c0ca9SNipun Gupta QBMAN_BUG_ON(!num_buffers || (num_buffers > 7)); 2585293c0ca9SNipun Gupta 2586293c0ca9SNipun Gupta /* Start the release command */ 2587293c0ca9SNipun Gupta p = qbman_cena_write_start_wo_shadow(&s->sys, 2588293c0ca9SNipun Gupta QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar))); 2589293c0ca9SNipun Gupta 2590293c0ca9SNipun Gupta /* Copy the caller's buffer pointers to the command */ 2591293c0ca9SNipun Gupta u64_to_le32_copy(&p[2], buffers, num_buffers); 2592293c0ca9SNipun Gupta 2593293c0ca9SNipun Gupta /* Set the verb byte, have to substitute in the valid-bit and the 2594293c0ca9SNipun Gupta * number of buffers. 2595293c0ca9SNipun Gupta */ 2596293c0ca9SNipun Gupta p[0] = cl[0] | RAR_VB(rar) | num_buffers; 2597293c0ca9SNipun Gupta lwsync(); 2598293c0ca9SNipun Gupta qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_RCR_AM_RT + 2599293c0ca9SNipun Gupta RAR_IDX(rar) * 4, QMAN_RT_MODE); 2600293c0ca9SNipun Gupta 2601293c0ca9SNipun Gupta return 0; 2602293c0ca9SNipun Gupta } 2603293c0ca9SNipun Gupta 26040ff708edSFerruh Yigit int qbman_swp_release(struct qbman_swp *s, 2605293c0ca9SNipun Gupta const struct qbman_release_desc *d, 2606293c0ca9SNipun Gupta const uint64_t *buffers, 2607293c0ca9SNipun Gupta unsigned int num_buffers) 2608293c0ca9SNipun Gupta { 2609b3bd7a50SNipun Gupta if (!s->stash_off) 2610293c0ca9SNipun Gupta return qbman_swp_release_ptr(s, d, buffers, num_buffers); 2611b3bd7a50SNipun Gupta else 2612b3bd7a50SNipun Gupta return qbman_swp_release_cinh_direct(s, d, buffers, 2613b3bd7a50SNipun Gupta num_buffers); 2614293c0ca9SNipun Gupta } 2615293c0ca9SNipun Gupta 2616531b17a7SHemant Agrawal /*******************/ 2617531b17a7SHemant Agrawal /* Buffer acquires */ 2618531b17a7SHemant Agrawal /*******************/ 261969293c77SHemant Agrawal struct qbman_acquire_desc { 262069293c77SHemant Agrawal uint8_t verb; 262169293c77SHemant Agrawal uint8_t reserved; 262269293c77SHemant Agrawal uint16_t bpid; 262369293c77SHemant Agrawal uint8_t num; 262469293c77SHemant Agrawal uint8_t reserved2[59]; 262569293c77SHemant Agrawal }; 2626531b17a7SHemant Agrawal 262769293c77SHemant Agrawal struct qbman_acquire_rslt { 262869293c77SHemant Agrawal uint8_t verb; 262969293c77SHemant Agrawal uint8_t rslt; 263069293c77SHemant Agrawal uint16_t reserved; 263169293c77SHemant Agrawal uint8_t num; 263269293c77SHemant Agrawal uint8_t reserved2[3]; 2633a116979aSJun Yang uint64_t buf[BMAN_VALID_RSLT_NUM_MASK]; 263469293c77SHemant Agrawal }; 2635531b17a7SHemant Agrawal 2636b3bd7a50SNipun Gupta static int qbman_swp_acquire_direct(struct qbman_swp *s, uint16_t bpid, 2637b3bd7a50SNipun Gupta uint64_t *buffers, unsigned int num_buffers) 2638531b17a7SHemant Agrawal { 263969293c77SHemant Agrawal struct qbman_acquire_desc *p; 264069293c77SHemant Agrawal struct qbman_acquire_rslt *r; 2641a116979aSJun Yang int num; 2642531b17a7SHemant Agrawal 2643a116979aSJun Yang if (!num_buffers || (num_buffers > BMAN_VALID_RSLT_NUM_MASK)) 264469293c77SHemant Agrawal return -EINVAL; 2645531b17a7SHemant Agrawal 2646531b17a7SHemant Agrawal /* Start the management command */ 2647531b17a7SHemant Agrawal p = qbman_swp_mc_start(s); 2648531b17a7SHemant Agrawal 2649531b17a7SHemant Agrawal if (!p) 2650531b17a7SHemant Agrawal return -EBUSY; 2651531b17a7SHemant Agrawal 2652531b17a7SHemant Agrawal /* Encode the caller-provided attributes */ 265369293c77SHemant Agrawal p->bpid = bpid; 265469293c77SHemant Agrawal p->num = num_buffers; 2655531b17a7SHemant Agrawal 2656531b17a7SHemant Agrawal /* Complete the management command */ 265769293c77SHemant Agrawal r = qbman_swp_mc_complete(s, p, QBMAN_MC_ACQUIRE); 2658293c0ca9SNipun Gupta if (!r) { 265969293c77SHemant Agrawal pr_err("qbman: acquire from BPID %d failed, no response\n", 266069293c77SHemant Agrawal bpid); 2661531b17a7SHemant Agrawal return -EIO; 2662531b17a7SHemant Agrawal } 266369293c77SHemant Agrawal 266469293c77SHemant Agrawal /* Decode the outcome */ 266569293c77SHemant Agrawal QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ACQUIRE); 266669293c77SHemant Agrawal 266769293c77SHemant Agrawal /* Determine success or failure */ 2668293c0ca9SNipun Gupta if (r->rslt != QBMAN_MC_RSLT_OK) { 266969293c77SHemant Agrawal pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n", 267069293c77SHemant Agrawal bpid, r->rslt); 267169293c77SHemant Agrawal return -EIO; 267269293c77SHemant Agrawal } 267369293c77SHemant Agrawal 2674a116979aSJun Yang num = r->num & BMAN_VALID_RSLT_NUM_MASK; 2675a116979aSJun Yang QBMAN_BUG_ON(num > num_buffers); 267669293c77SHemant Agrawal 2677531b17a7SHemant Agrawal /* Copy the acquired buffers to the caller's array */ 2678a116979aSJun Yang u64_from_le32_copy(buffers, &r->buf[0], num); 267969293c77SHemant Agrawal 2680a116979aSJun Yang return num; 2681531b17a7SHemant Agrawal } 2682531b17a7SHemant Agrawal 2683b3bd7a50SNipun Gupta static int qbman_swp_acquire_cinh_direct(struct qbman_swp *s, uint16_t bpid, 2684b3bd7a50SNipun Gupta uint64_t *buffers, unsigned int num_buffers) 2685b3bd7a50SNipun Gupta { 2686b3bd7a50SNipun Gupta struct qbman_acquire_desc *p; 2687b3bd7a50SNipun Gupta struct qbman_acquire_rslt *r; 2688a116979aSJun Yang int num; 2689b3bd7a50SNipun Gupta 2690a116979aSJun Yang if (!num_buffers || (num_buffers > BMAN_VALID_RSLT_NUM_MASK)) 2691b3bd7a50SNipun Gupta return -EINVAL; 2692b3bd7a50SNipun Gupta 2693b3bd7a50SNipun Gupta /* Start the management command */ 2694b3bd7a50SNipun Gupta p = qbman_swp_mc_start(s); 2695b3bd7a50SNipun Gupta 2696b3bd7a50SNipun Gupta if (!p) 2697b3bd7a50SNipun Gupta return -EBUSY; 2698b3bd7a50SNipun Gupta 2699b3bd7a50SNipun Gupta /* Encode the caller-provided attributes */ 2700b3bd7a50SNipun Gupta p->bpid = bpid; 2701b3bd7a50SNipun Gupta p->num = num_buffers; 2702b3bd7a50SNipun Gupta 2703b3bd7a50SNipun Gupta /* Complete the management command */ 2704b3bd7a50SNipun Gupta r = qbman_swp_mc_complete_cinh(s, p, QBMAN_MC_ACQUIRE); 2705b3bd7a50SNipun Gupta if (!r) { 2706b3bd7a50SNipun Gupta pr_err("qbman: acquire from BPID %d failed, no response\n", 2707b3bd7a50SNipun Gupta bpid); 2708b3bd7a50SNipun Gupta return -EIO; 2709b3bd7a50SNipun Gupta } 2710b3bd7a50SNipun Gupta 2711b3bd7a50SNipun Gupta /* Decode the outcome */ 2712b3bd7a50SNipun Gupta QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ACQUIRE); 2713b3bd7a50SNipun Gupta 2714b3bd7a50SNipun Gupta /* Determine success or failure */ 2715b3bd7a50SNipun Gupta if (r->rslt != QBMAN_MC_RSLT_OK) { 2716b3bd7a50SNipun Gupta pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n", 2717b3bd7a50SNipun Gupta bpid, r->rslt); 2718b3bd7a50SNipun Gupta return -EIO; 2719b3bd7a50SNipun Gupta } 2720b3bd7a50SNipun Gupta 2721a116979aSJun Yang num = r->num & BMAN_VALID_RSLT_NUM_MASK; 2722a116979aSJun Yang QBMAN_BUG_ON(num > num_buffers); 2723b3bd7a50SNipun Gupta 2724b3bd7a50SNipun Gupta /* Copy the acquired buffers to the caller's array */ 2725a116979aSJun Yang u64_from_le32_copy(buffers, &r->buf[0], num); 2726b3bd7a50SNipun Gupta 2727a116979aSJun Yang return num; 2728b3bd7a50SNipun Gupta } 2729b3bd7a50SNipun Gupta 2730b3bd7a50SNipun Gupta int qbman_swp_acquire(struct qbman_swp *s, uint16_t bpid, uint64_t *buffers, 2731b3bd7a50SNipun Gupta unsigned int num_buffers) 2732b3bd7a50SNipun Gupta { 2733b3bd7a50SNipun Gupta if (!s->stash_off) 2734b3bd7a50SNipun Gupta return qbman_swp_acquire_direct(s, bpid, buffers, num_buffers); 2735b3bd7a50SNipun Gupta else 2736b3bd7a50SNipun Gupta return qbman_swp_acquire_cinh_direct(s, bpid, buffers, 2737b3bd7a50SNipun Gupta num_buffers); 2738b3bd7a50SNipun Gupta } 2739b3bd7a50SNipun Gupta 2740531b17a7SHemant Agrawal /*****************/ 2741531b17a7SHemant Agrawal /* FQ management */ 2742531b17a7SHemant Agrawal /*****************/ 274369293c77SHemant Agrawal struct qbman_alt_fq_state_desc { 274469293c77SHemant Agrawal uint8_t verb; 274569293c77SHemant Agrawal uint8_t reserved[3]; 274669293c77SHemant Agrawal uint32_t fqid; 274769293c77SHemant Agrawal uint8_t reserved2[56]; 274869293c77SHemant Agrawal }; 2749531b17a7SHemant Agrawal 275069293c77SHemant Agrawal struct qbman_alt_fq_state_rslt { 275169293c77SHemant Agrawal uint8_t verb; 275269293c77SHemant Agrawal uint8_t rslt; 275369293c77SHemant Agrawal uint8_t reserved[62]; 275469293c77SHemant Agrawal }; 275569293c77SHemant Agrawal 275669293c77SHemant Agrawal #define ALT_FQ_FQID_MASK 0x00FFFFFF 2757531b17a7SHemant Agrawal 2758531b17a7SHemant Agrawal static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid, 2759531b17a7SHemant Agrawal uint8_t alt_fq_verb) 2760531b17a7SHemant Agrawal { 276169293c77SHemant Agrawal struct qbman_alt_fq_state_desc *p; 276269293c77SHemant Agrawal struct qbman_alt_fq_state_rslt *r; 2763531b17a7SHemant Agrawal 2764531b17a7SHemant Agrawal /* Start the management command */ 2765531b17a7SHemant Agrawal p = qbman_swp_mc_start(s); 2766531b17a7SHemant Agrawal if (!p) 2767531b17a7SHemant Agrawal return -EBUSY; 2768531b17a7SHemant Agrawal 276969293c77SHemant Agrawal p->fqid = fqid & ALT_FQ_FQID_MASK; 277069293c77SHemant Agrawal 2771531b17a7SHemant Agrawal /* Complete the management command */ 277269293c77SHemant Agrawal r = qbman_swp_mc_complete(s, p, alt_fq_verb); 2773293c0ca9SNipun Gupta if (!r) { 277469293c77SHemant Agrawal pr_err("qbman: mgmt cmd failed, no response (verb=0x%x)\n", 277569293c77SHemant Agrawal alt_fq_verb); 277669293c77SHemant Agrawal return -EIO; 277769293c77SHemant Agrawal } 2778531b17a7SHemant Agrawal 2779531b17a7SHemant Agrawal /* Decode the outcome */ 278069293c77SHemant Agrawal QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != alt_fq_verb); 2781531b17a7SHemant Agrawal 2782531b17a7SHemant Agrawal /* Determine success or failure */ 2783293c0ca9SNipun Gupta if (r->rslt != QBMAN_MC_RSLT_OK) { 2784531b17a7SHemant Agrawal pr_err("ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\n", 278569293c77SHemant Agrawal fqid, alt_fq_verb, r->rslt); 2786531b17a7SHemant Agrawal return -EIO; 2787531b17a7SHemant Agrawal } 2788531b17a7SHemant Agrawal 2789531b17a7SHemant Agrawal return 0; 2790531b17a7SHemant Agrawal } 2791531b17a7SHemant Agrawal 2792531b17a7SHemant Agrawal int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid) 2793531b17a7SHemant Agrawal { 2794531b17a7SHemant Agrawal return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE); 2795531b17a7SHemant Agrawal } 2796531b17a7SHemant Agrawal 2797531b17a7SHemant Agrawal int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid) 2798531b17a7SHemant Agrawal { 2799531b17a7SHemant Agrawal return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE); 2800531b17a7SHemant Agrawal } 2801531b17a7SHemant Agrawal 2802531b17a7SHemant Agrawal int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid) 2803531b17a7SHemant Agrawal { 2804531b17a7SHemant Agrawal return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON); 2805531b17a7SHemant Agrawal } 2806531b17a7SHemant Agrawal 2807531b17a7SHemant Agrawal int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid) 2808531b17a7SHemant Agrawal { 2809531b17a7SHemant Agrawal return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF); 2810531b17a7SHemant Agrawal } 2811531b17a7SHemant Agrawal 2812531b17a7SHemant Agrawal /**********************/ 2813531b17a7SHemant Agrawal /* Channel management */ 2814531b17a7SHemant Agrawal /**********************/ 2815531b17a7SHemant Agrawal 281669293c77SHemant Agrawal struct qbman_cdan_ctrl_desc { 281769293c77SHemant Agrawal uint8_t verb; 281869293c77SHemant Agrawal uint8_t reserved; 281969293c77SHemant Agrawal uint16_t ch; 282069293c77SHemant Agrawal uint8_t we; 282169293c77SHemant Agrawal uint8_t ctrl; 282269293c77SHemant Agrawal uint16_t reserved2; 282369293c77SHemant Agrawal uint64_t cdan_ctx; 282469293c77SHemant Agrawal uint8_t reserved3[48]; 282569293c77SHemant Agrawal 282669293c77SHemant Agrawal }; 282769293c77SHemant Agrawal 282869293c77SHemant Agrawal struct qbman_cdan_ctrl_rslt { 282969293c77SHemant Agrawal uint8_t verb; 283069293c77SHemant Agrawal uint8_t rslt; 283169293c77SHemant Agrawal uint16_t ch; 283269293c77SHemant Agrawal uint8_t reserved[60]; 283369293c77SHemant Agrawal }; 2834531b17a7SHemant Agrawal 2835531b17a7SHemant Agrawal /* Hide "ICD" for now as we don't use it, don't set it, and don't test it, so it 2836531b17a7SHemant Agrawal * would be irresponsible to expose it. 2837531b17a7SHemant Agrawal */ 2838531b17a7SHemant Agrawal #define CODE_CDAN_WE_EN 0x1 2839531b17a7SHemant Agrawal #define CODE_CDAN_WE_CTX 0x4 2840531b17a7SHemant Agrawal 2841531b17a7SHemant Agrawal static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid, 2842531b17a7SHemant Agrawal uint8_t we_mask, uint8_t cdan_en, 2843531b17a7SHemant Agrawal uint64_t ctx) 2844531b17a7SHemant Agrawal { 284569293c77SHemant Agrawal struct qbman_cdan_ctrl_desc *p; 284669293c77SHemant Agrawal struct qbman_cdan_ctrl_rslt *r; 2847531b17a7SHemant Agrawal 2848531b17a7SHemant Agrawal /* Start the management command */ 2849531b17a7SHemant Agrawal p = qbman_swp_mc_start(s); 2850531b17a7SHemant Agrawal if (!p) 2851531b17a7SHemant Agrawal return -EBUSY; 2852531b17a7SHemant Agrawal 2853531b17a7SHemant Agrawal /* Encode the caller-provided attributes */ 285469293c77SHemant Agrawal p->ch = channelid; 285569293c77SHemant Agrawal p->we = we_mask; 285669293c77SHemant Agrawal if (cdan_en) 285769293c77SHemant Agrawal p->ctrl = 1; 285869293c77SHemant Agrawal else 285969293c77SHemant Agrawal p->ctrl = 0; 286069293c77SHemant Agrawal p->cdan_ctx = ctx; 286169293c77SHemant Agrawal 2862531b17a7SHemant Agrawal /* Complete the management command */ 286369293c77SHemant Agrawal r = qbman_swp_mc_complete(s, p, QBMAN_WQCHAN_CONFIGURE); 2864293c0ca9SNipun Gupta if (!r) { 286569293c77SHemant Agrawal pr_err("qbman: wqchan config failed, no response\n"); 286669293c77SHemant Agrawal return -EIO; 286769293c77SHemant Agrawal } 2868531b17a7SHemant Agrawal 2869531b17a7SHemant Agrawal /* Decode the outcome */ 287069293c77SHemant Agrawal QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) 2871531b17a7SHemant Agrawal != QBMAN_WQCHAN_CONFIGURE); 2872531b17a7SHemant Agrawal 2873531b17a7SHemant Agrawal /* Determine success or failure */ 2874293c0ca9SNipun Gupta if (r->rslt != QBMAN_MC_RSLT_OK) { 2875531b17a7SHemant Agrawal pr_err("CDAN cQID %d failed: code = 0x%02x\n", 287669293c77SHemant Agrawal channelid, r->rslt); 2877531b17a7SHemant Agrawal return -EIO; 2878531b17a7SHemant Agrawal } 2879531b17a7SHemant Agrawal 2880531b17a7SHemant Agrawal return 0; 2881531b17a7SHemant Agrawal } 2882531b17a7SHemant Agrawal 2883531b17a7SHemant Agrawal int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid, 2884531b17a7SHemant Agrawal uint64_t ctx) 2885531b17a7SHemant Agrawal { 2886531b17a7SHemant Agrawal return qbman_swp_CDAN_set(s, channelid, 2887531b17a7SHemant Agrawal CODE_CDAN_WE_CTX, 2888531b17a7SHemant Agrawal 0, ctx); 2889531b17a7SHemant Agrawal } 2890531b17a7SHemant Agrawal 2891531b17a7SHemant Agrawal int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid) 2892531b17a7SHemant Agrawal { 2893531b17a7SHemant Agrawal return qbman_swp_CDAN_set(s, channelid, 2894531b17a7SHemant Agrawal CODE_CDAN_WE_EN, 2895531b17a7SHemant Agrawal 1, 0); 2896531b17a7SHemant Agrawal } 2897531b17a7SHemant Agrawal 2898531b17a7SHemant Agrawal int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid) 2899531b17a7SHemant Agrawal { 2900531b17a7SHemant Agrawal return qbman_swp_CDAN_set(s, channelid, 2901531b17a7SHemant Agrawal CODE_CDAN_WE_EN, 2902531b17a7SHemant Agrawal 0, 0); 2903531b17a7SHemant Agrawal } 2904531b17a7SHemant Agrawal 2905531b17a7SHemant Agrawal int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid, 2906531b17a7SHemant Agrawal uint64_t ctx) 2907531b17a7SHemant Agrawal { 2908531b17a7SHemant Agrawal return qbman_swp_CDAN_set(s, channelid, 2909531b17a7SHemant Agrawal CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX, 2910531b17a7SHemant Agrawal 1, ctx); 2911531b17a7SHemant Agrawal } 2912531b17a7SHemant Agrawal 29136070ce43SNipun Gupta uint8_t qbman_get_dqrr_idx(const struct qbman_result *dqrr) 2914531b17a7SHemant Agrawal { 2915531b17a7SHemant Agrawal return QBMAN_IDX_FROM_DQRR(dqrr); 2916531b17a7SHemant Agrawal } 2917531b17a7SHemant Agrawal 2918531b17a7SHemant Agrawal struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx) 2919531b17a7SHemant Agrawal { 2920531b17a7SHemant Agrawal struct qbman_result *dq; 2921531b17a7SHemant Agrawal 2922531b17a7SHemant Agrawal dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(idx)); 2923531b17a7SHemant Agrawal return dq; 2924531b17a7SHemant Agrawal } 2925