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