1cdcd52d4SBartosz Sobczak /*- 2cdcd52d4SBartosz Sobczak * SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 3cdcd52d4SBartosz Sobczak * 4777e472cSBartosz Sobczak * Copyright (c) 2015 - 2022 Intel Corporation 5cdcd52d4SBartosz Sobczak * 6cdcd52d4SBartosz Sobczak * This software is available to you under a choice of one of two 7cdcd52d4SBartosz Sobczak * licenses. You may choose to be licensed under the terms of the GNU 8cdcd52d4SBartosz Sobczak * General Public License (GPL) Version 2, available from the file 9cdcd52d4SBartosz Sobczak * COPYING in the main directory of this source tree, or the 10cdcd52d4SBartosz Sobczak * OpenFabrics.org BSD license below: 11cdcd52d4SBartosz Sobczak * 12cdcd52d4SBartosz Sobczak * Redistribution and use in source and binary forms, with or 13cdcd52d4SBartosz Sobczak * without modification, are permitted provided that the following 14cdcd52d4SBartosz Sobczak * conditions are met: 15cdcd52d4SBartosz Sobczak * 16cdcd52d4SBartosz Sobczak * - Redistributions of source code must retain the above 17cdcd52d4SBartosz Sobczak * copyright notice, this list of conditions and the following 18cdcd52d4SBartosz Sobczak * disclaimer. 19cdcd52d4SBartosz Sobczak * 20cdcd52d4SBartosz Sobczak * - Redistributions in binary form must reproduce the above 21cdcd52d4SBartosz Sobczak * copyright notice, this list of conditions and the following 22cdcd52d4SBartosz Sobczak * disclaimer in the documentation and/or other materials 23cdcd52d4SBartosz Sobczak * provided with the distribution. 24cdcd52d4SBartosz Sobczak * 25cdcd52d4SBartosz Sobczak * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26cdcd52d4SBartosz Sobczak * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27cdcd52d4SBartosz Sobczak * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28cdcd52d4SBartosz Sobczak * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29cdcd52d4SBartosz Sobczak * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30cdcd52d4SBartosz Sobczak * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31cdcd52d4SBartosz Sobczak * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32cdcd52d4SBartosz Sobczak * SOFTWARE. 33cdcd52d4SBartosz Sobczak */ 34cdcd52d4SBartosz Sobczak /*$FreeBSD$*/ 35cdcd52d4SBartosz Sobczak 36cdcd52d4SBartosz Sobczak #include "osdep.h" 37cdcd52d4SBartosz Sobczak #include "irdma_hmc.h" 38cdcd52d4SBartosz Sobczak #include "irdma_defs.h" 39cdcd52d4SBartosz Sobczak #include "irdma_type.h" 40cdcd52d4SBartosz Sobczak #include "irdma_protos.h" 41cdcd52d4SBartosz Sobczak #include "irdma_puda.h" 42cdcd52d4SBartosz Sobczak #include "irdma_ws.h" 43cdcd52d4SBartosz Sobczak 44cdcd52d4SBartosz Sobczak static void 45cdcd52d4SBartosz Sobczak irdma_ieq_receive(struct irdma_sc_vsi *vsi, 46cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf); 47cdcd52d4SBartosz Sobczak static void irdma_ieq_tx_compl(struct irdma_sc_vsi *vsi, void *sqwrid); 48cdcd52d4SBartosz Sobczak static void 49cdcd52d4SBartosz Sobczak irdma_ilq_putback_rcvbuf(struct irdma_sc_qp *qp, 50cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf, u32 wqe_idx); 51cdcd52d4SBartosz Sobczak /** 52cdcd52d4SBartosz Sobczak * irdma_puda_get_listbuf - get buffer from puda list 53cdcd52d4SBartosz Sobczak * @list: list to use for buffers (ILQ or IEQ) 54cdcd52d4SBartosz Sobczak */ 55cdcd52d4SBartosz Sobczak static struct irdma_puda_buf * 56cdcd52d4SBartosz Sobczak irdma_puda_get_listbuf(struct list_head *list) 57cdcd52d4SBartosz Sobczak { 58cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf = NULL; 59cdcd52d4SBartosz Sobczak 60cdcd52d4SBartosz Sobczak if (!list_empty(list)) { 61cdcd52d4SBartosz Sobczak buf = (struct irdma_puda_buf *)(list)->next; 62cdcd52d4SBartosz Sobczak list_del((struct list_head *)&buf->list); 63cdcd52d4SBartosz Sobczak } 64cdcd52d4SBartosz Sobczak 65cdcd52d4SBartosz Sobczak return buf; 66cdcd52d4SBartosz Sobczak } 67cdcd52d4SBartosz Sobczak 68cdcd52d4SBartosz Sobczak /** 69cdcd52d4SBartosz Sobczak * irdma_puda_get_bufpool - return buffer from resource 70cdcd52d4SBartosz Sobczak * @rsrc: resource to use for buffer 71cdcd52d4SBartosz Sobczak */ 72cdcd52d4SBartosz Sobczak struct irdma_puda_buf * 73cdcd52d4SBartosz Sobczak irdma_puda_get_bufpool(struct irdma_puda_rsrc *rsrc) 74cdcd52d4SBartosz Sobczak { 75cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf = NULL; 76cdcd52d4SBartosz Sobczak struct list_head *list = &rsrc->bufpool; 77cdcd52d4SBartosz Sobczak unsigned long flags; 78cdcd52d4SBartosz Sobczak 79cdcd52d4SBartosz Sobczak spin_lock_irqsave(&rsrc->bufpool_lock, flags); 80cdcd52d4SBartosz Sobczak buf = irdma_puda_get_listbuf(list); 81cdcd52d4SBartosz Sobczak if (buf) { 82cdcd52d4SBartosz Sobczak rsrc->avail_buf_count--; 83cdcd52d4SBartosz Sobczak buf->vsi = rsrc->vsi; 84cdcd52d4SBartosz Sobczak } else { 85cdcd52d4SBartosz Sobczak rsrc->stats_buf_alloc_fail++; 86cdcd52d4SBartosz Sobczak } 87cdcd52d4SBartosz Sobczak spin_unlock_irqrestore(&rsrc->bufpool_lock, flags); 88cdcd52d4SBartosz Sobczak 89cdcd52d4SBartosz Sobczak return buf; 90cdcd52d4SBartosz Sobczak } 91cdcd52d4SBartosz Sobczak 92cdcd52d4SBartosz Sobczak /** 93cdcd52d4SBartosz Sobczak * irdma_puda_ret_bufpool - return buffer to rsrc list 94cdcd52d4SBartosz Sobczak * @rsrc: resource to use for buffer 95cdcd52d4SBartosz Sobczak * @buf: buffer to return to resource 96cdcd52d4SBartosz Sobczak */ 97cdcd52d4SBartosz Sobczak void 98cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(struct irdma_puda_rsrc *rsrc, 99cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf) 100cdcd52d4SBartosz Sobczak { 101cdcd52d4SBartosz Sobczak unsigned long flags; 102cdcd52d4SBartosz Sobczak 103cdcd52d4SBartosz Sobczak buf->do_lpb = false; 104cdcd52d4SBartosz Sobczak spin_lock_irqsave(&rsrc->bufpool_lock, flags); 105cdcd52d4SBartosz Sobczak list_add(&buf->list, &rsrc->bufpool); 106cdcd52d4SBartosz Sobczak spin_unlock_irqrestore(&rsrc->bufpool_lock, flags); 107cdcd52d4SBartosz Sobczak rsrc->avail_buf_count++; 108cdcd52d4SBartosz Sobczak } 109cdcd52d4SBartosz Sobczak 110cdcd52d4SBartosz Sobczak /** 111cdcd52d4SBartosz Sobczak * irdma_puda_post_recvbuf - set wqe for rcv buffer 112cdcd52d4SBartosz Sobczak * @rsrc: resource ptr 113cdcd52d4SBartosz Sobczak * @wqe_idx: wqe index to use 114cdcd52d4SBartosz Sobczak * @buf: puda buffer for rcv q 115cdcd52d4SBartosz Sobczak * @initial: flag if during init time 116cdcd52d4SBartosz Sobczak */ 117cdcd52d4SBartosz Sobczak static void 118cdcd52d4SBartosz Sobczak irdma_puda_post_recvbuf(struct irdma_puda_rsrc *rsrc, u32 wqe_idx, 119cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf, bool initial) 120cdcd52d4SBartosz Sobczak { 121cdcd52d4SBartosz Sobczak __le64 *wqe; 122cdcd52d4SBartosz Sobczak struct irdma_sc_qp *qp = &rsrc->qp; 123cdcd52d4SBartosz Sobczak u64 offset24 = 0; 124cdcd52d4SBartosz Sobczak 125cdcd52d4SBartosz Sobczak /* Synch buffer for use by device */ 126cdcd52d4SBartosz Sobczak dma_sync_single_for_device(hw_to_dev(rsrc->dev->hw), buf->mem.pa, buf->mem.size, DMA_BIDIRECTIONAL); 127cdcd52d4SBartosz Sobczak qp->qp_uk.rq_wrid_array[wqe_idx] = (uintptr_t)buf; 128cdcd52d4SBartosz Sobczak wqe = qp->qp_uk.rq_base[wqe_idx].elem; 129cdcd52d4SBartosz Sobczak if (!initial) 130cdcd52d4SBartosz Sobczak get_64bit_val(wqe, IRDMA_BYTE_24, &offset24); 131cdcd52d4SBartosz Sobczak 132777e472cSBartosz Sobczak offset24 = (offset24) ? 0 : FIELD_PREP(IRDMAQPSQ_VALID, 1); 133cdcd52d4SBartosz Sobczak 134cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_16, 0); 135cdcd52d4SBartosz Sobczak set_64bit_val(wqe, 0, buf->mem.pa); 136cdcd52d4SBartosz Sobczak if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) { 137cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_8, 138777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_LEN, buf->mem.size)); 139cdcd52d4SBartosz Sobczak } else { 140cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_8, 141777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPSQ_FRAG_LEN, buf->mem.size) | 142777e472cSBartosz Sobczak offset24); 143cdcd52d4SBartosz Sobczak } 144cdcd52d4SBartosz Sobczak irdma_wmb(); /* make sure WQE is written before valid bit is set */ 145cdcd52d4SBartosz Sobczak 146cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_24, offset24); 147cdcd52d4SBartosz Sobczak } 148cdcd52d4SBartosz Sobczak 149cdcd52d4SBartosz Sobczak /** 150cdcd52d4SBartosz Sobczak * irdma_puda_replenish_rq - post rcv buffers 151cdcd52d4SBartosz Sobczak * @rsrc: resource to use for buffer 152cdcd52d4SBartosz Sobczak * @initial: flag if during init time 153cdcd52d4SBartosz Sobczak */ 154cdcd52d4SBartosz Sobczak static int 155cdcd52d4SBartosz Sobczak irdma_puda_replenish_rq(struct irdma_puda_rsrc *rsrc, bool initial) 156cdcd52d4SBartosz Sobczak { 157cdcd52d4SBartosz Sobczak u32 i; 158cdcd52d4SBartosz Sobczak u32 invalid_cnt = rsrc->rxq_invalid_cnt; 159cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf = NULL; 160cdcd52d4SBartosz Sobczak 161cdcd52d4SBartosz Sobczak for (i = 0; i < invalid_cnt; i++) { 162cdcd52d4SBartosz Sobczak buf = irdma_puda_get_bufpool(rsrc); 163cdcd52d4SBartosz Sobczak if (!buf) 164cdcd52d4SBartosz Sobczak return -ENOBUFS; 165cdcd52d4SBartosz Sobczak irdma_puda_post_recvbuf(rsrc, rsrc->rx_wqe_idx, buf, initial); 166cdcd52d4SBartosz Sobczak rsrc->rx_wqe_idx = ((rsrc->rx_wqe_idx + 1) % rsrc->rq_size); 167cdcd52d4SBartosz Sobczak rsrc->rxq_invalid_cnt--; 168cdcd52d4SBartosz Sobczak } 169cdcd52d4SBartosz Sobczak 170cdcd52d4SBartosz Sobczak return 0; 171cdcd52d4SBartosz Sobczak } 172cdcd52d4SBartosz Sobczak 173cdcd52d4SBartosz Sobczak /** 174cdcd52d4SBartosz Sobczak * irdma_puda_alloc_buf - allocate mem for buffer 175cdcd52d4SBartosz Sobczak * @dev: iwarp device 176cdcd52d4SBartosz Sobczak * @len: length of buffer 177cdcd52d4SBartosz Sobczak */ 178cdcd52d4SBartosz Sobczak static struct irdma_puda_buf * 179cdcd52d4SBartosz Sobczak irdma_puda_alloc_buf(struct irdma_sc_dev *dev, 180cdcd52d4SBartosz Sobczak u32 len) 181cdcd52d4SBartosz Sobczak { 182cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf; 183cdcd52d4SBartosz Sobczak struct irdma_virt_mem buf_mem; 184cdcd52d4SBartosz Sobczak 185cdcd52d4SBartosz Sobczak buf_mem.size = sizeof(struct irdma_puda_buf); 186777e472cSBartosz Sobczak buf_mem.va = kzalloc(buf_mem.size, GFP_KERNEL); 187cdcd52d4SBartosz Sobczak if (!buf_mem.va) 188cdcd52d4SBartosz Sobczak return NULL; 189cdcd52d4SBartosz Sobczak 190cdcd52d4SBartosz Sobczak buf = buf_mem.va; 191cdcd52d4SBartosz Sobczak buf->mem.size = len; 192cdcd52d4SBartosz Sobczak buf->mem.va = kzalloc(buf->mem.size, GFP_KERNEL); 193cdcd52d4SBartosz Sobczak if (!buf->mem.va) 194cdcd52d4SBartosz Sobczak goto free_virt; 195cdcd52d4SBartosz Sobczak buf->mem.pa = dma_map_single(hw_to_dev(dev->hw), buf->mem.va, buf->mem.size, DMA_BIDIRECTIONAL); 196cdcd52d4SBartosz Sobczak if (dma_mapping_error(hw_to_dev(dev->hw), buf->mem.pa)) { 197cdcd52d4SBartosz Sobczak kfree(buf->mem.va); 198cdcd52d4SBartosz Sobczak goto free_virt; 199cdcd52d4SBartosz Sobczak } 200cdcd52d4SBartosz Sobczak 201cdcd52d4SBartosz Sobczak buf->buf_mem.va = buf_mem.va; 202cdcd52d4SBartosz Sobczak buf->buf_mem.size = buf_mem.size; 203cdcd52d4SBartosz Sobczak 204cdcd52d4SBartosz Sobczak return buf; 205cdcd52d4SBartosz Sobczak 206cdcd52d4SBartosz Sobczak free_virt: 207cdcd52d4SBartosz Sobczak kfree(buf_mem.va); 208cdcd52d4SBartosz Sobczak return NULL; 209cdcd52d4SBartosz Sobczak } 210cdcd52d4SBartosz Sobczak 211cdcd52d4SBartosz Sobczak /** 212cdcd52d4SBartosz Sobczak * irdma_puda_dele_buf - delete buffer back to system 213cdcd52d4SBartosz Sobczak * @dev: iwarp device 214cdcd52d4SBartosz Sobczak * @buf: buffer to free 215cdcd52d4SBartosz Sobczak */ 216cdcd52d4SBartosz Sobczak static void 217cdcd52d4SBartosz Sobczak irdma_puda_dele_buf(struct irdma_sc_dev *dev, 218cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf) 219cdcd52d4SBartosz Sobczak { 220cdcd52d4SBartosz Sobczak if (!buf->virtdma) { 221cdcd52d4SBartosz Sobczak irdma_free_dma_mem(dev->hw, &buf->mem); 222cdcd52d4SBartosz Sobczak kfree(buf->buf_mem.va); 223cdcd52d4SBartosz Sobczak } 224cdcd52d4SBartosz Sobczak } 225cdcd52d4SBartosz Sobczak 226cdcd52d4SBartosz Sobczak /** 227cdcd52d4SBartosz Sobczak * irdma_puda_get_next_send_wqe - return next wqe for processing 228cdcd52d4SBartosz Sobczak * @qp: puda qp for wqe 229cdcd52d4SBartosz Sobczak * @wqe_idx: wqe index for caller 230cdcd52d4SBartosz Sobczak */ 231cdcd52d4SBartosz Sobczak static __le64 * irdma_puda_get_next_send_wqe(struct irdma_qp_uk *qp, 232cdcd52d4SBartosz Sobczak u32 *wqe_idx){ 233cdcd52d4SBartosz Sobczak int ret_code = 0; 234cdcd52d4SBartosz Sobczak 235cdcd52d4SBartosz Sobczak *wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring); 236cdcd52d4SBartosz Sobczak if (!*wqe_idx) 237cdcd52d4SBartosz Sobczak qp->swqe_polarity = !qp->swqe_polarity; 238cdcd52d4SBartosz Sobczak IRDMA_RING_MOVE_HEAD(qp->sq_ring, ret_code); 239cdcd52d4SBartosz Sobczak if (ret_code) 240*35105900SBartosz Sobczak return NULL; 241cdcd52d4SBartosz Sobczak 242*35105900SBartosz Sobczak return qp->sq_base[*wqe_idx].elem; 243cdcd52d4SBartosz Sobczak } 244cdcd52d4SBartosz Sobczak 245cdcd52d4SBartosz Sobczak /** 246cdcd52d4SBartosz Sobczak * irdma_puda_poll_info - poll cq for completion 247cdcd52d4SBartosz Sobczak * @cq: cq for poll 248cdcd52d4SBartosz Sobczak * @info: info return for successful completion 249cdcd52d4SBartosz Sobczak */ 250cdcd52d4SBartosz Sobczak static int 251cdcd52d4SBartosz Sobczak irdma_puda_poll_info(struct irdma_sc_cq *cq, 252cdcd52d4SBartosz Sobczak struct irdma_puda_cmpl_info *info) 253cdcd52d4SBartosz Sobczak { 254cdcd52d4SBartosz Sobczak struct irdma_cq_uk *cq_uk = &cq->cq_uk; 255cdcd52d4SBartosz Sobczak u64 qword0, qword2, qword3, qword6; 256cdcd52d4SBartosz Sobczak __le64 *cqe; 257cdcd52d4SBartosz Sobczak __le64 *ext_cqe = NULL; 258cdcd52d4SBartosz Sobczak u64 qword7 = 0; 259cdcd52d4SBartosz Sobczak u64 comp_ctx; 260cdcd52d4SBartosz Sobczak bool valid_bit; 261cdcd52d4SBartosz Sobczak bool ext_valid = 0; 262cdcd52d4SBartosz Sobczak u32 major_err, minor_err; 263cdcd52d4SBartosz Sobczak u32 peek_head; 264cdcd52d4SBartosz Sobczak bool error; 265cdcd52d4SBartosz Sobczak u8 polarity; 266cdcd52d4SBartosz Sobczak 267cdcd52d4SBartosz Sobczak cqe = IRDMA_GET_CURRENT_CQ_ELEM(&cq->cq_uk); 268cdcd52d4SBartosz Sobczak get_64bit_val(cqe, IRDMA_BYTE_24, &qword3); 269777e472cSBartosz Sobczak valid_bit = (bool)FIELD_GET(IRDMA_CQ_VALID, qword3); 270cdcd52d4SBartosz Sobczak if (valid_bit != cq_uk->polarity) 271cdcd52d4SBartosz Sobczak return -ENOENT; 272cdcd52d4SBartosz Sobczak 273cdcd52d4SBartosz Sobczak if (cq->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) 274777e472cSBartosz Sobczak ext_valid = (bool)FIELD_GET(IRDMA_CQ_EXTCQE, qword3); 275cdcd52d4SBartosz Sobczak 276cdcd52d4SBartosz Sobczak if (ext_valid) { 277cdcd52d4SBartosz Sobczak peek_head = (cq_uk->cq_ring.head + 1) % cq_uk->cq_ring.size; 278cdcd52d4SBartosz Sobczak ext_cqe = cq_uk->cq_base[peek_head].buf; 279cdcd52d4SBartosz Sobczak get_64bit_val(ext_cqe, IRDMA_BYTE_24, &qword7); 280777e472cSBartosz Sobczak polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword7); 281cdcd52d4SBartosz Sobczak if (!peek_head) 282cdcd52d4SBartosz Sobczak polarity ^= 1; 283cdcd52d4SBartosz Sobczak if (polarity != cq_uk->polarity) 284cdcd52d4SBartosz Sobczak return -ENOENT; 285cdcd52d4SBartosz Sobczak 286cdcd52d4SBartosz Sobczak IRDMA_RING_MOVE_HEAD_NOCHECK(cq_uk->cq_ring); 287cdcd52d4SBartosz Sobczak if (!IRDMA_RING_CURRENT_HEAD(cq_uk->cq_ring)) 288cdcd52d4SBartosz Sobczak cq_uk->polarity = !cq_uk->polarity; 289cdcd52d4SBartosz Sobczak /* update cq tail in cq shadow memory also */ 290cdcd52d4SBartosz Sobczak IRDMA_RING_MOVE_TAIL(cq_uk->cq_ring); 291cdcd52d4SBartosz Sobczak } 292cdcd52d4SBartosz Sobczak 293cdcd52d4SBartosz Sobczak irdma_debug_buf(cq->dev, IRDMA_DEBUG_PUDA, "PUDA CQE", cqe, 32); 294cdcd52d4SBartosz Sobczak if (ext_valid) 295cdcd52d4SBartosz Sobczak irdma_debug_buf(cq->dev, IRDMA_DEBUG_PUDA, "PUDA EXT-CQE", 296cdcd52d4SBartosz Sobczak ext_cqe, 32); 297cdcd52d4SBartosz Sobczak 298777e472cSBartosz Sobczak error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3); 299cdcd52d4SBartosz Sobczak if (error) { 300cdcd52d4SBartosz Sobczak irdma_debug(cq->dev, IRDMA_DEBUG_PUDA, "receive error\n"); 301777e472cSBartosz Sobczak major_err = (u32)(FIELD_GET(IRDMA_CQ_MAJERR, qword3)); 302777e472cSBartosz Sobczak minor_err = (u32)(FIELD_GET(IRDMA_CQ_MINERR, qword3)); 303cdcd52d4SBartosz Sobczak info->compl_error = major_err << 16 | minor_err; 304cdcd52d4SBartosz Sobczak return -EIO; 305cdcd52d4SBartosz Sobczak } 306cdcd52d4SBartosz Sobczak 307cdcd52d4SBartosz Sobczak get_64bit_val(cqe, IRDMA_BYTE_0, &qword0); 308cdcd52d4SBartosz Sobczak get_64bit_val(cqe, IRDMA_BYTE_16, &qword2); 309cdcd52d4SBartosz Sobczak 310777e472cSBartosz Sobczak info->q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3); 311777e472cSBartosz Sobczak info->qp_id = (u32)FIELD_GET(IRDMACQ_QPID, qword2); 312cdcd52d4SBartosz Sobczak if (cq->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) 313777e472cSBartosz Sobczak info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3); 314cdcd52d4SBartosz Sobczak 315cdcd52d4SBartosz Sobczak get_64bit_val(cqe, IRDMA_BYTE_8, &comp_ctx); 316cdcd52d4SBartosz Sobczak info->qp = (struct irdma_qp_uk *)(irdma_uintptr) comp_ctx; 317777e472cSBartosz Sobczak info->wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3); 318cdcd52d4SBartosz Sobczak 319cdcd52d4SBartosz Sobczak if (info->q_type == IRDMA_CQE_QTYPE_RQ) { 320cdcd52d4SBartosz Sobczak if (ext_valid) { 321777e472cSBartosz Sobczak info->vlan_valid = (bool)FIELD_GET(IRDMA_CQ_UDVLANVALID, qword7); 322cdcd52d4SBartosz Sobczak if (info->vlan_valid) { 323cdcd52d4SBartosz Sobczak get_64bit_val(ext_cqe, IRDMA_BYTE_16, &qword6); 324777e472cSBartosz Sobczak info->vlan = (u16)FIELD_GET(IRDMA_CQ_UDVLAN, qword6); 325cdcd52d4SBartosz Sobczak } 326777e472cSBartosz Sobczak info->smac_valid = (bool)FIELD_GET(IRDMA_CQ_UDSMACVALID, qword7); 327cdcd52d4SBartosz Sobczak if (info->smac_valid) { 328cdcd52d4SBartosz Sobczak get_64bit_val(ext_cqe, IRDMA_BYTE_16, &qword6); 329cdcd52d4SBartosz Sobczak info->smac[0] = (u8)((qword6 >> 40) & 0xFF); 330cdcd52d4SBartosz Sobczak info->smac[1] = (u8)((qword6 >> 32) & 0xFF); 331cdcd52d4SBartosz Sobczak info->smac[2] = (u8)((qword6 >> 24) & 0xFF); 332cdcd52d4SBartosz Sobczak info->smac[3] = (u8)((qword6 >> 16) & 0xFF); 333cdcd52d4SBartosz Sobczak info->smac[4] = (u8)((qword6 >> 8) & 0xFF); 334cdcd52d4SBartosz Sobczak info->smac[5] = (u8)(qword6 & 0xFF); 335cdcd52d4SBartosz Sobczak } 336cdcd52d4SBartosz Sobczak } 337cdcd52d4SBartosz Sobczak 338cdcd52d4SBartosz Sobczak if (cq->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) { 339777e472cSBartosz Sobczak info->vlan_valid = (bool)FIELD_GET(IRDMA_VLAN_TAG_VALID, qword3); 340777e472cSBartosz Sobczak info->l4proto = (u8)FIELD_GET(IRDMA_UDA_L4PROTO, qword2); 341777e472cSBartosz Sobczak info->l3proto = (u8)FIELD_GET(IRDMA_UDA_L3PROTO, qword2); 342cdcd52d4SBartosz Sobczak } 343cdcd52d4SBartosz Sobczak 344777e472cSBartosz Sobczak info->payload_len = (u32)FIELD_GET(IRDMACQ_PAYLDLEN, qword0); 345cdcd52d4SBartosz Sobczak } 346cdcd52d4SBartosz Sobczak 347cdcd52d4SBartosz Sobczak return 0; 348cdcd52d4SBartosz Sobczak } 349cdcd52d4SBartosz Sobczak 350cdcd52d4SBartosz Sobczak /** 351cdcd52d4SBartosz Sobczak * irdma_puda_poll_cmpl - processes completion for cq 352cdcd52d4SBartosz Sobczak * @dev: iwarp device 353cdcd52d4SBartosz Sobczak * @cq: cq getting interrupt 354cdcd52d4SBartosz Sobczak * @compl_err: return any completion err 355cdcd52d4SBartosz Sobczak */ 356cdcd52d4SBartosz Sobczak int 357cdcd52d4SBartosz Sobczak irdma_puda_poll_cmpl(struct irdma_sc_dev *dev, struct irdma_sc_cq *cq, 358cdcd52d4SBartosz Sobczak u32 *compl_err) 359cdcd52d4SBartosz Sobczak { 360cdcd52d4SBartosz Sobczak struct irdma_qp_uk *qp; 361cdcd52d4SBartosz Sobczak struct irdma_cq_uk *cq_uk = &cq->cq_uk; 362cdcd52d4SBartosz Sobczak struct irdma_puda_cmpl_info info = {0}; 363cdcd52d4SBartosz Sobczak int ret = 0; 364cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf; 365cdcd52d4SBartosz Sobczak struct irdma_puda_rsrc *rsrc; 366cdcd52d4SBartosz Sobczak u8 cq_type = cq->cq_type; 367cdcd52d4SBartosz Sobczak unsigned long flags; 368cdcd52d4SBartosz Sobczak 369cdcd52d4SBartosz Sobczak if (cq_type == IRDMA_CQ_TYPE_ILQ || cq_type == IRDMA_CQ_TYPE_IEQ) { 370cdcd52d4SBartosz Sobczak rsrc = (cq_type == IRDMA_CQ_TYPE_ILQ) ? cq->vsi->ilq : 371cdcd52d4SBartosz Sobczak cq->vsi->ieq; 372cdcd52d4SBartosz Sobczak } else { 373cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, "qp_type error\n"); 374cdcd52d4SBartosz Sobczak return -EFAULT; 375cdcd52d4SBartosz Sobczak } 376cdcd52d4SBartosz Sobczak 377cdcd52d4SBartosz Sobczak ret = irdma_puda_poll_info(cq, &info); 378cdcd52d4SBartosz Sobczak *compl_err = info.compl_error; 379cdcd52d4SBartosz Sobczak if (ret == -ENOENT) 380cdcd52d4SBartosz Sobczak return ret; 381cdcd52d4SBartosz Sobczak if (ret) 382cdcd52d4SBartosz Sobczak goto done; 383cdcd52d4SBartosz Sobczak 384cdcd52d4SBartosz Sobczak qp = info.qp; 385cdcd52d4SBartosz Sobczak if (!qp || !rsrc) { 386cdcd52d4SBartosz Sobczak ret = -EFAULT; 387cdcd52d4SBartosz Sobczak goto done; 388cdcd52d4SBartosz Sobczak } 389cdcd52d4SBartosz Sobczak 390cdcd52d4SBartosz Sobczak if (qp->qp_id != rsrc->qp_id) { 391cdcd52d4SBartosz Sobczak ret = -EFAULT; 392cdcd52d4SBartosz Sobczak goto done; 393cdcd52d4SBartosz Sobczak } 394cdcd52d4SBartosz Sobczak 395cdcd52d4SBartosz Sobczak if (info.q_type == IRDMA_CQE_QTYPE_RQ) { 396cdcd52d4SBartosz Sobczak buf = (struct irdma_puda_buf *)(uintptr_t) 397cdcd52d4SBartosz Sobczak qp->rq_wrid_array[info.wqe_idx]; 398cdcd52d4SBartosz Sobczak 399cdcd52d4SBartosz Sobczak /* reusing so synch the buffer for CPU use */ 400cdcd52d4SBartosz Sobczak dma_sync_single_for_cpu(hw_to_dev(dev->hw), buf->mem.pa, buf->mem.size, DMA_BIDIRECTIONAL); 401cdcd52d4SBartosz Sobczak /* Get all the tcpip information in the buf header */ 402cdcd52d4SBartosz Sobczak ret = irdma_puda_get_tcpip_info(&info, buf); 403cdcd52d4SBartosz Sobczak if (ret) { 404cdcd52d4SBartosz Sobczak rsrc->stats_rcvd_pkt_err++; 405cdcd52d4SBartosz Sobczak if (cq_type == IRDMA_CQ_TYPE_ILQ) { 406cdcd52d4SBartosz Sobczak irdma_ilq_putback_rcvbuf(&rsrc->qp, buf, 407cdcd52d4SBartosz Sobczak info.wqe_idx); 408cdcd52d4SBartosz Sobczak } else { 409cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(rsrc, buf); 410cdcd52d4SBartosz Sobczak irdma_puda_replenish_rq(rsrc, false); 411cdcd52d4SBartosz Sobczak } 412cdcd52d4SBartosz Sobczak goto done; 413cdcd52d4SBartosz Sobczak } 414cdcd52d4SBartosz Sobczak 415cdcd52d4SBartosz Sobczak rsrc->stats_pkt_rcvd++; 416cdcd52d4SBartosz Sobczak rsrc->compl_rxwqe_idx = info.wqe_idx; 417cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, "RQ completion\n"); 418cdcd52d4SBartosz Sobczak rsrc->receive(rsrc->vsi, buf); 419cdcd52d4SBartosz Sobczak if (cq_type == IRDMA_CQ_TYPE_ILQ) 420cdcd52d4SBartosz Sobczak irdma_ilq_putback_rcvbuf(&rsrc->qp, buf, info.wqe_idx); 421cdcd52d4SBartosz Sobczak else 422cdcd52d4SBartosz Sobczak irdma_puda_replenish_rq(rsrc, false); 423cdcd52d4SBartosz Sobczak 424cdcd52d4SBartosz Sobczak } else { 425cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, "SQ completion\n"); 426cdcd52d4SBartosz Sobczak buf = (struct irdma_puda_buf *)(uintptr_t) 427cdcd52d4SBartosz Sobczak qp->sq_wrtrk_array[info.wqe_idx].wrid; 428cdcd52d4SBartosz Sobczak 429cdcd52d4SBartosz Sobczak /* reusing so synch the buffer for CPU use */ 430cdcd52d4SBartosz Sobczak dma_sync_single_for_cpu(hw_to_dev(dev->hw), buf->mem.pa, buf->mem.size, DMA_BIDIRECTIONAL); 431cdcd52d4SBartosz Sobczak IRDMA_RING_SET_TAIL(qp->sq_ring, info.wqe_idx); 432cdcd52d4SBartosz Sobczak rsrc->xmit_complete(rsrc->vsi, buf); 433cdcd52d4SBartosz Sobczak spin_lock_irqsave(&rsrc->bufpool_lock, flags); 434cdcd52d4SBartosz Sobczak rsrc->tx_wqe_avail_cnt++; 435cdcd52d4SBartosz Sobczak spin_unlock_irqrestore(&rsrc->bufpool_lock, flags); 436cdcd52d4SBartosz Sobczak if (!list_empty(&rsrc->txpend)) 437cdcd52d4SBartosz Sobczak irdma_puda_send_buf(rsrc, NULL); 438cdcd52d4SBartosz Sobczak } 439cdcd52d4SBartosz Sobczak 440cdcd52d4SBartosz Sobczak done: 441cdcd52d4SBartosz Sobczak IRDMA_RING_MOVE_HEAD_NOCHECK(cq_uk->cq_ring); 442cdcd52d4SBartosz Sobczak if (!IRDMA_RING_CURRENT_HEAD(cq_uk->cq_ring)) 443cdcd52d4SBartosz Sobczak cq_uk->polarity = !cq_uk->polarity; 444cdcd52d4SBartosz Sobczak /* update cq tail in cq shadow memory also */ 445cdcd52d4SBartosz Sobczak IRDMA_RING_MOVE_TAIL(cq_uk->cq_ring); 446cdcd52d4SBartosz Sobczak set_64bit_val(cq_uk->shadow_area, IRDMA_BYTE_0, 447cdcd52d4SBartosz Sobczak IRDMA_RING_CURRENT_HEAD(cq_uk->cq_ring)); 448cdcd52d4SBartosz Sobczak 449cdcd52d4SBartosz Sobczak return ret; 450cdcd52d4SBartosz Sobczak } 451cdcd52d4SBartosz Sobczak 452cdcd52d4SBartosz Sobczak /** 453cdcd52d4SBartosz Sobczak * irdma_puda_send - complete send wqe for transmit 454cdcd52d4SBartosz Sobczak * @qp: puda qp for send 455cdcd52d4SBartosz Sobczak * @info: buffer information for transmit 456cdcd52d4SBartosz Sobczak */ 457cdcd52d4SBartosz Sobczak int 458cdcd52d4SBartosz Sobczak irdma_puda_send(struct irdma_sc_qp *qp, struct irdma_puda_send_info *info) 459cdcd52d4SBartosz Sobczak { 460cdcd52d4SBartosz Sobczak __le64 *wqe; 461cdcd52d4SBartosz Sobczak u32 iplen, l4len; 462cdcd52d4SBartosz Sobczak u64 hdr[2]; 463cdcd52d4SBartosz Sobczak u32 wqe_idx; 464cdcd52d4SBartosz Sobczak u8 iipt; 465cdcd52d4SBartosz Sobczak 466cdcd52d4SBartosz Sobczak /* number of 32 bits DWORDS in header */ 467cdcd52d4SBartosz Sobczak l4len = info->tcplen >> 2; 468cdcd52d4SBartosz Sobczak if (info->ipv4) { 469cdcd52d4SBartosz Sobczak iipt = 3; 470cdcd52d4SBartosz Sobczak iplen = 5; 471cdcd52d4SBartosz Sobczak } else { 472cdcd52d4SBartosz Sobczak iipt = 1; 473cdcd52d4SBartosz Sobczak iplen = 10; 474cdcd52d4SBartosz Sobczak } 475cdcd52d4SBartosz Sobczak 476cdcd52d4SBartosz Sobczak wqe = irdma_puda_get_next_send_wqe(&qp->qp_uk, &wqe_idx); 477cdcd52d4SBartosz Sobczak if (!wqe) 478cdcd52d4SBartosz Sobczak return -ENOSPC; 479cdcd52d4SBartosz Sobczak 480cdcd52d4SBartosz Sobczak qp->qp_uk.sq_wrtrk_array[wqe_idx].wrid = (uintptr_t)info->scratch; 481cdcd52d4SBartosz Sobczak /* Third line of WQE descriptor */ 482cdcd52d4SBartosz Sobczak /* maclen is in words */ 483cdcd52d4SBartosz Sobczak 484cdcd52d4SBartosz Sobczak if (qp->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 485cdcd52d4SBartosz Sobczak hdr[0] = 0; /* Dest_QPN and Dest_QKey only for UD */ 486777e472cSBartosz Sobczak hdr[1] = FIELD_PREP(IRDMA_UDA_QPSQ_OPCODE, IRDMA_OP_TYPE_SEND) | 487777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_L4LEN, l4len) | 488777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPSQ_AHID, info->ah_id) | 489777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_SIGCOMPL, 1) | 490777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_VALID, 491777e472cSBartosz Sobczak qp->qp_uk.swqe_polarity); 492cdcd52d4SBartosz Sobczak 493cdcd52d4SBartosz Sobczak /* Forth line of WQE descriptor */ 494cdcd52d4SBartosz Sobczak 495cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_0, info->paddr); 496cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_8, 497777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPSQ_FRAG_LEN, info->len) | 498777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_VALID, qp->qp_uk.swqe_polarity)); 499cdcd52d4SBartosz Sobczak } else { 500777e472cSBartosz Sobczak hdr[0] = FIELD_PREP(IRDMA_UDA_QPSQ_MACLEN, info->maclen >> 1) | 501777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_IPLEN, iplen) | 502777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_L4T, 1) | 503777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_IIPT, iipt) | 504777e472cSBartosz Sobczak FIELD_PREP(IRDMA_GEN1_UDA_QPSQ_L4LEN, l4len); 505cdcd52d4SBartosz Sobczak 506777e472cSBartosz Sobczak hdr[1] = FIELD_PREP(IRDMA_UDA_QPSQ_OPCODE, IRDMA_OP_TYPE_SEND) | 507777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_SIGCOMPL, 1) | 508777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_DOLOOPBACK, info->do_lpb) | 509777e472cSBartosz Sobczak FIELD_PREP(IRDMA_UDA_QPSQ_VALID, qp->qp_uk.swqe_polarity); 510cdcd52d4SBartosz Sobczak 511cdcd52d4SBartosz Sobczak /* Forth line of WQE descriptor */ 512cdcd52d4SBartosz Sobczak 513cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_0, info->paddr); 514cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_8, 515777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_LEN, info->len)); 516cdcd52d4SBartosz Sobczak } 517cdcd52d4SBartosz Sobczak 518cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_16, hdr[0]); 519cdcd52d4SBartosz Sobczak irdma_wmb(); /* make sure WQE is written before valid bit is set */ 520cdcd52d4SBartosz Sobczak 521cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_24, hdr[1]); 522cdcd52d4SBartosz Sobczak 523cdcd52d4SBartosz Sobczak irdma_debug_buf(qp->dev, IRDMA_DEBUG_PUDA, "PUDA SEND WQE", wqe, 32); 524cdcd52d4SBartosz Sobczak irdma_uk_qp_post_wr(&qp->qp_uk); 525cdcd52d4SBartosz Sobczak return 0; 526cdcd52d4SBartosz Sobczak } 527cdcd52d4SBartosz Sobczak 528cdcd52d4SBartosz Sobczak /** 529cdcd52d4SBartosz Sobczak * irdma_puda_send_buf - transmit puda buffer 530cdcd52d4SBartosz Sobczak * @rsrc: resource to use for buffer 531cdcd52d4SBartosz Sobczak * @buf: puda buffer to transmit 532cdcd52d4SBartosz Sobczak */ 533cdcd52d4SBartosz Sobczak void 534cdcd52d4SBartosz Sobczak irdma_puda_send_buf(struct irdma_puda_rsrc *rsrc, 535cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf) 536cdcd52d4SBartosz Sobczak { 537cdcd52d4SBartosz Sobczak struct irdma_puda_send_info info; 538cdcd52d4SBartosz Sobczak int ret = 0; 539cdcd52d4SBartosz Sobczak unsigned long flags; 540cdcd52d4SBartosz Sobczak 541cdcd52d4SBartosz Sobczak spin_lock_irqsave(&rsrc->bufpool_lock, flags); 542cdcd52d4SBartosz Sobczak /* 543cdcd52d4SBartosz Sobczak * if no wqe available or not from a completion and we have pending buffers, we must queue new buffer 544cdcd52d4SBartosz Sobczak */ 545cdcd52d4SBartosz Sobczak if (!rsrc->tx_wqe_avail_cnt || (buf && !list_empty(&rsrc->txpend))) { 546cdcd52d4SBartosz Sobczak list_add_tail(&buf->list, &rsrc->txpend); 547cdcd52d4SBartosz Sobczak spin_unlock_irqrestore(&rsrc->bufpool_lock, flags); 548cdcd52d4SBartosz Sobczak rsrc->stats_sent_pkt_q++; 549cdcd52d4SBartosz Sobczak if (rsrc->type == IRDMA_PUDA_RSRC_TYPE_ILQ) 550cdcd52d4SBartosz Sobczak irdma_debug(rsrc->dev, IRDMA_DEBUG_PUDA, 551cdcd52d4SBartosz Sobczak "adding to txpend\n"); 552cdcd52d4SBartosz Sobczak return; 553cdcd52d4SBartosz Sobczak } 554cdcd52d4SBartosz Sobczak rsrc->tx_wqe_avail_cnt--; 555cdcd52d4SBartosz Sobczak /* 556cdcd52d4SBartosz Sobczak * if we are coming from a completion and have pending buffers then Get one from pending list 557cdcd52d4SBartosz Sobczak */ 558cdcd52d4SBartosz Sobczak if (!buf) { 559cdcd52d4SBartosz Sobczak buf = irdma_puda_get_listbuf(&rsrc->txpend); 560cdcd52d4SBartosz Sobczak if (!buf) 561cdcd52d4SBartosz Sobczak goto done; 562cdcd52d4SBartosz Sobczak } 563cdcd52d4SBartosz Sobczak 564cdcd52d4SBartosz Sobczak info.scratch = buf; 565cdcd52d4SBartosz Sobczak info.paddr = buf->mem.pa; 566cdcd52d4SBartosz Sobczak info.len = buf->totallen; 567cdcd52d4SBartosz Sobczak info.tcplen = buf->tcphlen; 568cdcd52d4SBartosz Sobczak info.ipv4 = buf->ipv4; 569cdcd52d4SBartosz Sobczak 570cdcd52d4SBartosz Sobczak if (rsrc->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 571cdcd52d4SBartosz Sobczak info.ah_id = buf->ah_id; 572cdcd52d4SBartosz Sobczak } else { 573cdcd52d4SBartosz Sobczak info.maclen = buf->maclen; 574cdcd52d4SBartosz Sobczak info.do_lpb = buf->do_lpb; 575cdcd52d4SBartosz Sobczak } 576cdcd52d4SBartosz Sobczak 577cdcd52d4SBartosz Sobczak /* Synch buffer for use by device */ 578cdcd52d4SBartosz Sobczak dma_sync_single_for_cpu(hw_to_dev(rsrc->dev->hw), buf->mem.pa, buf->mem.size, DMA_BIDIRECTIONAL); 579cdcd52d4SBartosz Sobczak ret = irdma_puda_send(&rsrc->qp, &info); 580cdcd52d4SBartosz Sobczak if (ret) { 581cdcd52d4SBartosz Sobczak rsrc->tx_wqe_avail_cnt++; 582cdcd52d4SBartosz Sobczak rsrc->stats_sent_pkt_q++; 583cdcd52d4SBartosz Sobczak list_add(&buf->list, &rsrc->txpend); 584cdcd52d4SBartosz Sobczak if (rsrc->type == IRDMA_PUDA_RSRC_TYPE_ILQ) 585cdcd52d4SBartosz Sobczak irdma_debug(rsrc->dev, IRDMA_DEBUG_PUDA, 586cdcd52d4SBartosz Sobczak "adding to puda_send\n"); 587cdcd52d4SBartosz Sobczak } else { 588cdcd52d4SBartosz Sobczak rsrc->stats_pkt_sent++; 589cdcd52d4SBartosz Sobczak } 590cdcd52d4SBartosz Sobczak done: 591cdcd52d4SBartosz Sobczak spin_unlock_irqrestore(&rsrc->bufpool_lock, flags); 592cdcd52d4SBartosz Sobczak } 593cdcd52d4SBartosz Sobczak 594cdcd52d4SBartosz Sobczak /** 595cdcd52d4SBartosz Sobczak * irdma_puda_qp_setctx - during init, set qp's context 596cdcd52d4SBartosz Sobczak * @rsrc: qp's resource 597cdcd52d4SBartosz Sobczak */ 598cdcd52d4SBartosz Sobczak static void 599cdcd52d4SBartosz Sobczak irdma_puda_qp_setctx(struct irdma_puda_rsrc *rsrc) 600cdcd52d4SBartosz Sobczak { 601cdcd52d4SBartosz Sobczak struct irdma_sc_qp *qp = &rsrc->qp; 602cdcd52d4SBartosz Sobczak __le64 *qp_ctx = qp->hw_host_ctx; 603cdcd52d4SBartosz Sobczak 604cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_8, qp->sq_pa); 605cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_16, qp->rq_pa); 606cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_24, 607777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_RQSIZE, qp->hw_rq_size) | 608777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_SQSIZE, qp->hw_sq_size)); 609cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_48, 610777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_SNDMSS, rsrc->buf_size)); 611cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_56, 0); 612cdcd52d4SBartosz Sobczak if (qp->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) 613cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_64, 1); 614cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_136, 615777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_TXCQNUM, rsrc->cq_id) | 616777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_RXCQNUM, rsrc->cq_id)); 617cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_144, 618777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_STAT_INDEX, rsrc->stats_idx)); 619cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_160, 620777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_PRIVEN, 1) | 621777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_USESTATSINSTANCE, rsrc->stats_idx_valid)); 622cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_168, 623777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_QPCOMPCTX, (uintptr_t)qp)); 624cdcd52d4SBartosz Sobczak set_64bit_val(qp_ctx, IRDMA_BYTE_176, 625777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_SQTPHVAL, qp->sq_tph_val) | 626777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_RQTPHVAL, qp->rq_tph_val) | 627777e472cSBartosz Sobczak FIELD_PREP(IRDMAQPC_QSHANDLE, qp->qs_handle)); 628cdcd52d4SBartosz Sobczak 629cdcd52d4SBartosz Sobczak irdma_debug_buf(rsrc->dev, IRDMA_DEBUG_PUDA, "PUDA QP CONTEXT", qp_ctx, 630cdcd52d4SBartosz Sobczak IRDMA_QP_CTX_SIZE); 631cdcd52d4SBartosz Sobczak } 632cdcd52d4SBartosz Sobczak 633cdcd52d4SBartosz Sobczak /** 634cdcd52d4SBartosz Sobczak * irdma_puda_qp_wqe - setup wqe for qp create 635cdcd52d4SBartosz Sobczak * @dev: Device 636cdcd52d4SBartosz Sobczak * @qp: Resource qp 637cdcd52d4SBartosz Sobczak */ 638cdcd52d4SBartosz Sobczak static int 639cdcd52d4SBartosz Sobczak irdma_puda_qp_wqe(struct irdma_sc_dev *dev, struct irdma_sc_qp *qp) 640cdcd52d4SBartosz Sobczak { 641cdcd52d4SBartosz Sobczak struct irdma_sc_cqp *cqp; 642cdcd52d4SBartosz Sobczak __le64 *wqe; 643cdcd52d4SBartosz Sobczak u64 hdr; 644cdcd52d4SBartosz Sobczak struct irdma_ccq_cqe_info compl_info; 645cdcd52d4SBartosz Sobczak int status = 0; 646cdcd52d4SBartosz Sobczak 647cdcd52d4SBartosz Sobczak cqp = dev->cqp; 648cdcd52d4SBartosz Sobczak wqe = irdma_sc_cqp_get_next_send_wqe(cqp, 0); 649cdcd52d4SBartosz Sobczak if (!wqe) 650cdcd52d4SBartosz Sobczak return -ENOSPC; 651cdcd52d4SBartosz Sobczak 652cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_16, qp->hw_host_ctx_pa); 653cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_40, qp->shadow_area_pa); 654cdcd52d4SBartosz Sobczak 655cdcd52d4SBartosz Sobczak hdr = qp->qp_uk.qp_id | 656777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_QP) | 657777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_QP_QPTYPE, IRDMA_QP_TYPE_UDA) | 658777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_QP_CQNUMVALID, 1) | 659777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_QP_NEXTIWSTATE, 2) | 660777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 661cdcd52d4SBartosz Sobczak irdma_wmb(); /* make sure WQE is written before valid bit is set */ 662cdcd52d4SBartosz Sobczak 663cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_24, hdr); 664cdcd52d4SBartosz Sobczak 665cdcd52d4SBartosz Sobczak irdma_debug_buf(cqp->dev, IRDMA_DEBUG_PUDA, "PUDA QP CREATE", wqe, 40); 666cdcd52d4SBartosz Sobczak irdma_sc_cqp_post_sq(cqp); 667cdcd52d4SBartosz Sobczak status = irdma_sc_poll_for_cqp_op_done(dev->cqp, IRDMA_CQP_OP_CREATE_QP, 668cdcd52d4SBartosz Sobczak &compl_info); 669cdcd52d4SBartosz Sobczak 670cdcd52d4SBartosz Sobczak return status; 671cdcd52d4SBartosz Sobczak } 672cdcd52d4SBartosz Sobczak 673cdcd52d4SBartosz Sobczak /** 674cdcd52d4SBartosz Sobczak * irdma_puda_qp_create - create qp for resource 675cdcd52d4SBartosz Sobczak * @rsrc: resource to use for buffer 676cdcd52d4SBartosz Sobczak */ 677cdcd52d4SBartosz Sobczak static int 678cdcd52d4SBartosz Sobczak irdma_puda_qp_create(struct irdma_puda_rsrc *rsrc) 679cdcd52d4SBartosz Sobczak { 680cdcd52d4SBartosz Sobczak struct irdma_sc_qp *qp = &rsrc->qp; 681cdcd52d4SBartosz Sobczak struct irdma_qp_uk *ukqp = &qp->qp_uk; 682cdcd52d4SBartosz Sobczak int ret = 0; 683cdcd52d4SBartosz Sobczak u32 sq_size, rq_size; 684cdcd52d4SBartosz Sobczak struct irdma_dma_mem *mem; 685cdcd52d4SBartosz Sobczak 686cdcd52d4SBartosz Sobczak sq_size = rsrc->sq_size * IRDMA_QP_WQE_MIN_SIZE; 687cdcd52d4SBartosz Sobczak rq_size = rsrc->rq_size * IRDMA_QP_WQE_MIN_SIZE; 688cdcd52d4SBartosz Sobczak rsrc->qpmem.size = (sq_size + rq_size + (IRDMA_SHADOW_AREA_SIZE << 3) + 689cdcd52d4SBartosz Sobczak IRDMA_QP_CTX_SIZE); 690cdcd52d4SBartosz Sobczak rsrc->qpmem.va = irdma_allocate_dma_mem(rsrc->dev->hw, &rsrc->qpmem, 691cdcd52d4SBartosz Sobczak rsrc->qpmem.size, IRDMA_HW_PAGE_SIZE); 692cdcd52d4SBartosz Sobczak if (!rsrc->qpmem.va) 693cdcd52d4SBartosz Sobczak return -ENOMEM; 694cdcd52d4SBartosz Sobczak 695cdcd52d4SBartosz Sobczak mem = &rsrc->qpmem; 696cdcd52d4SBartosz Sobczak memset(mem->va, 0, rsrc->qpmem.size); 697cdcd52d4SBartosz Sobczak qp->hw_sq_size = irdma_get_encoded_wqe_size(rsrc->sq_size, IRDMA_QUEUE_TYPE_SQ_RQ); 698cdcd52d4SBartosz Sobczak qp->hw_rq_size = irdma_get_encoded_wqe_size(rsrc->rq_size, IRDMA_QUEUE_TYPE_SQ_RQ); 699cdcd52d4SBartosz Sobczak qp->pd = &rsrc->sc_pd; 700cdcd52d4SBartosz Sobczak qp->qp_uk.qp_type = IRDMA_QP_TYPE_UDA; 701cdcd52d4SBartosz Sobczak qp->dev = rsrc->dev; 702cdcd52d4SBartosz Sobczak qp->qp_uk.back_qp = rsrc; 703cdcd52d4SBartosz Sobczak qp->sq_pa = mem->pa; 704cdcd52d4SBartosz Sobczak qp->rq_pa = qp->sq_pa + sq_size; 705cdcd52d4SBartosz Sobczak qp->vsi = rsrc->vsi; 706cdcd52d4SBartosz Sobczak ukqp->sq_base = mem->va; 707cdcd52d4SBartosz Sobczak ukqp->rq_base = &ukqp->sq_base[rsrc->sq_size]; 708cdcd52d4SBartosz Sobczak ukqp->shadow_area = ukqp->rq_base[rsrc->rq_size].elem; 709cdcd52d4SBartosz Sobczak ukqp->uk_attrs = &qp->dev->hw_attrs.uk_attrs; 710cdcd52d4SBartosz Sobczak qp->shadow_area_pa = qp->rq_pa + rq_size; 711cdcd52d4SBartosz Sobczak qp->hw_host_ctx = ukqp->shadow_area + IRDMA_SHADOW_AREA_SIZE; 712cdcd52d4SBartosz Sobczak qp->hw_host_ctx_pa = qp->shadow_area_pa + (IRDMA_SHADOW_AREA_SIZE << 3); 713cdcd52d4SBartosz Sobczak qp->push_idx = IRDMA_INVALID_PUSH_PAGE_INDEX; 714cdcd52d4SBartosz Sobczak ukqp->qp_id = rsrc->qp_id; 715cdcd52d4SBartosz Sobczak ukqp->sq_wrtrk_array = rsrc->sq_wrtrk_array; 716cdcd52d4SBartosz Sobczak ukqp->rq_wrid_array = rsrc->rq_wrid_array; 717cdcd52d4SBartosz Sobczak ukqp->sq_size = rsrc->sq_size; 718cdcd52d4SBartosz Sobczak ukqp->rq_size = rsrc->rq_size; 719cdcd52d4SBartosz Sobczak 720cdcd52d4SBartosz Sobczak IRDMA_RING_INIT(ukqp->sq_ring, ukqp->sq_size); 721cdcd52d4SBartosz Sobczak IRDMA_RING_INIT(ukqp->initial_ring, ukqp->sq_size); 722cdcd52d4SBartosz Sobczak IRDMA_RING_INIT(ukqp->rq_ring, ukqp->rq_size); 723cdcd52d4SBartosz Sobczak ukqp->wqe_alloc_db = qp->pd->dev->wqe_alloc_db; 724cdcd52d4SBartosz Sobczak 725cdcd52d4SBartosz Sobczak ret = rsrc->dev->ws_add(qp->vsi, qp->user_pri); 726cdcd52d4SBartosz Sobczak if (ret) { 727cdcd52d4SBartosz Sobczak irdma_free_dma_mem(rsrc->dev->hw, &rsrc->qpmem); 728cdcd52d4SBartosz Sobczak return ret; 729cdcd52d4SBartosz Sobczak } 730cdcd52d4SBartosz Sobczak 731cdcd52d4SBartosz Sobczak irdma_qp_add_qos(qp); 732cdcd52d4SBartosz Sobczak irdma_puda_qp_setctx(rsrc); 733cdcd52d4SBartosz Sobczak 734cdcd52d4SBartosz Sobczak if (rsrc->dev->ceq_valid) 735cdcd52d4SBartosz Sobczak ret = irdma_cqp_qp_create_cmd(rsrc->dev, qp); 736cdcd52d4SBartosz Sobczak else 737cdcd52d4SBartosz Sobczak ret = irdma_puda_qp_wqe(rsrc->dev, qp); 738cdcd52d4SBartosz Sobczak if (ret) { 739cdcd52d4SBartosz Sobczak irdma_qp_rem_qos(qp); 740cdcd52d4SBartosz Sobczak rsrc->dev->ws_remove(qp->vsi, qp->user_pri); 741cdcd52d4SBartosz Sobczak irdma_free_dma_mem(rsrc->dev->hw, &rsrc->qpmem); 742cdcd52d4SBartosz Sobczak } 743cdcd52d4SBartosz Sobczak 744cdcd52d4SBartosz Sobczak return ret; 745cdcd52d4SBartosz Sobczak } 746cdcd52d4SBartosz Sobczak 747cdcd52d4SBartosz Sobczak /** 748cdcd52d4SBartosz Sobczak * irdma_puda_cq_wqe - setup wqe for CQ create 749cdcd52d4SBartosz Sobczak * @dev: Device 750cdcd52d4SBartosz Sobczak * @cq: resource for cq 751cdcd52d4SBartosz Sobczak */ 752cdcd52d4SBartosz Sobczak static int 753cdcd52d4SBartosz Sobczak irdma_puda_cq_wqe(struct irdma_sc_dev *dev, struct irdma_sc_cq *cq) 754cdcd52d4SBartosz Sobczak { 755cdcd52d4SBartosz Sobczak __le64 *wqe; 756cdcd52d4SBartosz Sobczak struct irdma_sc_cqp *cqp; 757cdcd52d4SBartosz Sobczak u64 hdr; 758cdcd52d4SBartosz Sobczak struct irdma_ccq_cqe_info compl_info; 759cdcd52d4SBartosz Sobczak int status = 0; 760cdcd52d4SBartosz Sobczak 761cdcd52d4SBartosz Sobczak cqp = dev->cqp; 762cdcd52d4SBartosz Sobczak wqe = irdma_sc_cqp_get_next_send_wqe(cqp, 0); 763cdcd52d4SBartosz Sobczak if (!wqe) 764cdcd52d4SBartosz Sobczak return -ENOSPC; 765cdcd52d4SBartosz Sobczak 766cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_0, cq->cq_uk.cq_size); 767cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_8, RS_64_1(cq, 1)); 768cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_16, 769777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD, cq->shadow_read_threshold)); 770cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_32, cq->cq_pa); 771cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_40, cq->shadow_area_pa); 772cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_56, 773777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_TPHVAL, cq->tph_val) | 774777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_VSIIDX, cq->vsi->vsi_idx)); 775cdcd52d4SBartosz Sobczak 776cdcd52d4SBartosz Sobczak hdr = cq->cq_uk.cq_id | 777777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_CQ) | 778777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_CQ_CHKOVERFLOW, 1) | 779777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, 1) | 780777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_CQ_CEQIDVALID, 1) | 781777e472cSBartosz Sobczak FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 782cdcd52d4SBartosz Sobczak irdma_wmb(); /* make sure WQE is written before valid bit is set */ 783cdcd52d4SBartosz Sobczak 784cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_24, hdr); 785cdcd52d4SBartosz Sobczak 786cdcd52d4SBartosz Sobczak irdma_debug_buf(dev, IRDMA_DEBUG_PUDA, "PUDA CREATE CQ", wqe, 787cdcd52d4SBartosz Sobczak IRDMA_CQP_WQE_SIZE * 8); 788cdcd52d4SBartosz Sobczak irdma_sc_cqp_post_sq(dev->cqp); 789cdcd52d4SBartosz Sobczak status = irdma_sc_poll_for_cqp_op_done(dev->cqp, IRDMA_CQP_OP_CREATE_CQ, 790cdcd52d4SBartosz Sobczak &compl_info); 791cdcd52d4SBartosz Sobczak if (!status) { 792cdcd52d4SBartosz Sobczak struct irdma_sc_ceq *ceq = dev->ceq[0]; 793cdcd52d4SBartosz Sobczak 794cdcd52d4SBartosz Sobczak if (ceq && ceq->reg_cq) 795cdcd52d4SBartosz Sobczak status = irdma_sc_add_cq_ctx(ceq, cq); 796cdcd52d4SBartosz Sobczak } 797cdcd52d4SBartosz Sobczak 798cdcd52d4SBartosz Sobczak return status; 799cdcd52d4SBartosz Sobczak } 800cdcd52d4SBartosz Sobczak 801cdcd52d4SBartosz Sobczak /** 802cdcd52d4SBartosz Sobczak * irdma_puda_cq_create - create cq for resource 803cdcd52d4SBartosz Sobczak * @rsrc: resource for which cq to create 804cdcd52d4SBartosz Sobczak */ 805cdcd52d4SBartosz Sobczak static int 806cdcd52d4SBartosz Sobczak irdma_puda_cq_create(struct irdma_puda_rsrc *rsrc) 807cdcd52d4SBartosz Sobczak { 808cdcd52d4SBartosz Sobczak struct irdma_sc_dev *dev = rsrc->dev; 809cdcd52d4SBartosz Sobczak struct irdma_sc_cq *cq = &rsrc->cq; 810cdcd52d4SBartosz Sobczak int ret = 0; 811cdcd52d4SBartosz Sobczak u32 cqsize; 812cdcd52d4SBartosz Sobczak struct irdma_dma_mem *mem; 813cdcd52d4SBartosz Sobczak struct irdma_cq_init_info info = {0}; 814cdcd52d4SBartosz Sobczak struct irdma_cq_uk_init_info *init_info = &info.cq_uk_init_info; 815cdcd52d4SBartosz Sobczak 816cdcd52d4SBartosz Sobczak cq->vsi = rsrc->vsi; 817cdcd52d4SBartosz Sobczak cqsize = rsrc->cq_size * (sizeof(struct irdma_cqe)); 818cdcd52d4SBartosz Sobczak rsrc->cqmem.size = cqsize + sizeof(struct irdma_cq_shadow_area); 819cdcd52d4SBartosz Sobczak rsrc->cqmem.va = irdma_allocate_dma_mem(dev->hw, &rsrc->cqmem, 820cdcd52d4SBartosz Sobczak rsrc->cqmem.size, 821cdcd52d4SBartosz Sobczak IRDMA_CQ0_ALIGNMENT); 822cdcd52d4SBartosz Sobczak if (!rsrc->cqmem.va) 823cdcd52d4SBartosz Sobczak return -ENOMEM; 824cdcd52d4SBartosz Sobczak 825cdcd52d4SBartosz Sobczak mem = &rsrc->cqmem; 826cdcd52d4SBartosz Sobczak info.dev = dev; 827cdcd52d4SBartosz Sobczak info.type = (rsrc->type == IRDMA_PUDA_RSRC_TYPE_ILQ) ? 828cdcd52d4SBartosz Sobczak IRDMA_CQ_TYPE_ILQ : IRDMA_CQ_TYPE_IEQ; 829cdcd52d4SBartosz Sobczak info.shadow_read_threshold = rsrc->cq_size >> 2; 830cdcd52d4SBartosz Sobczak info.cq_base_pa = mem->pa; 831cdcd52d4SBartosz Sobczak info.shadow_area_pa = mem->pa + cqsize; 832cdcd52d4SBartosz Sobczak init_info->cq_base = mem->va; 833cdcd52d4SBartosz Sobczak init_info->shadow_area = (__le64 *) ((u8 *)mem->va + cqsize); 834cdcd52d4SBartosz Sobczak init_info->cq_size = rsrc->cq_size; 835cdcd52d4SBartosz Sobczak init_info->cq_id = rsrc->cq_id; 836cdcd52d4SBartosz Sobczak info.ceqe_mask = true; 837cdcd52d4SBartosz Sobczak info.ceq_id_valid = true; 838cdcd52d4SBartosz Sobczak info.vsi = rsrc->vsi; 839cdcd52d4SBartosz Sobczak 840cdcd52d4SBartosz Sobczak ret = irdma_sc_cq_init(cq, &info); 841cdcd52d4SBartosz Sobczak if (ret) 842cdcd52d4SBartosz Sobczak goto error; 843cdcd52d4SBartosz Sobczak 844cdcd52d4SBartosz Sobczak if (rsrc->dev->ceq_valid) 845cdcd52d4SBartosz Sobczak ret = irdma_cqp_cq_create_cmd(dev, cq); 846cdcd52d4SBartosz Sobczak else 847cdcd52d4SBartosz Sobczak ret = irdma_puda_cq_wqe(dev, cq); 848cdcd52d4SBartosz Sobczak error: 849cdcd52d4SBartosz Sobczak if (ret) 850cdcd52d4SBartosz Sobczak irdma_free_dma_mem(dev->hw, &rsrc->cqmem); 851cdcd52d4SBartosz Sobczak 852cdcd52d4SBartosz Sobczak return ret; 853cdcd52d4SBartosz Sobczak } 854cdcd52d4SBartosz Sobczak 855cdcd52d4SBartosz Sobczak /** 856cdcd52d4SBartosz Sobczak * irdma_puda_free_qp - free qp for resource 857cdcd52d4SBartosz Sobczak * @rsrc: resource for which qp to free 858cdcd52d4SBartosz Sobczak */ 859cdcd52d4SBartosz Sobczak static void 860cdcd52d4SBartosz Sobczak irdma_puda_free_qp(struct irdma_puda_rsrc *rsrc) 861cdcd52d4SBartosz Sobczak { 862cdcd52d4SBartosz Sobczak int ret; 863cdcd52d4SBartosz Sobczak struct irdma_ccq_cqe_info compl_info; 864cdcd52d4SBartosz Sobczak struct irdma_sc_dev *dev = rsrc->dev; 865cdcd52d4SBartosz Sobczak 866cdcd52d4SBartosz Sobczak if (rsrc->dev->ceq_valid) { 867cdcd52d4SBartosz Sobczak irdma_cqp_qp_destroy_cmd(dev, &rsrc->qp); 868cdcd52d4SBartosz Sobczak rsrc->dev->ws_remove(rsrc->qp.vsi, rsrc->qp.user_pri); 869cdcd52d4SBartosz Sobczak return; 870cdcd52d4SBartosz Sobczak } 871cdcd52d4SBartosz Sobczak 872cdcd52d4SBartosz Sobczak ret = irdma_sc_qp_destroy(&rsrc->qp, 0, false, true, true); 873cdcd52d4SBartosz Sobczak if (ret) 874cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, 875cdcd52d4SBartosz Sobczak "error puda qp destroy wqe, status = %d\n", ret); 876cdcd52d4SBartosz Sobczak if (!ret) { 877cdcd52d4SBartosz Sobczak ret = irdma_sc_poll_for_cqp_op_done(dev->cqp, IRDMA_CQP_OP_DESTROY_QP, 878cdcd52d4SBartosz Sobczak &compl_info); 879cdcd52d4SBartosz Sobczak if (ret) 880cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, 881cdcd52d4SBartosz Sobczak "error puda qp destroy failed, status = %d\n", 882cdcd52d4SBartosz Sobczak ret); 883cdcd52d4SBartosz Sobczak } 884cdcd52d4SBartosz Sobczak rsrc->dev->ws_remove(rsrc->qp.vsi, rsrc->qp.user_pri); 885cdcd52d4SBartosz Sobczak } 886cdcd52d4SBartosz Sobczak 887cdcd52d4SBartosz Sobczak /** 888cdcd52d4SBartosz Sobczak * irdma_puda_free_cq - free cq for resource 889cdcd52d4SBartosz Sobczak * @rsrc: resource for which cq to free 890cdcd52d4SBartosz Sobczak */ 891cdcd52d4SBartosz Sobczak static void 892cdcd52d4SBartosz Sobczak irdma_puda_free_cq(struct irdma_puda_rsrc *rsrc) 893cdcd52d4SBartosz Sobczak { 894cdcd52d4SBartosz Sobczak int ret; 895cdcd52d4SBartosz Sobczak struct irdma_ccq_cqe_info compl_info; 896cdcd52d4SBartosz Sobczak struct irdma_sc_dev *dev = rsrc->dev; 897cdcd52d4SBartosz Sobczak 898cdcd52d4SBartosz Sobczak if (rsrc->dev->ceq_valid) { 899cdcd52d4SBartosz Sobczak irdma_cqp_cq_destroy_cmd(dev, &rsrc->cq); 900cdcd52d4SBartosz Sobczak return; 901cdcd52d4SBartosz Sobczak } 902cdcd52d4SBartosz Sobczak 903cdcd52d4SBartosz Sobczak ret = irdma_sc_cq_destroy(&rsrc->cq, 0, true); 904cdcd52d4SBartosz Sobczak if (ret) 905cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, "error ieq cq destroy\n"); 906cdcd52d4SBartosz Sobczak if (!ret) { 907cdcd52d4SBartosz Sobczak ret = irdma_sc_poll_for_cqp_op_done(dev->cqp, IRDMA_CQP_OP_DESTROY_CQ, 908cdcd52d4SBartosz Sobczak &compl_info); 909cdcd52d4SBartosz Sobczak if (ret) 910cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, 911cdcd52d4SBartosz Sobczak "error ieq qp destroy done\n"); 912cdcd52d4SBartosz Sobczak } 913cdcd52d4SBartosz Sobczak } 914cdcd52d4SBartosz Sobczak 915cdcd52d4SBartosz Sobczak /** 916cdcd52d4SBartosz Sobczak * irdma_puda_dele_rsrc - delete all resources during close 917cdcd52d4SBartosz Sobczak * @vsi: VSI structure of device 918cdcd52d4SBartosz Sobczak * @type: type of resource to dele 919cdcd52d4SBartosz Sobczak * @reset: true if reset chip 920cdcd52d4SBartosz Sobczak */ 921cdcd52d4SBartosz Sobczak void 922cdcd52d4SBartosz Sobczak irdma_puda_dele_rsrc(struct irdma_sc_vsi *vsi, enum puda_rsrc_type type, 923cdcd52d4SBartosz Sobczak bool reset) 924cdcd52d4SBartosz Sobczak { 925cdcd52d4SBartosz Sobczak struct irdma_sc_dev *dev = vsi->dev; 926cdcd52d4SBartosz Sobczak struct irdma_puda_rsrc *rsrc; 927cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf = NULL; 928cdcd52d4SBartosz Sobczak struct irdma_puda_buf *nextbuf = NULL; 929cdcd52d4SBartosz Sobczak struct irdma_virt_mem *vmem; 930cdcd52d4SBartosz Sobczak struct irdma_sc_ceq *ceq; 931cdcd52d4SBartosz Sobczak 932cdcd52d4SBartosz Sobczak ceq = vsi->dev->ceq[0]; 933cdcd52d4SBartosz Sobczak switch (type) { 934cdcd52d4SBartosz Sobczak case IRDMA_PUDA_RSRC_TYPE_ILQ: 935cdcd52d4SBartosz Sobczak rsrc = vsi->ilq; 936cdcd52d4SBartosz Sobczak vmem = &vsi->ilq_mem; 937cdcd52d4SBartosz Sobczak vsi->ilq = NULL; 938cdcd52d4SBartosz Sobczak if (ceq && ceq->reg_cq) 939cdcd52d4SBartosz Sobczak irdma_sc_remove_cq_ctx(ceq, &rsrc->cq); 940cdcd52d4SBartosz Sobczak break; 941cdcd52d4SBartosz Sobczak case IRDMA_PUDA_RSRC_TYPE_IEQ: 942cdcd52d4SBartosz Sobczak rsrc = vsi->ieq; 943cdcd52d4SBartosz Sobczak vmem = &vsi->ieq_mem; 944cdcd52d4SBartosz Sobczak vsi->ieq = NULL; 945cdcd52d4SBartosz Sobczak if (ceq && ceq->reg_cq) 946cdcd52d4SBartosz Sobczak irdma_sc_remove_cq_ctx(ceq, &rsrc->cq); 947cdcd52d4SBartosz Sobczak break; 948cdcd52d4SBartosz Sobczak default: 949cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, 950cdcd52d4SBartosz Sobczak "error resource type = 0x%x\n", type); 951cdcd52d4SBartosz Sobczak return; 952cdcd52d4SBartosz Sobczak } 953cdcd52d4SBartosz Sobczak 954cdcd52d4SBartosz Sobczak spin_lock_destroy(&rsrc->bufpool_lock); 955cdcd52d4SBartosz Sobczak switch (rsrc->cmpl) { 956cdcd52d4SBartosz Sobczak case PUDA_HASH_CRC_COMPLETE: 957cdcd52d4SBartosz Sobczak irdma_free_hash_desc(rsrc->hash_desc); 958cdcd52d4SBartosz Sobczak /* fallthrough */ 959cdcd52d4SBartosz Sobczak case PUDA_QP_CREATED: 960cdcd52d4SBartosz Sobczak irdma_qp_rem_qos(&rsrc->qp); 961cdcd52d4SBartosz Sobczak 962777e472cSBartosz Sobczak if (!reset) 963cdcd52d4SBartosz Sobczak irdma_puda_free_qp(rsrc); 964cdcd52d4SBartosz Sobczak 965cdcd52d4SBartosz Sobczak irdma_free_dma_mem(dev->hw, &rsrc->qpmem); 966cdcd52d4SBartosz Sobczak /* fallthrough */ 967cdcd52d4SBartosz Sobczak case PUDA_CQ_CREATED: 968777e472cSBartosz Sobczak if (!reset) 969cdcd52d4SBartosz Sobczak irdma_puda_free_cq(rsrc); 970cdcd52d4SBartosz Sobczak 971cdcd52d4SBartosz Sobczak irdma_free_dma_mem(dev->hw, &rsrc->cqmem); 972cdcd52d4SBartosz Sobczak break; 973cdcd52d4SBartosz Sobczak default: 974cdcd52d4SBartosz Sobczak irdma_debug(rsrc->dev, IRDMA_DEBUG_PUDA, 975cdcd52d4SBartosz Sobczak "error no resources\n"); 976cdcd52d4SBartosz Sobczak break; 977cdcd52d4SBartosz Sobczak } 978cdcd52d4SBartosz Sobczak /* Free all allocated puda buffers for both tx and rx */ 979cdcd52d4SBartosz Sobczak buf = rsrc->alloclist; 980cdcd52d4SBartosz Sobczak while (buf) { 981cdcd52d4SBartosz Sobczak nextbuf = buf->next; 982cdcd52d4SBartosz Sobczak irdma_puda_dele_buf(dev, buf); 983cdcd52d4SBartosz Sobczak buf = nextbuf; 984cdcd52d4SBartosz Sobczak rsrc->alloc_buf_count--; 985cdcd52d4SBartosz Sobczak } 986cdcd52d4SBartosz Sobczak 987cdcd52d4SBartosz Sobczak kfree(vmem->va); 988cdcd52d4SBartosz Sobczak } 989cdcd52d4SBartosz Sobczak 990cdcd52d4SBartosz Sobczak /** 991cdcd52d4SBartosz Sobczak * irdma_puda_allocbufs - allocate buffers for resource 992cdcd52d4SBartosz Sobczak * @rsrc: resource for buffer allocation 993cdcd52d4SBartosz Sobczak * @count: number of buffers to create 994cdcd52d4SBartosz Sobczak */ 995cdcd52d4SBartosz Sobczak static int 996cdcd52d4SBartosz Sobczak irdma_puda_allocbufs(struct irdma_puda_rsrc *rsrc, u32 count) 997cdcd52d4SBartosz Sobczak { 998cdcd52d4SBartosz Sobczak u32 i; 999cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf; 1000cdcd52d4SBartosz Sobczak struct irdma_puda_buf *nextbuf; 1001cdcd52d4SBartosz Sobczak struct irdma_virt_mem buf_mem; 1002cdcd52d4SBartosz Sobczak struct irdma_dma_mem *dma_mem; 1003cdcd52d4SBartosz Sobczak bool virtdma = false; 1004cdcd52d4SBartosz Sobczak unsigned long flags; 1005cdcd52d4SBartosz Sobczak 1006cdcd52d4SBartosz Sobczak buf_mem.size = count * sizeof(struct irdma_puda_buf); 1007777e472cSBartosz Sobczak buf_mem.va = kzalloc(buf_mem.size, GFP_KERNEL); 1008cdcd52d4SBartosz Sobczak if (!buf_mem.va) { 1009cdcd52d4SBartosz Sobczak irdma_debug(rsrc->dev, IRDMA_DEBUG_PUDA, 1010cdcd52d4SBartosz Sobczak "error virt_mem for buf\n"); 1011cdcd52d4SBartosz Sobczak rsrc->stats_buf_alloc_fail++; 1012cdcd52d4SBartosz Sobczak goto trysmall; 1013cdcd52d4SBartosz Sobczak } 1014cdcd52d4SBartosz Sobczak 1015cdcd52d4SBartosz Sobczak /* 1016cdcd52d4SBartosz Sobczak * Allocate the large dma chunk and setup dma attributes into first puda buffer. This is required during free 1017cdcd52d4SBartosz Sobczak */ 1018cdcd52d4SBartosz Sobczak buf = (struct irdma_puda_buf *)buf_mem.va; 1019cdcd52d4SBartosz Sobczak buf->mem.va = irdma_allocate_dma_mem(rsrc->dev->hw, &buf->mem, 1020cdcd52d4SBartosz Sobczak rsrc->buf_size * count, 1); 1021cdcd52d4SBartosz Sobczak if (!buf->mem.va) { 1022cdcd52d4SBartosz Sobczak irdma_debug(rsrc->dev, IRDMA_DEBUG_PUDA, 1023cdcd52d4SBartosz Sobczak "error dma_mem for buf\n"); 1024cdcd52d4SBartosz Sobczak kfree(buf_mem.va); 1025cdcd52d4SBartosz Sobczak rsrc->stats_buf_alloc_fail++; 1026cdcd52d4SBartosz Sobczak goto trysmall; 1027cdcd52d4SBartosz Sobczak } 1028cdcd52d4SBartosz Sobczak 1029cdcd52d4SBartosz Sobczak /* 1030cdcd52d4SBartosz Sobczak * dma_mem points to start of the large DMA chunk 1031cdcd52d4SBartosz Sobczak */ 1032cdcd52d4SBartosz Sobczak dma_mem = &buf->mem; 1033cdcd52d4SBartosz Sobczak 1034cdcd52d4SBartosz Sobczak spin_lock_irqsave(&rsrc->bufpool_lock, flags); 1035cdcd52d4SBartosz Sobczak for (i = 0; i < count; i++) { 1036cdcd52d4SBartosz Sobczak buf = ((struct irdma_puda_buf *)buf_mem.va) + i; 1037cdcd52d4SBartosz Sobczak 1038cdcd52d4SBartosz Sobczak buf->mem.va = (char *)dma_mem->va + (i * rsrc->buf_size); 1039cdcd52d4SBartosz Sobczak buf->mem.pa = dma_mem->pa + (i * rsrc->buf_size); 1040cdcd52d4SBartosz Sobczak buf->mem.size = rsrc->buf_size; 1041cdcd52d4SBartosz Sobczak buf->virtdma = virtdma; 1042cdcd52d4SBartosz Sobczak virtdma = true; 1043cdcd52d4SBartosz Sobczak 1044cdcd52d4SBartosz Sobczak buf->buf_mem.va = buf_mem.va; 1045cdcd52d4SBartosz Sobczak buf->buf_mem.size = buf_mem.size; 1046cdcd52d4SBartosz Sobczak 1047cdcd52d4SBartosz Sobczak list_add(&buf->list, &rsrc->bufpool); 1048cdcd52d4SBartosz Sobczak rsrc->alloc_buf_count++; 1049cdcd52d4SBartosz Sobczak if (!rsrc->alloclist) { 1050cdcd52d4SBartosz Sobczak rsrc->alloclist = buf; 1051cdcd52d4SBartosz Sobczak } else { 1052cdcd52d4SBartosz Sobczak nextbuf = rsrc->alloclist; 1053cdcd52d4SBartosz Sobczak rsrc->alloclist = buf; 1054cdcd52d4SBartosz Sobczak buf->next = nextbuf; 1055cdcd52d4SBartosz Sobczak } 1056cdcd52d4SBartosz Sobczak } 1057cdcd52d4SBartosz Sobczak spin_unlock_irqrestore(&rsrc->bufpool_lock, flags); 1058cdcd52d4SBartosz Sobczak 1059cdcd52d4SBartosz Sobczak rsrc->avail_buf_count = rsrc->alloc_buf_count; 1060cdcd52d4SBartosz Sobczak return 0; 1061cdcd52d4SBartosz Sobczak trysmall: 1062cdcd52d4SBartosz Sobczak for (i = 0; i < count; i++) { 1063cdcd52d4SBartosz Sobczak buf = irdma_puda_alloc_buf(rsrc->dev, rsrc->buf_size); 1064cdcd52d4SBartosz Sobczak if (!buf) { 1065cdcd52d4SBartosz Sobczak rsrc->stats_buf_alloc_fail++; 1066cdcd52d4SBartosz Sobczak return -ENOMEM; 1067cdcd52d4SBartosz Sobczak } 1068cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(rsrc, buf); 1069cdcd52d4SBartosz Sobczak rsrc->alloc_buf_count++; 1070cdcd52d4SBartosz Sobczak if (!rsrc->alloclist) { 1071cdcd52d4SBartosz Sobczak rsrc->alloclist = buf; 1072cdcd52d4SBartosz Sobczak } else { 1073cdcd52d4SBartosz Sobczak nextbuf = rsrc->alloclist; 1074cdcd52d4SBartosz Sobczak rsrc->alloclist = buf; 1075cdcd52d4SBartosz Sobczak buf->next = nextbuf; 1076cdcd52d4SBartosz Sobczak } 1077cdcd52d4SBartosz Sobczak } 1078cdcd52d4SBartosz Sobczak 1079cdcd52d4SBartosz Sobczak rsrc->avail_buf_count = rsrc->alloc_buf_count; 1080cdcd52d4SBartosz Sobczak 1081cdcd52d4SBartosz Sobczak return 0; 1082cdcd52d4SBartosz Sobczak } 1083cdcd52d4SBartosz Sobczak 1084cdcd52d4SBartosz Sobczak /** 1085cdcd52d4SBartosz Sobczak * irdma_puda_create_rsrc - create resource (ilq or ieq) 1086cdcd52d4SBartosz Sobczak * @vsi: sc VSI struct 1087cdcd52d4SBartosz Sobczak * @info: resource information 1088cdcd52d4SBartosz Sobczak */ 1089cdcd52d4SBartosz Sobczak int 1090cdcd52d4SBartosz Sobczak irdma_puda_create_rsrc(struct irdma_sc_vsi *vsi, 1091cdcd52d4SBartosz Sobczak struct irdma_puda_rsrc_info *info) 1092cdcd52d4SBartosz Sobczak { 1093cdcd52d4SBartosz Sobczak struct irdma_sc_dev *dev = vsi->dev; 1094cdcd52d4SBartosz Sobczak int ret = 0; 1095cdcd52d4SBartosz Sobczak struct irdma_puda_rsrc *rsrc; 1096cdcd52d4SBartosz Sobczak u32 pudasize; 1097cdcd52d4SBartosz Sobczak u32 sqwridsize, rqwridsize; 1098cdcd52d4SBartosz Sobczak struct irdma_virt_mem *vmem; 1099cdcd52d4SBartosz Sobczak 1100cdcd52d4SBartosz Sobczak info->count = 1; 1101cdcd52d4SBartosz Sobczak pudasize = sizeof(struct irdma_puda_rsrc); 1102cdcd52d4SBartosz Sobczak sqwridsize = info->sq_size * sizeof(struct irdma_sq_uk_wr_trk_info); 1103cdcd52d4SBartosz Sobczak rqwridsize = info->rq_size * 8; 1104cdcd52d4SBartosz Sobczak switch (info->type) { 1105cdcd52d4SBartosz Sobczak case IRDMA_PUDA_RSRC_TYPE_ILQ: 1106cdcd52d4SBartosz Sobczak vmem = &vsi->ilq_mem; 1107cdcd52d4SBartosz Sobczak break; 1108cdcd52d4SBartosz Sobczak case IRDMA_PUDA_RSRC_TYPE_IEQ: 1109cdcd52d4SBartosz Sobczak vmem = &vsi->ieq_mem; 1110cdcd52d4SBartosz Sobczak break; 1111cdcd52d4SBartosz Sobczak default: 1112cdcd52d4SBartosz Sobczak return -EOPNOTSUPP; 1113cdcd52d4SBartosz Sobczak } 1114cdcd52d4SBartosz Sobczak vmem->size = pudasize + sqwridsize + rqwridsize; 1115777e472cSBartosz Sobczak vmem->va = kzalloc(vmem->size, GFP_KERNEL); 1116cdcd52d4SBartosz Sobczak if (!vmem->va) 1117cdcd52d4SBartosz Sobczak return -ENOMEM; 1118cdcd52d4SBartosz Sobczak 1119cdcd52d4SBartosz Sobczak rsrc = vmem->va; 1120cdcd52d4SBartosz Sobczak spin_lock_init(&rsrc->bufpool_lock); 1121cdcd52d4SBartosz Sobczak switch (info->type) { 1122cdcd52d4SBartosz Sobczak case IRDMA_PUDA_RSRC_TYPE_ILQ: 1123cdcd52d4SBartosz Sobczak vsi->ilq = vmem->va; 1124cdcd52d4SBartosz Sobczak vsi->ilq_count = info->count; 1125cdcd52d4SBartosz Sobczak rsrc->receive = info->receive; 1126cdcd52d4SBartosz Sobczak rsrc->xmit_complete = info->xmit_complete; 1127cdcd52d4SBartosz Sobczak break; 1128cdcd52d4SBartosz Sobczak case IRDMA_PUDA_RSRC_TYPE_IEQ: 1129cdcd52d4SBartosz Sobczak vsi->ieq_count = info->count; 1130cdcd52d4SBartosz Sobczak vsi->ieq = vmem->va; 1131cdcd52d4SBartosz Sobczak rsrc->receive = irdma_ieq_receive; 1132cdcd52d4SBartosz Sobczak rsrc->xmit_complete = irdma_ieq_tx_compl; 1133cdcd52d4SBartosz Sobczak break; 1134cdcd52d4SBartosz Sobczak default: 1135cdcd52d4SBartosz Sobczak return -EOPNOTSUPP; 1136cdcd52d4SBartosz Sobczak } 1137cdcd52d4SBartosz Sobczak 1138cdcd52d4SBartosz Sobczak rsrc->type = info->type; 1139cdcd52d4SBartosz Sobczak rsrc->sq_wrtrk_array = (struct irdma_sq_uk_wr_trk_info *) 1140cdcd52d4SBartosz Sobczak ((u8 *)vmem->va + pudasize); 1141cdcd52d4SBartosz Sobczak rsrc->rq_wrid_array = (u64 *)((u8 *)vmem->va + pudasize + sqwridsize); 1142cdcd52d4SBartosz Sobczak /* Initialize all ieq lists */ 1143cdcd52d4SBartosz Sobczak INIT_LIST_HEAD(&rsrc->bufpool); 1144cdcd52d4SBartosz Sobczak INIT_LIST_HEAD(&rsrc->txpend); 1145cdcd52d4SBartosz Sobczak 1146cdcd52d4SBartosz Sobczak rsrc->tx_wqe_avail_cnt = info->sq_size - 1; 1147cdcd52d4SBartosz Sobczak irdma_sc_pd_init(dev, &rsrc->sc_pd, info->pd_id, info->abi_ver); 1148cdcd52d4SBartosz Sobczak rsrc->qp_id = info->qp_id; 1149cdcd52d4SBartosz Sobczak rsrc->cq_id = info->cq_id; 1150cdcd52d4SBartosz Sobczak rsrc->sq_size = info->sq_size; 1151cdcd52d4SBartosz Sobczak rsrc->rq_size = info->rq_size; 1152cdcd52d4SBartosz Sobczak rsrc->cq_size = info->rq_size + info->sq_size; 1153cdcd52d4SBartosz Sobczak if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 1154cdcd52d4SBartosz Sobczak if (rsrc->type == IRDMA_PUDA_RSRC_TYPE_ILQ) 1155cdcd52d4SBartosz Sobczak rsrc->cq_size += info->rq_size; 1156cdcd52d4SBartosz Sobczak } 1157cdcd52d4SBartosz Sobczak rsrc->buf_size = info->buf_size; 1158cdcd52d4SBartosz Sobczak rsrc->dev = dev; 1159cdcd52d4SBartosz Sobczak rsrc->vsi = vsi; 1160cdcd52d4SBartosz Sobczak rsrc->stats_idx = info->stats_idx; 1161cdcd52d4SBartosz Sobczak rsrc->stats_idx_valid = info->stats_idx_valid; 1162cdcd52d4SBartosz Sobczak 1163cdcd52d4SBartosz Sobczak ret = irdma_puda_cq_create(rsrc); 1164cdcd52d4SBartosz Sobczak if (!ret) { 1165cdcd52d4SBartosz Sobczak rsrc->cmpl = PUDA_CQ_CREATED; 1166cdcd52d4SBartosz Sobczak ret = irdma_puda_qp_create(rsrc); 1167cdcd52d4SBartosz Sobczak } 1168cdcd52d4SBartosz Sobczak if (ret) { 1169cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, 1170cdcd52d4SBartosz Sobczak "error qp_create type=%d, status=%d\n", rsrc->type, 1171cdcd52d4SBartosz Sobczak ret); 1172cdcd52d4SBartosz Sobczak goto error; 1173cdcd52d4SBartosz Sobczak } 1174cdcd52d4SBartosz Sobczak rsrc->cmpl = PUDA_QP_CREATED; 1175cdcd52d4SBartosz Sobczak 1176cdcd52d4SBartosz Sobczak ret = irdma_puda_allocbufs(rsrc, info->tx_buf_cnt + info->rq_size); 1177cdcd52d4SBartosz Sobczak if (ret) { 1178cdcd52d4SBartosz Sobczak irdma_debug(dev, IRDMA_DEBUG_PUDA, "error alloc_buf\n"); 1179cdcd52d4SBartosz Sobczak goto error; 1180cdcd52d4SBartosz Sobczak } 1181cdcd52d4SBartosz Sobczak 1182cdcd52d4SBartosz Sobczak rsrc->rxq_invalid_cnt = info->rq_size; 1183cdcd52d4SBartosz Sobczak ret = irdma_puda_replenish_rq(rsrc, true); 1184cdcd52d4SBartosz Sobczak if (ret) 1185cdcd52d4SBartosz Sobczak goto error; 1186cdcd52d4SBartosz Sobczak 1187cdcd52d4SBartosz Sobczak if (info->type == IRDMA_PUDA_RSRC_TYPE_IEQ) { 1188cdcd52d4SBartosz Sobczak if (!irdma_init_hash_desc(&rsrc->hash_desc)) { 1189cdcd52d4SBartosz Sobczak rsrc->check_crc = true; 1190cdcd52d4SBartosz Sobczak rsrc->cmpl = PUDA_HASH_CRC_COMPLETE; 1191cdcd52d4SBartosz Sobczak ret = 0; 1192cdcd52d4SBartosz Sobczak } 1193cdcd52d4SBartosz Sobczak } 1194cdcd52d4SBartosz Sobczak 1195cdcd52d4SBartosz Sobczak irdma_sc_ccq_arm(&rsrc->cq); 1196cdcd52d4SBartosz Sobczak return ret; 1197cdcd52d4SBartosz Sobczak 1198cdcd52d4SBartosz Sobczak error: 1199cdcd52d4SBartosz Sobczak irdma_puda_dele_rsrc(vsi, info->type, false); 1200cdcd52d4SBartosz Sobczak 1201cdcd52d4SBartosz Sobczak return ret; 1202cdcd52d4SBartosz Sobczak } 1203cdcd52d4SBartosz Sobczak 1204cdcd52d4SBartosz Sobczak /** 1205cdcd52d4SBartosz Sobczak * irdma_ilq_putback_rcvbuf - ilq buffer to put back on rq 1206cdcd52d4SBartosz Sobczak * @qp: ilq's qp resource 1207cdcd52d4SBartosz Sobczak * @buf: puda buffer for rcv q 1208cdcd52d4SBartosz Sobczak * @wqe_idx: wqe index of completed rcvbuf 1209cdcd52d4SBartosz Sobczak */ 1210cdcd52d4SBartosz Sobczak static void 1211cdcd52d4SBartosz Sobczak irdma_ilq_putback_rcvbuf(struct irdma_sc_qp *qp, 1212cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf, u32 wqe_idx) 1213cdcd52d4SBartosz Sobczak { 1214cdcd52d4SBartosz Sobczak __le64 *wqe; 1215cdcd52d4SBartosz Sobczak u64 offset8, offset24; 1216cdcd52d4SBartosz Sobczak 1217cdcd52d4SBartosz Sobczak /* Synch buffer for use by device */ 1218cdcd52d4SBartosz Sobczak dma_sync_single_for_device(hw_to_dev(qp->dev->hw), buf->mem.pa, buf->mem.size, DMA_BIDIRECTIONAL); 1219cdcd52d4SBartosz Sobczak wqe = qp->qp_uk.rq_base[wqe_idx].elem; 1220cdcd52d4SBartosz Sobczak get_64bit_val(wqe, IRDMA_BYTE_24, &offset24); 1221cdcd52d4SBartosz Sobczak if (qp->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 1222cdcd52d4SBartosz Sobczak get_64bit_val(wqe, IRDMA_BYTE_8, &offset8); 1223cdcd52d4SBartosz Sobczak if (offset24) 1224777e472cSBartosz Sobczak offset8 &= ~FIELD_PREP(IRDMAQPSQ_VALID, 1); 1225cdcd52d4SBartosz Sobczak else 1226777e472cSBartosz Sobczak offset8 |= FIELD_PREP(IRDMAQPSQ_VALID, 1); 1227cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_8, offset8); 1228cdcd52d4SBartosz Sobczak irdma_wmb(); /* make sure WQE is written before valid bit is set */ 1229cdcd52d4SBartosz Sobczak } 1230cdcd52d4SBartosz Sobczak if (offset24) 1231cdcd52d4SBartosz Sobczak offset24 = 0; 1232cdcd52d4SBartosz Sobczak else 1233777e472cSBartosz Sobczak offset24 = FIELD_PREP(IRDMAQPSQ_VALID, 1); 1234cdcd52d4SBartosz Sobczak 1235cdcd52d4SBartosz Sobczak set_64bit_val(wqe, IRDMA_BYTE_24, offset24); 1236cdcd52d4SBartosz Sobczak } 1237cdcd52d4SBartosz Sobczak 1238cdcd52d4SBartosz Sobczak /** 1239cdcd52d4SBartosz Sobczak * irdma_ieq_get_fpdu_len - get length of fpdu with or without marker 1240cdcd52d4SBartosz Sobczak * @pfpdu: pointer to fpdu 1241cdcd52d4SBartosz Sobczak * @datap: pointer to data in the buffer 1242cdcd52d4SBartosz Sobczak * @rcv_seq: seqnum of the data buffer 1243cdcd52d4SBartosz Sobczak */ 1244cdcd52d4SBartosz Sobczak static u16 irdma_ieq_get_fpdu_len(struct irdma_pfpdu *pfpdu, u8 *datap, 1245cdcd52d4SBartosz Sobczak u32 rcv_seq){ 1246cdcd52d4SBartosz Sobczak u32 marker_seq, end_seq, blk_start; 1247cdcd52d4SBartosz Sobczak u8 marker_len = pfpdu->marker_len; 1248cdcd52d4SBartosz Sobczak u16 total_len = 0; 1249cdcd52d4SBartosz Sobczak u16 fpdu_len; 1250cdcd52d4SBartosz Sobczak 1251cdcd52d4SBartosz Sobczak blk_start = (pfpdu->rcv_start_seq - rcv_seq) & (IRDMA_MRK_BLK_SZ - 1); 1252cdcd52d4SBartosz Sobczak if (!blk_start) { 1253cdcd52d4SBartosz Sobczak total_len = marker_len; 1254cdcd52d4SBartosz Sobczak marker_seq = rcv_seq + IRDMA_MRK_BLK_SZ; 1255cdcd52d4SBartosz Sobczak if (marker_len && *(u32 *)datap) 1256cdcd52d4SBartosz Sobczak return 0; 1257cdcd52d4SBartosz Sobczak } else { 1258cdcd52d4SBartosz Sobczak marker_seq = rcv_seq + blk_start; 1259cdcd52d4SBartosz Sobczak } 1260cdcd52d4SBartosz Sobczak 1261cdcd52d4SBartosz Sobczak datap += total_len; 1262cdcd52d4SBartosz Sobczak fpdu_len = IRDMA_NTOHS(*(__be16 *) datap); 1263cdcd52d4SBartosz Sobczak fpdu_len += IRDMA_IEQ_MPA_FRAMING; 1264cdcd52d4SBartosz Sobczak fpdu_len = (fpdu_len + 3) & 0xfffc; 1265cdcd52d4SBartosz Sobczak 1266cdcd52d4SBartosz Sobczak if (fpdu_len > pfpdu->max_fpdu_data) 1267cdcd52d4SBartosz Sobczak return 0; 1268cdcd52d4SBartosz Sobczak 1269cdcd52d4SBartosz Sobczak total_len += fpdu_len; 1270cdcd52d4SBartosz Sobczak end_seq = rcv_seq + total_len; 1271cdcd52d4SBartosz Sobczak while ((int)(marker_seq - end_seq) < 0) { 1272cdcd52d4SBartosz Sobczak total_len += marker_len; 1273cdcd52d4SBartosz Sobczak end_seq += marker_len; 1274cdcd52d4SBartosz Sobczak marker_seq += IRDMA_MRK_BLK_SZ; 1275cdcd52d4SBartosz Sobczak } 1276cdcd52d4SBartosz Sobczak 1277cdcd52d4SBartosz Sobczak return total_len; 1278cdcd52d4SBartosz Sobczak } 1279cdcd52d4SBartosz Sobczak 1280cdcd52d4SBartosz Sobczak /** 1281cdcd52d4SBartosz Sobczak * irdma_ieq_copy_to_txbuf - copydata from rcv buf to tx buf 1282cdcd52d4SBartosz Sobczak * @buf: rcv buffer with partial 1283cdcd52d4SBartosz Sobczak * @txbuf: tx buffer for sending back 1284cdcd52d4SBartosz Sobczak * @buf_offset: rcv buffer offset to copy from 1285cdcd52d4SBartosz Sobczak * @txbuf_offset: at offset in tx buf to copy 1286cdcd52d4SBartosz Sobczak * @len: length of data to copy 1287cdcd52d4SBartosz Sobczak */ 1288cdcd52d4SBartosz Sobczak static void 1289cdcd52d4SBartosz Sobczak irdma_ieq_copy_to_txbuf(struct irdma_puda_buf *buf, 1290cdcd52d4SBartosz Sobczak struct irdma_puda_buf *txbuf, 1291cdcd52d4SBartosz Sobczak u16 buf_offset, u32 txbuf_offset, u32 len) 1292cdcd52d4SBartosz Sobczak { 1293cdcd52d4SBartosz Sobczak void *mem1 = (u8 *)buf->mem.va + buf_offset; 1294cdcd52d4SBartosz Sobczak void *mem2 = (u8 *)txbuf->mem.va + txbuf_offset; 1295cdcd52d4SBartosz Sobczak 1296cdcd52d4SBartosz Sobczak irdma_memcpy(mem2, mem1, len); 1297cdcd52d4SBartosz Sobczak } 1298cdcd52d4SBartosz Sobczak 1299cdcd52d4SBartosz Sobczak /** 1300cdcd52d4SBartosz Sobczak * irdma_ieq_setup_tx_buf - setup tx buffer for partial handling 1301cdcd52d4SBartosz Sobczak * @buf: reeive buffer with partial 1302cdcd52d4SBartosz Sobczak * @txbuf: buffer to prepare 1303cdcd52d4SBartosz Sobczak */ 1304cdcd52d4SBartosz Sobczak static void 1305cdcd52d4SBartosz Sobczak irdma_ieq_setup_tx_buf(struct irdma_puda_buf *buf, 1306cdcd52d4SBartosz Sobczak struct irdma_puda_buf *txbuf) 1307cdcd52d4SBartosz Sobczak { 1308cdcd52d4SBartosz Sobczak txbuf->tcphlen = buf->tcphlen; 1309cdcd52d4SBartosz Sobczak txbuf->ipv4 = buf->ipv4; 1310cdcd52d4SBartosz Sobczak 1311cdcd52d4SBartosz Sobczak if (buf->vsi->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 1312cdcd52d4SBartosz Sobczak txbuf->hdrlen = txbuf->tcphlen; 1313cdcd52d4SBartosz Sobczak irdma_ieq_copy_to_txbuf(buf, txbuf, IRDMA_TCP_OFFSET, 0, 1314cdcd52d4SBartosz Sobczak txbuf->hdrlen); 1315cdcd52d4SBartosz Sobczak } else { 1316cdcd52d4SBartosz Sobczak txbuf->maclen = buf->maclen; 1317cdcd52d4SBartosz Sobczak txbuf->hdrlen = buf->hdrlen; 1318cdcd52d4SBartosz Sobczak irdma_ieq_copy_to_txbuf(buf, txbuf, 0, 0, buf->hdrlen); 1319cdcd52d4SBartosz Sobczak } 1320cdcd52d4SBartosz Sobczak } 1321cdcd52d4SBartosz Sobczak 1322cdcd52d4SBartosz Sobczak /** 1323cdcd52d4SBartosz Sobczak * irdma_ieq_check_first_buf - check if rcv buffer's seq is in range 1324cdcd52d4SBartosz Sobczak * @buf: receive exception buffer 1325cdcd52d4SBartosz Sobczak * @fps: first partial sequence number 1326cdcd52d4SBartosz Sobczak */ 1327cdcd52d4SBartosz Sobczak static void 1328cdcd52d4SBartosz Sobczak irdma_ieq_check_first_buf(struct irdma_puda_buf *buf, u32 fps) 1329cdcd52d4SBartosz Sobczak { 1330cdcd52d4SBartosz Sobczak u32 offset; 1331cdcd52d4SBartosz Sobczak 1332cdcd52d4SBartosz Sobczak if (buf->seqnum < fps) { 1333cdcd52d4SBartosz Sobczak offset = fps - buf->seqnum; 1334cdcd52d4SBartosz Sobczak if (offset > buf->datalen) 1335cdcd52d4SBartosz Sobczak return; 1336cdcd52d4SBartosz Sobczak buf->data += offset; 1337cdcd52d4SBartosz Sobczak buf->datalen -= (u16)offset; 1338cdcd52d4SBartosz Sobczak buf->seqnum = fps; 1339cdcd52d4SBartosz Sobczak } 1340cdcd52d4SBartosz Sobczak } 1341cdcd52d4SBartosz Sobczak 1342cdcd52d4SBartosz Sobczak /** 1343cdcd52d4SBartosz Sobczak * irdma_ieq_compl_pfpdu - write txbuf with full fpdu 1344cdcd52d4SBartosz Sobczak * @ieq: ieq resource 1345cdcd52d4SBartosz Sobczak * @rxlist: ieq's received buffer list 1346cdcd52d4SBartosz Sobczak * @pbufl: temporary list for buffers for fpddu 1347cdcd52d4SBartosz Sobczak * @txbuf: tx buffer for fpdu 1348cdcd52d4SBartosz Sobczak * @fpdu_len: total length of fpdu 1349cdcd52d4SBartosz Sobczak */ 1350cdcd52d4SBartosz Sobczak static void 1351cdcd52d4SBartosz Sobczak irdma_ieq_compl_pfpdu(struct irdma_puda_rsrc *ieq, 1352cdcd52d4SBartosz Sobczak struct list_head *rxlist, 1353cdcd52d4SBartosz Sobczak struct list_head *pbufl, 1354cdcd52d4SBartosz Sobczak struct irdma_puda_buf *txbuf, u16 fpdu_len) 1355cdcd52d4SBartosz Sobczak { 1356cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf; 1357cdcd52d4SBartosz Sobczak u32 nextseqnum; 1358cdcd52d4SBartosz Sobczak u16 txoffset, bufoffset; 1359cdcd52d4SBartosz Sobczak 1360cdcd52d4SBartosz Sobczak buf = irdma_puda_get_listbuf(pbufl); 1361cdcd52d4SBartosz Sobczak if (!buf) 1362cdcd52d4SBartosz Sobczak return; 1363cdcd52d4SBartosz Sobczak 1364cdcd52d4SBartosz Sobczak nextseqnum = buf->seqnum + fpdu_len; 1365cdcd52d4SBartosz Sobczak irdma_ieq_setup_tx_buf(buf, txbuf); 1366cdcd52d4SBartosz Sobczak if (buf->vsi->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 1367cdcd52d4SBartosz Sobczak txoffset = txbuf->hdrlen; 1368cdcd52d4SBartosz Sobczak txbuf->totallen = txbuf->hdrlen + fpdu_len; 1369cdcd52d4SBartosz Sobczak txbuf->data = (u8 *)txbuf->mem.va + txoffset; 1370cdcd52d4SBartosz Sobczak } else { 1371cdcd52d4SBartosz Sobczak txoffset = buf->hdrlen; 1372cdcd52d4SBartosz Sobczak txbuf->totallen = buf->hdrlen + fpdu_len; 1373cdcd52d4SBartosz Sobczak txbuf->data = (u8 *)txbuf->mem.va + buf->hdrlen; 1374cdcd52d4SBartosz Sobczak } 1375cdcd52d4SBartosz Sobczak bufoffset = (u16)(buf->data - (u8 *)buf->mem.va); 1376cdcd52d4SBartosz Sobczak 1377cdcd52d4SBartosz Sobczak do { 1378cdcd52d4SBartosz Sobczak if (buf->datalen >= fpdu_len) { 1379cdcd52d4SBartosz Sobczak /* copied full fpdu */ 1380cdcd52d4SBartosz Sobczak irdma_ieq_copy_to_txbuf(buf, txbuf, bufoffset, txoffset, 1381cdcd52d4SBartosz Sobczak fpdu_len); 1382cdcd52d4SBartosz Sobczak buf->datalen -= fpdu_len; 1383cdcd52d4SBartosz Sobczak buf->data += fpdu_len; 1384cdcd52d4SBartosz Sobczak buf->seqnum = nextseqnum; 1385cdcd52d4SBartosz Sobczak break; 1386cdcd52d4SBartosz Sobczak } 1387cdcd52d4SBartosz Sobczak /* copy partial fpdu */ 1388cdcd52d4SBartosz Sobczak irdma_ieq_copy_to_txbuf(buf, txbuf, bufoffset, txoffset, 1389cdcd52d4SBartosz Sobczak buf->datalen); 1390cdcd52d4SBartosz Sobczak txoffset += buf->datalen; 1391cdcd52d4SBartosz Sobczak fpdu_len -= buf->datalen; 1392cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, buf); 1393cdcd52d4SBartosz Sobczak buf = irdma_puda_get_listbuf(pbufl); 1394cdcd52d4SBartosz Sobczak if (!buf) 1395cdcd52d4SBartosz Sobczak return; 1396cdcd52d4SBartosz Sobczak 1397cdcd52d4SBartosz Sobczak bufoffset = (u16)(buf->data - (u8 *)buf->mem.va); 1398cdcd52d4SBartosz Sobczak } while (1); 1399cdcd52d4SBartosz Sobczak 1400cdcd52d4SBartosz Sobczak /* last buffer on the list */ 1401cdcd52d4SBartosz Sobczak if (buf->datalen) 1402cdcd52d4SBartosz Sobczak list_add(&buf->list, rxlist); 1403cdcd52d4SBartosz Sobczak else 1404cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, buf); 1405cdcd52d4SBartosz Sobczak } 1406cdcd52d4SBartosz Sobczak 1407cdcd52d4SBartosz Sobczak /** 1408cdcd52d4SBartosz Sobczak * irdma_ieq_create_pbufl - create buffer list for single fpdu 1409cdcd52d4SBartosz Sobczak * @pfpdu: pointer to fpdu 1410cdcd52d4SBartosz Sobczak * @rxlist: resource list for receive ieq buffes 1411cdcd52d4SBartosz Sobczak * @pbufl: temp. list for buffers for fpddu 1412cdcd52d4SBartosz Sobczak * @buf: first receive buffer 1413cdcd52d4SBartosz Sobczak * @fpdu_len: total length of fpdu 1414cdcd52d4SBartosz Sobczak */ 1415cdcd52d4SBartosz Sobczak static int 1416cdcd52d4SBartosz Sobczak irdma_ieq_create_pbufl(struct irdma_pfpdu *pfpdu, 1417cdcd52d4SBartosz Sobczak struct list_head *rxlist, 1418cdcd52d4SBartosz Sobczak struct list_head *pbufl, 1419cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf, u16 fpdu_len) 1420cdcd52d4SBartosz Sobczak { 1421cdcd52d4SBartosz Sobczak int status = 0; 1422cdcd52d4SBartosz Sobczak struct irdma_puda_buf *nextbuf; 1423cdcd52d4SBartosz Sobczak u32 nextseqnum; 1424cdcd52d4SBartosz Sobczak u16 plen = fpdu_len - buf->datalen; 1425cdcd52d4SBartosz Sobczak bool done = false; 1426cdcd52d4SBartosz Sobczak 1427cdcd52d4SBartosz Sobczak nextseqnum = buf->seqnum + buf->datalen; 1428cdcd52d4SBartosz Sobczak do { 1429cdcd52d4SBartosz Sobczak nextbuf = irdma_puda_get_listbuf(rxlist); 1430cdcd52d4SBartosz Sobczak if (!nextbuf) { 1431cdcd52d4SBartosz Sobczak status = -ENOBUFS; 1432cdcd52d4SBartosz Sobczak break; 1433cdcd52d4SBartosz Sobczak } 1434cdcd52d4SBartosz Sobczak list_add_tail(&nextbuf->list, pbufl); 1435cdcd52d4SBartosz Sobczak if (nextbuf->seqnum != nextseqnum) { 1436cdcd52d4SBartosz Sobczak pfpdu->bad_seq_num++; 1437cdcd52d4SBartosz Sobczak status = -ERANGE; 1438cdcd52d4SBartosz Sobczak break; 1439cdcd52d4SBartosz Sobczak } 1440cdcd52d4SBartosz Sobczak if (nextbuf->datalen >= plen) { 1441cdcd52d4SBartosz Sobczak done = true; 1442cdcd52d4SBartosz Sobczak } else { 1443cdcd52d4SBartosz Sobczak plen -= nextbuf->datalen; 1444cdcd52d4SBartosz Sobczak nextseqnum = nextbuf->seqnum + nextbuf->datalen; 1445cdcd52d4SBartosz Sobczak } 1446cdcd52d4SBartosz Sobczak 1447cdcd52d4SBartosz Sobczak } while (!done); 1448cdcd52d4SBartosz Sobczak 1449cdcd52d4SBartosz Sobczak return status; 1450cdcd52d4SBartosz Sobczak } 1451cdcd52d4SBartosz Sobczak 1452cdcd52d4SBartosz Sobczak /** 1453cdcd52d4SBartosz Sobczak * irdma_ieq_handle_partial - process partial fpdu buffer 1454cdcd52d4SBartosz Sobczak * @ieq: ieq resource 1455cdcd52d4SBartosz Sobczak * @pfpdu: partial management per user qp 1456cdcd52d4SBartosz Sobczak * @buf: receive buffer 1457cdcd52d4SBartosz Sobczak * @fpdu_len: fpdu len in the buffer 1458cdcd52d4SBartosz Sobczak */ 1459cdcd52d4SBartosz Sobczak static int 1460cdcd52d4SBartosz Sobczak irdma_ieq_handle_partial(struct irdma_puda_rsrc *ieq, 1461cdcd52d4SBartosz Sobczak struct irdma_pfpdu *pfpdu, 1462cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf, u16 fpdu_len) 1463cdcd52d4SBartosz Sobczak { 1464cdcd52d4SBartosz Sobczak int status = 0; 1465cdcd52d4SBartosz Sobczak u8 *crcptr; 1466cdcd52d4SBartosz Sobczak u32 mpacrc; 1467cdcd52d4SBartosz Sobczak u32 seqnum = buf->seqnum; 1468cdcd52d4SBartosz Sobczak struct list_head pbufl; /* partial buffer list */ 1469cdcd52d4SBartosz Sobczak struct irdma_puda_buf *txbuf = NULL; 1470cdcd52d4SBartosz Sobczak struct list_head *rxlist = &pfpdu->rxlist; 1471cdcd52d4SBartosz Sobczak 1472cdcd52d4SBartosz Sobczak ieq->partials_handled++; 1473cdcd52d4SBartosz Sobczak 1474cdcd52d4SBartosz Sobczak INIT_LIST_HEAD(&pbufl); 1475cdcd52d4SBartosz Sobczak list_add(&buf->list, &pbufl); 1476cdcd52d4SBartosz Sobczak 1477cdcd52d4SBartosz Sobczak status = irdma_ieq_create_pbufl(pfpdu, rxlist, &pbufl, buf, fpdu_len); 1478cdcd52d4SBartosz Sobczak if (status) 1479cdcd52d4SBartosz Sobczak goto error; 1480cdcd52d4SBartosz Sobczak 1481cdcd52d4SBartosz Sobczak txbuf = irdma_puda_get_bufpool(ieq); 1482cdcd52d4SBartosz Sobczak if (!txbuf) { 1483cdcd52d4SBartosz Sobczak pfpdu->no_tx_bufs++; 1484cdcd52d4SBartosz Sobczak status = -ENOBUFS; 1485cdcd52d4SBartosz Sobczak goto error; 1486cdcd52d4SBartosz Sobczak } 1487cdcd52d4SBartosz Sobczak 1488cdcd52d4SBartosz Sobczak irdma_ieq_compl_pfpdu(ieq, rxlist, &pbufl, txbuf, fpdu_len); 1489cdcd52d4SBartosz Sobczak irdma_ieq_update_tcpip_info(txbuf, fpdu_len, seqnum); 1490cdcd52d4SBartosz Sobczak 1491cdcd52d4SBartosz Sobczak crcptr = txbuf->data + fpdu_len - 4; 1492cdcd52d4SBartosz Sobczak mpacrc = *(u32 *)crcptr; 1493cdcd52d4SBartosz Sobczak if (ieq->check_crc) { 1494cdcd52d4SBartosz Sobczak status = irdma_ieq_check_mpacrc(ieq->hash_desc, txbuf->data, 1495cdcd52d4SBartosz Sobczak (fpdu_len - 4), mpacrc); 1496cdcd52d4SBartosz Sobczak if (status) { 1497cdcd52d4SBartosz Sobczak irdma_debug(ieq->dev, IRDMA_DEBUG_IEQ, 1498cdcd52d4SBartosz Sobczak "error bad crc\n"); 1499cdcd52d4SBartosz Sobczak pfpdu->mpa_crc_err = true; 1500cdcd52d4SBartosz Sobczak goto error; 1501cdcd52d4SBartosz Sobczak } 1502cdcd52d4SBartosz Sobczak } 1503cdcd52d4SBartosz Sobczak 1504cdcd52d4SBartosz Sobczak irdma_debug_buf(ieq->dev, IRDMA_DEBUG_IEQ, "IEQ TX BUFFER", 1505cdcd52d4SBartosz Sobczak txbuf->mem.va, txbuf->totallen); 1506cdcd52d4SBartosz Sobczak if (ieq->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) 1507cdcd52d4SBartosz Sobczak txbuf->ah_id = pfpdu->ah->ah_info.ah_idx; 1508cdcd52d4SBartosz Sobczak txbuf->do_lpb = true; 1509cdcd52d4SBartosz Sobczak irdma_puda_send_buf(ieq, txbuf); 1510cdcd52d4SBartosz Sobczak pfpdu->rcv_nxt = seqnum + fpdu_len; 1511cdcd52d4SBartosz Sobczak return status; 1512cdcd52d4SBartosz Sobczak 1513cdcd52d4SBartosz Sobczak error: 1514cdcd52d4SBartosz Sobczak while (!list_empty(&pbufl)) { 1515cdcd52d4SBartosz Sobczak buf = (struct irdma_puda_buf *)(&pbufl)->prev; 1516*35105900SBartosz Sobczak list_move(&buf->list, rxlist); 1517cdcd52d4SBartosz Sobczak } 1518cdcd52d4SBartosz Sobczak if (txbuf) 1519cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, txbuf); 1520cdcd52d4SBartosz Sobczak 1521cdcd52d4SBartosz Sobczak return status; 1522cdcd52d4SBartosz Sobczak } 1523cdcd52d4SBartosz Sobczak 1524cdcd52d4SBartosz Sobczak /** 1525cdcd52d4SBartosz Sobczak * irdma_ieq_process_buf - process buffer rcvd for ieq 1526cdcd52d4SBartosz Sobczak * @ieq: ieq resource 1527cdcd52d4SBartosz Sobczak * @pfpdu: partial management per user qp 1528cdcd52d4SBartosz Sobczak * @buf: receive buffer 1529cdcd52d4SBartosz Sobczak */ 1530cdcd52d4SBartosz Sobczak static int 1531cdcd52d4SBartosz Sobczak irdma_ieq_process_buf(struct irdma_puda_rsrc *ieq, 1532cdcd52d4SBartosz Sobczak struct irdma_pfpdu *pfpdu, 1533cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf) 1534cdcd52d4SBartosz Sobczak { 1535cdcd52d4SBartosz Sobczak u16 fpdu_len = 0; 1536cdcd52d4SBartosz Sobczak u16 datalen = buf->datalen; 1537cdcd52d4SBartosz Sobczak u8 *datap = buf->data; 1538cdcd52d4SBartosz Sobczak u8 *crcptr; 1539cdcd52d4SBartosz Sobczak u16 ioffset = 0; 1540cdcd52d4SBartosz Sobczak u32 mpacrc; 1541cdcd52d4SBartosz Sobczak u32 seqnum = buf->seqnum; 1542cdcd52d4SBartosz Sobczak u16 len = 0; 1543cdcd52d4SBartosz Sobczak u16 full = 0; 1544cdcd52d4SBartosz Sobczak bool partial = false; 1545cdcd52d4SBartosz Sobczak struct irdma_puda_buf *txbuf; 1546cdcd52d4SBartosz Sobczak struct list_head *rxlist = &pfpdu->rxlist; 1547cdcd52d4SBartosz Sobczak int ret = 0; 1548cdcd52d4SBartosz Sobczak 1549cdcd52d4SBartosz Sobczak ioffset = (u16)(buf->data - (u8 *)buf->mem.va); 1550cdcd52d4SBartosz Sobczak while (datalen) { 1551cdcd52d4SBartosz Sobczak fpdu_len = irdma_ieq_get_fpdu_len(pfpdu, datap, buf->seqnum); 1552cdcd52d4SBartosz Sobczak if (!fpdu_len) { 1553cdcd52d4SBartosz Sobczak irdma_debug(ieq->dev, IRDMA_DEBUG_IEQ, 1554cdcd52d4SBartosz Sobczak "error bad fpdu len\n"); 1555cdcd52d4SBartosz Sobczak list_add(&buf->list, rxlist); 1556cdcd52d4SBartosz Sobczak pfpdu->mpa_crc_err = true; 1557cdcd52d4SBartosz Sobczak return -EINVAL; 1558cdcd52d4SBartosz Sobczak } 1559cdcd52d4SBartosz Sobczak 1560cdcd52d4SBartosz Sobczak if (datalen < fpdu_len) { 1561cdcd52d4SBartosz Sobczak partial = true; 1562cdcd52d4SBartosz Sobczak break; 1563cdcd52d4SBartosz Sobczak } 1564cdcd52d4SBartosz Sobczak crcptr = datap + fpdu_len - 4; 1565cdcd52d4SBartosz Sobczak mpacrc = *(u32 *)crcptr; 1566cdcd52d4SBartosz Sobczak if (ieq->check_crc) 1567cdcd52d4SBartosz Sobczak ret = irdma_ieq_check_mpacrc(ieq->hash_desc, datap, 1568cdcd52d4SBartosz Sobczak fpdu_len - 4, mpacrc); 1569cdcd52d4SBartosz Sobczak if (ret) { 1570cdcd52d4SBartosz Sobczak list_add(&buf->list, rxlist); 1571cdcd52d4SBartosz Sobczak irdma_debug(ieq->dev, IRDMA_DEBUG_ERR, 1572cdcd52d4SBartosz Sobczak "IRDMA_ERR_MPA_CRC\n"); 1573cdcd52d4SBartosz Sobczak pfpdu->mpa_crc_err = true; 1574cdcd52d4SBartosz Sobczak return ret; 1575cdcd52d4SBartosz Sobczak } 1576cdcd52d4SBartosz Sobczak full++; 1577cdcd52d4SBartosz Sobczak pfpdu->fpdu_processed++; 1578cdcd52d4SBartosz Sobczak ieq->fpdu_processed++; 1579cdcd52d4SBartosz Sobczak datap += fpdu_len; 1580cdcd52d4SBartosz Sobczak len += fpdu_len; 1581cdcd52d4SBartosz Sobczak datalen -= fpdu_len; 1582cdcd52d4SBartosz Sobczak } 1583cdcd52d4SBartosz Sobczak if (full) { 1584cdcd52d4SBartosz Sobczak /* copy full pdu's in the txbuf and send them out */ 1585cdcd52d4SBartosz Sobczak txbuf = irdma_puda_get_bufpool(ieq); 1586cdcd52d4SBartosz Sobczak if (!txbuf) { 1587cdcd52d4SBartosz Sobczak pfpdu->no_tx_bufs++; 1588cdcd52d4SBartosz Sobczak list_add(&buf->list, rxlist); 1589cdcd52d4SBartosz Sobczak return -ENOBUFS; 1590cdcd52d4SBartosz Sobczak } 1591cdcd52d4SBartosz Sobczak /* modify txbuf's buffer header */ 1592cdcd52d4SBartosz Sobczak irdma_ieq_setup_tx_buf(buf, txbuf); 1593cdcd52d4SBartosz Sobczak /* copy full fpdu's to new buffer */ 1594cdcd52d4SBartosz Sobczak if (ieq->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 1595cdcd52d4SBartosz Sobczak irdma_ieq_copy_to_txbuf(buf, txbuf, ioffset, 1596cdcd52d4SBartosz Sobczak txbuf->hdrlen, len); 1597cdcd52d4SBartosz Sobczak txbuf->totallen = txbuf->hdrlen + len; 1598cdcd52d4SBartosz Sobczak txbuf->ah_id = pfpdu->ah->ah_info.ah_idx; 1599cdcd52d4SBartosz Sobczak } else { 1600cdcd52d4SBartosz Sobczak irdma_ieq_copy_to_txbuf(buf, txbuf, ioffset, 1601cdcd52d4SBartosz Sobczak buf->hdrlen, len); 1602cdcd52d4SBartosz Sobczak txbuf->totallen = buf->hdrlen + len; 1603cdcd52d4SBartosz Sobczak } 1604cdcd52d4SBartosz Sobczak irdma_ieq_update_tcpip_info(txbuf, len, buf->seqnum); 1605cdcd52d4SBartosz Sobczak irdma_debug_buf(ieq->dev, IRDMA_DEBUG_IEQ, "IEQ TX BUFFER", 1606cdcd52d4SBartosz Sobczak txbuf->mem.va, txbuf->totallen); 1607cdcd52d4SBartosz Sobczak txbuf->do_lpb = true; 1608cdcd52d4SBartosz Sobczak irdma_puda_send_buf(ieq, txbuf); 1609cdcd52d4SBartosz Sobczak 1610cdcd52d4SBartosz Sobczak if (!datalen) { 1611cdcd52d4SBartosz Sobczak pfpdu->rcv_nxt = buf->seqnum + len; 1612cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, buf); 1613cdcd52d4SBartosz Sobczak return 0; 1614cdcd52d4SBartosz Sobczak } 1615cdcd52d4SBartosz Sobczak buf->data = datap; 1616cdcd52d4SBartosz Sobczak buf->seqnum = seqnum + len; 1617cdcd52d4SBartosz Sobczak buf->datalen = datalen; 1618cdcd52d4SBartosz Sobczak pfpdu->rcv_nxt = buf->seqnum; 1619cdcd52d4SBartosz Sobczak } 1620cdcd52d4SBartosz Sobczak if (partial) 1621cdcd52d4SBartosz Sobczak return irdma_ieq_handle_partial(ieq, pfpdu, buf, fpdu_len); 1622cdcd52d4SBartosz Sobczak 1623cdcd52d4SBartosz Sobczak return 0; 1624cdcd52d4SBartosz Sobczak } 1625cdcd52d4SBartosz Sobczak 1626cdcd52d4SBartosz Sobczak /** 1627cdcd52d4SBartosz Sobczak * irdma_ieq_process_fpdus - process fpdu's buffers on its list 1628cdcd52d4SBartosz Sobczak * @qp: qp for which partial fpdus 1629cdcd52d4SBartosz Sobczak * @ieq: ieq resource 1630cdcd52d4SBartosz Sobczak */ 1631cdcd52d4SBartosz Sobczak void 1632cdcd52d4SBartosz Sobczak irdma_ieq_process_fpdus(struct irdma_sc_qp *qp, 1633cdcd52d4SBartosz Sobczak struct irdma_puda_rsrc *ieq) 1634cdcd52d4SBartosz Sobczak { 1635cdcd52d4SBartosz Sobczak struct irdma_pfpdu *pfpdu = &qp->pfpdu; 1636cdcd52d4SBartosz Sobczak struct list_head *rxlist = &pfpdu->rxlist; 1637cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf; 1638cdcd52d4SBartosz Sobczak int status; 1639cdcd52d4SBartosz Sobczak 1640cdcd52d4SBartosz Sobczak do { 1641cdcd52d4SBartosz Sobczak if (list_empty(rxlist)) 1642cdcd52d4SBartosz Sobczak break; 1643cdcd52d4SBartosz Sobczak buf = irdma_puda_get_listbuf(rxlist); 1644cdcd52d4SBartosz Sobczak if (!buf) { 1645cdcd52d4SBartosz Sobczak irdma_debug(ieq->dev, IRDMA_DEBUG_IEQ, 1646cdcd52d4SBartosz Sobczak "error no buf\n"); 1647cdcd52d4SBartosz Sobczak break; 1648cdcd52d4SBartosz Sobczak } 1649cdcd52d4SBartosz Sobczak if (buf->seqnum != pfpdu->rcv_nxt) { 1650cdcd52d4SBartosz Sobczak /* This could be out of order or missing packet */ 1651cdcd52d4SBartosz Sobczak pfpdu->out_of_order++; 1652cdcd52d4SBartosz Sobczak list_add(&buf->list, rxlist); 1653cdcd52d4SBartosz Sobczak break; 1654cdcd52d4SBartosz Sobczak } 1655cdcd52d4SBartosz Sobczak /* keep processing buffers from the head of the list */ 1656cdcd52d4SBartosz Sobczak status = irdma_ieq_process_buf(ieq, pfpdu, buf); 1657cdcd52d4SBartosz Sobczak if (status && pfpdu->mpa_crc_err) { 1658cdcd52d4SBartosz Sobczak while (!list_empty(rxlist)) { 1659cdcd52d4SBartosz Sobczak buf = irdma_puda_get_listbuf(rxlist); 1660cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, buf); 1661cdcd52d4SBartosz Sobczak pfpdu->crc_err++; 1662cdcd52d4SBartosz Sobczak ieq->crc_err++; 1663cdcd52d4SBartosz Sobczak } 1664cdcd52d4SBartosz Sobczak /* create CQP for AE */ 1665cdcd52d4SBartosz Sobczak irdma_ieq_mpa_crc_ae(ieq->dev, qp); 1666cdcd52d4SBartosz Sobczak } 1667cdcd52d4SBartosz Sobczak } while (!status); 1668cdcd52d4SBartosz Sobczak } 1669cdcd52d4SBartosz Sobczak 1670cdcd52d4SBartosz Sobczak /** 1671cdcd52d4SBartosz Sobczak * irdma_ieq_create_ah - create an address handle for IEQ 1672cdcd52d4SBartosz Sobczak * @qp: qp pointer 1673cdcd52d4SBartosz Sobczak * @buf: buf received on IEQ used to create AH 1674cdcd52d4SBartosz Sobczak */ 1675cdcd52d4SBartosz Sobczak static int 1676cdcd52d4SBartosz Sobczak irdma_ieq_create_ah(struct irdma_sc_qp *qp, struct irdma_puda_buf *buf) 1677cdcd52d4SBartosz Sobczak { 1678cdcd52d4SBartosz Sobczak struct irdma_ah_info ah_info = {0}; 1679cdcd52d4SBartosz Sobczak 1680cdcd52d4SBartosz Sobczak qp->pfpdu.ah_buf = buf; 1681cdcd52d4SBartosz Sobczak irdma_puda_ieq_get_ah_info(qp, &ah_info); 1682cdcd52d4SBartosz Sobczak return irdma_puda_create_ah(qp->vsi->dev, &ah_info, false, 1683cdcd52d4SBartosz Sobczak IRDMA_PUDA_RSRC_TYPE_IEQ, qp, 1684cdcd52d4SBartosz Sobczak &qp->pfpdu.ah); 1685cdcd52d4SBartosz Sobczak } 1686cdcd52d4SBartosz Sobczak 1687cdcd52d4SBartosz Sobczak /** 1688cdcd52d4SBartosz Sobczak * irdma_ieq_handle_exception - handle qp's exception 1689cdcd52d4SBartosz Sobczak * @ieq: ieq resource 1690cdcd52d4SBartosz Sobczak * @qp: qp receiving excpetion 1691cdcd52d4SBartosz Sobczak * @buf: receive buffer 1692cdcd52d4SBartosz Sobczak */ 1693cdcd52d4SBartosz Sobczak static void 1694cdcd52d4SBartosz Sobczak irdma_ieq_handle_exception(struct irdma_puda_rsrc *ieq, 1695cdcd52d4SBartosz Sobczak struct irdma_sc_qp *qp, 1696cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf) 1697cdcd52d4SBartosz Sobczak { 1698cdcd52d4SBartosz Sobczak struct irdma_pfpdu *pfpdu = &qp->pfpdu; 1699cdcd52d4SBartosz Sobczak u32 *hw_host_ctx = (u32 *)qp->hw_host_ctx; 1700cdcd52d4SBartosz Sobczak u32 rcv_wnd = hw_host_ctx[23]; 1701cdcd52d4SBartosz Sobczak /* first partial seq # in q2 */ 1702cdcd52d4SBartosz Sobczak u32 fps = *(u32 *)(qp->q2_buf + Q2_FPSN_OFFSET); 1703cdcd52d4SBartosz Sobczak struct list_head *rxlist = &pfpdu->rxlist; 1704cdcd52d4SBartosz Sobczak struct list_head *plist; 1705cdcd52d4SBartosz Sobczak struct irdma_puda_buf *tmpbuf = NULL; 1706cdcd52d4SBartosz Sobczak unsigned long flags = 0; 1707cdcd52d4SBartosz Sobczak u8 hw_rev = qp->dev->hw_attrs.uk_attrs.hw_rev; 1708cdcd52d4SBartosz Sobczak 1709cdcd52d4SBartosz Sobczak irdma_debug_buf(ieq->dev, IRDMA_DEBUG_IEQ, "IEQ RX BUFFER", buf->mem.va, 1710cdcd52d4SBartosz Sobczak buf->totallen); 1711cdcd52d4SBartosz Sobczak 1712cdcd52d4SBartosz Sobczak spin_lock_irqsave(&pfpdu->lock, flags); 1713cdcd52d4SBartosz Sobczak pfpdu->total_ieq_bufs++; 1714cdcd52d4SBartosz Sobczak if (pfpdu->mpa_crc_err) { 1715cdcd52d4SBartosz Sobczak pfpdu->crc_err++; 1716cdcd52d4SBartosz Sobczak goto error; 1717cdcd52d4SBartosz Sobczak } 1718cdcd52d4SBartosz Sobczak if (pfpdu->mode && fps != pfpdu->fps) { 1719cdcd52d4SBartosz Sobczak /* clean up qp as it is new partial sequence */ 1720cdcd52d4SBartosz Sobczak irdma_ieq_cleanup_qp(ieq, qp); 1721cdcd52d4SBartosz Sobczak irdma_debug(ieq->dev, IRDMA_DEBUG_IEQ, 1722cdcd52d4SBartosz Sobczak "restarting new partial\n"); 1723cdcd52d4SBartosz Sobczak pfpdu->mode = false; 1724cdcd52d4SBartosz Sobczak } 1725cdcd52d4SBartosz Sobczak 1726cdcd52d4SBartosz Sobczak if (!pfpdu->mode) { 1727cdcd52d4SBartosz Sobczak irdma_debug_buf(ieq->dev, IRDMA_DEBUG_IEQ, "Q2 BUFFER", 1728cdcd52d4SBartosz Sobczak (u64 *)qp->q2_buf, 128); 1729cdcd52d4SBartosz Sobczak /* First_Partial_Sequence_Number check */ 1730cdcd52d4SBartosz Sobczak pfpdu->rcv_nxt = fps; 1731cdcd52d4SBartosz Sobczak pfpdu->fps = fps; 1732cdcd52d4SBartosz Sobczak pfpdu->mode = true; 1733cdcd52d4SBartosz Sobczak pfpdu->max_fpdu_data = (buf->ipv4) ? 1734cdcd52d4SBartosz Sobczak (ieq->vsi->mtu - IRDMA_MTU_TO_MSS_IPV4) : 1735cdcd52d4SBartosz Sobczak (ieq->vsi->mtu - IRDMA_MTU_TO_MSS_IPV6); 1736cdcd52d4SBartosz Sobczak pfpdu->pmode_count++; 1737cdcd52d4SBartosz Sobczak ieq->pmode_count++; 1738cdcd52d4SBartosz Sobczak INIT_LIST_HEAD(rxlist); 1739cdcd52d4SBartosz Sobczak irdma_ieq_check_first_buf(buf, fps); 1740cdcd52d4SBartosz Sobczak } 1741cdcd52d4SBartosz Sobczak 1742cdcd52d4SBartosz Sobczak if (!(rcv_wnd >= (buf->seqnum - pfpdu->rcv_nxt))) { 1743cdcd52d4SBartosz Sobczak pfpdu->bad_seq_num++; 1744cdcd52d4SBartosz Sobczak ieq->bad_seq_num++; 1745cdcd52d4SBartosz Sobczak goto error; 1746cdcd52d4SBartosz Sobczak } 1747cdcd52d4SBartosz Sobczak 1748cdcd52d4SBartosz Sobczak if (!list_empty(rxlist)) { 1749cdcd52d4SBartosz Sobczak tmpbuf = (struct irdma_puda_buf *)(rxlist)->next; 1750cdcd52d4SBartosz Sobczak while ((struct list_head *)tmpbuf != rxlist) { 1751cdcd52d4SBartosz Sobczak if (buf->seqnum == tmpbuf->seqnum) 1752cdcd52d4SBartosz Sobczak goto error; 1753cdcd52d4SBartosz Sobczak if ((int)(buf->seqnum - tmpbuf->seqnum) < 0) 1754cdcd52d4SBartosz Sobczak break; 1755cdcd52d4SBartosz Sobczak plist = &tmpbuf->list; 1756cdcd52d4SBartosz Sobczak tmpbuf = (struct irdma_puda_buf *)(plist)->next; 1757cdcd52d4SBartosz Sobczak } 1758cdcd52d4SBartosz Sobczak /* Insert buf before tmpbuf */ 1759cdcd52d4SBartosz Sobczak list_add_tail(&buf->list, &tmpbuf->list); 1760cdcd52d4SBartosz Sobczak } else { 1761cdcd52d4SBartosz Sobczak list_add_tail(&buf->list, rxlist); 1762cdcd52d4SBartosz Sobczak } 1763cdcd52d4SBartosz Sobczak pfpdu->nextseqnum = buf->seqnum + buf->datalen; 1764cdcd52d4SBartosz Sobczak pfpdu->lastrcv_buf = buf; 1765cdcd52d4SBartosz Sobczak if (hw_rev >= IRDMA_GEN_2 && !pfpdu->ah) { 1766cdcd52d4SBartosz Sobczak irdma_ieq_create_ah(qp, buf); 1767cdcd52d4SBartosz Sobczak if (!pfpdu->ah) 1768cdcd52d4SBartosz Sobczak goto error; 1769cdcd52d4SBartosz Sobczak goto exit; 1770cdcd52d4SBartosz Sobczak } 1771cdcd52d4SBartosz Sobczak if (hw_rev == IRDMA_GEN_1) 1772cdcd52d4SBartosz Sobczak irdma_ieq_process_fpdus(qp, ieq); 1773cdcd52d4SBartosz Sobczak else if (pfpdu->ah && pfpdu->ah->ah_info.ah_valid) 1774cdcd52d4SBartosz Sobczak irdma_ieq_process_fpdus(qp, ieq); 1775cdcd52d4SBartosz Sobczak exit: 1776cdcd52d4SBartosz Sobczak spin_unlock_irqrestore(&pfpdu->lock, flags); 1777cdcd52d4SBartosz Sobczak 1778cdcd52d4SBartosz Sobczak return; 1779cdcd52d4SBartosz Sobczak 1780cdcd52d4SBartosz Sobczak error: 1781cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, buf); 1782cdcd52d4SBartosz Sobczak spin_unlock_irqrestore(&pfpdu->lock, flags); 1783cdcd52d4SBartosz Sobczak } 1784cdcd52d4SBartosz Sobczak 1785cdcd52d4SBartosz Sobczak /** 1786cdcd52d4SBartosz Sobczak * irdma_ieq_receive - received exception buffer 1787cdcd52d4SBartosz Sobczak * @vsi: VSI of device 1788cdcd52d4SBartosz Sobczak * @buf: exception buffer received 1789cdcd52d4SBartosz Sobczak */ 1790cdcd52d4SBartosz Sobczak static void 1791cdcd52d4SBartosz Sobczak irdma_ieq_receive(struct irdma_sc_vsi *vsi, 1792cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf) 1793cdcd52d4SBartosz Sobczak { 1794cdcd52d4SBartosz Sobczak struct irdma_puda_rsrc *ieq = vsi->ieq; 1795cdcd52d4SBartosz Sobczak struct irdma_sc_qp *qp = NULL; 1796cdcd52d4SBartosz Sobczak u32 wqe_idx = ieq->compl_rxwqe_idx; 1797cdcd52d4SBartosz Sobczak 1798cdcd52d4SBartosz Sobczak qp = irdma_ieq_get_qp(vsi->dev, buf); 1799cdcd52d4SBartosz Sobczak if (!qp) { 1800cdcd52d4SBartosz Sobczak ieq->stats_bad_qp_id++; 1801cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, buf); 1802cdcd52d4SBartosz Sobczak } else { 1803cdcd52d4SBartosz Sobczak irdma_ieq_handle_exception(ieq, qp, buf); 1804cdcd52d4SBartosz Sobczak } 1805cdcd52d4SBartosz Sobczak /* 1806cdcd52d4SBartosz Sobczak * ieq->rx_wqe_idx is used by irdma_puda_replenish_rq() on which wqe_idx to start replenish rq 1807cdcd52d4SBartosz Sobczak */ 1808cdcd52d4SBartosz Sobczak if (!ieq->rxq_invalid_cnt) 1809cdcd52d4SBartosz Sobczak ieq->rx_wqe_idx = wqe_idx; 1810cdcd52d4SBartosz Sobczak ieq->rxq_invalid_cnt++; 1811cdcd52d4SBartosz Sobczak } 1812cdcd52d4SBartosz Sobczak 1813cdcd52d4SBartosz Sobczak /** 1814cdcd52d4SBartosz Sobczak * irdma_ieq_tx_compl - put back after sending completed exception buffer 1815cdcd52d4SBartosz Sobczak * @vsi: sc VSI struct 1816cdcd52d4SBartosz Sobczak * @sqwrid: pointer to puda buffer 1817cdcd52d4SBartosz Sobczak */ 1818cdcd52d4SBartosz Sobczak static void 1819cdcd52d4SBartosz Sobczak irdma_ieq_tx_compl(struct irdma_sc_vsi *vsi, void *sqwrid) 1820cdcd52d4SBartosz Sobczak { 1821cdcd52d4SBartosz Sobczak struct irdma_puda_rsrc *ieq = vsi->ieq; 1822cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf = sqwrid; 1823cdcd52d4SBartosz Sobczak 1824cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, buf); 1825cdcd52d4SBartosz Sobczak } 1826cdcd52d4SBartosz Sobczak 1827cdcd52d4SBartosz Sobczak /** 1828cdcd52d4SBartosz Sobczak * irdma_ieq_cleanup_qp - qp is being destroyed 1829cdcd52d4SBartosz Sobczak * @ieq: ieq resource 1830cdcd52d4SBartosz Sobczak * @qp: all pending fpdu buffers 1831cdcd52d4SBartosz Sobczak */ 1832cdcd52d4SBartosz Sobczak void 1833cdcd52d4SBartosz Sobczak irdma_ieq_cleanup_qp(struct irdma_puda_rsrc *ieq, struct irdma_sc_qp *qp) 1834cdcd52d4SBartosz Sobczak { 1835cdcd52d4SBartosz Sobczak struct irdma_puda_buf *buf; 1836cdcd52d4SBartosz Sobczak struct irdma_pfpdu *pfpdu = &qp->pfpdu; 1837cdcd52d4SBartosz Sobczak struct list_head *rxlist = &pfpdu->rxlist; 1838cdcd52d4SBartosz Sobczak 1839cdcd52d4SBartosz Sobczak if (qp->pfpdu.ah) { 1840cdcd52d4SBartosz Sobczak irdma_puda_free_ah(ieq->dev, qp->pfpdu.ah); 1841cdcd52d4SBartosz Sobczak qp->pfpdu.ah = NULL; 1842cdcd52d4SBartosz Sobczak qp->pfpdu.ah_buf = NULL; 1843cdcd52d4SBartosz Sobczak } 1844cdcd52d4SBartosz Sobczak 1845cdcd52d4SBartosz Sobczak if (!pfpdu->mode) 1846cdcd52d4SBartosz Sobczak return; 1847cdcd52d4SBartosz Sobczak 1848cdcd52d4SBartosz Sobczak while (!list_empty(rxlist)) { 1849cdcd52d4SBartosz Sobczak buf = irdma_puda_get_listbuf(rxlist); 1850cdcd52d4SBartosz Sobczak irdma_puda_ret_bufpool(ieq, buf); 1851cdcd52d4SBartosz Sobczak } 1852cdcd52d4SBartosz Sobczak } 1853