]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/infiniband/hw/bnxt_re/qplib_fp.c
RDMA/bnxt_re: HW workarounds for handling specific conditions
[karo-tx-linux.git] / drivers / infiniband / hw / bnxt_re / qplib_fp.c
1 /*
2  * Broadcom NetXtreme-E RoCE driver.
3  *
4  * Copyright (c) 2016 - 2017, Broadcom. All rights reserved.  The term
5  * Broadcom refers to Broadcom Limited and/or its subsidiaries.
6  *
7  * This software is available to you under a choice of one of two
8  * licenses.  You may choose to be licensed under the terms of the GNU
9  * General Public License (GPL) Version 2, available from the file
10  * COPYING in the main directory of this source tree, or the
11  * BSD license below:
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in
21  *    the documentation and/or other materials provided with the
22  *    distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * Description: Fast Path Operators
37  */
38
39 #include <linux/interrupt.h>
40 #include <linux/spinlock.h>
41 #include <linux/sched.h>
42 #include <linux/slab.h>
43 #include <linux/pci.h>
44 #include <linux/prefetch.h>
45
46 #include "roce_hsi.h"
47
48 #include "qplib_res.h"
49 #include "qplib_rcfw.h"
50 #include "qplib_sp.h"
51 #include "qplib_fp.h"
52
53 static void bnxt_qplib_arm_cq_enable(struct bnxt_qplib_cq *cq);
54
55 static void bnxt_qplib_free_qp_hdr_buf(struct bnxt_qplib_res *res,
56                                        struct bnxt_qplib_qp *qp)
57 {
58         struct bnxt_qplib_q *rq = &qp->rq;
59         struct bnxt_qplib_q *sq = &qp->sq;
60
61         if (qp->rq_hdr_buf)
62                 dma_free_coherent(&res->pdev->dev,
63                                   rq->hwq.max_elements * qp->rq_hdr_buf_size,
64                                   qp->rq_hdr_buf, qp->rq_hdr_buf_map);
65         if (qp->sq_hdr_buf)
66                 dma_free_coherent(&res->pdev->dev,
67                                   sq->hwq.max_elements * qp->sq_hdr_buf_size,
68                                   qp->sq_hdr_buf, qp->sq_hdr_buf_map);
69         qp->rq_hdr_buf = NULL;
70         qp->sq_hdr_buf = NULL;
71         qp->rq_hdr_buf_map = 0;
72         qp->sq_hdr_buf_map = 0;
73         qp->sq_hdr_buf_size = 0;
74         qp->rq_hdr_buf_size = 0;
75 }
76
77 static int bnxt_qplib_alloc_qp_hdr_buf(struct bnxt_qplib_res *res,
78                                        struct bnxt_qplib_qp *qp)
79 {
80         struct bnxt_qplib_q *rq = &qp->rq;
81         struct bnxt_qplib_q *sq = &qp->rq;
82         int rc = 0;
83
84         if (qp->sq_hdr_buf_size && sq->hwq.max_elements) {
85                 qp->sq_hdr_buf = dma_alloc_coherent(&res->pdev->dev,
86                                         sq->hwq.max_elements *
87                                         qp->sq_hdr_buf_size,
88                                         &qp->sq_hdr_buf_map, GFP_KERNEL);
89                 if (!qp->sq_hdr_buf) {
90                         rc = -ENOMEM;
91                         dev_err(&res->pdev->dev,
92                                 "QPLIB: Failed to create sq_hdr_buf");
93                         goto fail;
94                 }
95         }
96
97         if (qp->rq_hdr_buf_size && rq->hwq.max_elements) {
98                 qp->rq_hdr_buf = dma_alloc_coherent(&res->pdev->dev,
99                                                     rq->hwq.max_elements *
100                                                     qp->rq_hdr_buf_size,
101                                                     &qp->rq_hdr_buf_map,
102                                                     GFP_KERNEL);
103                 if (!qp->rq_hdr_buf) {
104                         rc = -ENOMEM;
105                         dev_err(&res->pdev->dev,
106                                 "QPLIB: Failed to create rq_hdr_buf");
107                         goto fail;
108                 }
109         }
110         return 0;
111
112 fail:
113         bnxt_qplib_free_qp_hdr_buf(res, qp);
114         return rc;
115 }
116
117 static void bnxt_qplib_service_nq(unsigned long data)
118 {
119         struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data;
120         struct bnxt_qplib_hwq *hwq = &nq->hwq;
121         struct nq_base *nqe, **nq_ptr;
122         int num_cqne_processed = 0;
123         u32 sw_cons, raw_cons;
124         u16 type;
125         int budget = nq->budget;
126         u64 q_handle;
127
128         /* Service the NQ until empty */
129         raw_cons = hwq->cons;
130         while (budget--) {
131                 sw_cons = HWQ_CMP(raw_cons, hwq);
132                 nq_ptr = (struct nq_base **)hwq->pbl_ptr;
133                 nqe = &nq_ptr[NQE_PG(sw_cons)][NQE_IDX(sw_cons)];
134                 if (!NQE_CMP_VALID(nqe, raw_cons, hwq->max_elements))
135                         break;
136
137                 type = le16_to_cpu(nqe->info10_type) & NQ_BASE_TYPE_MASK;
138                 switch (type) {
139                 case NQ_BASE_TYPE_CQ_NOTIFICATION:
140                 {
141                         struct nq_cn *nqcne = (struct nq_cn *)nqe;
142
143                         q_handle = le32_to_cpu(nqcne->cq_handle_low);
144                         q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high)
145                                                      << 32;
146                         bnxt_qplib_arm_cq_enable((struct bnxt_qplib_cq *)
147                                                  ((unsigned long)q_handle));
148                         if (!nq->cqn_handler(nq, (struct bnxt_qplib_cq *)
149                                                  ((unsigned long)q_handle)))
150                                 num_cqne_processed++;
151                         else
152                                 dev_warn(&nq->pdev->dev,
153                                          "QPLIB: cqn - type 0x%x not handled",
154                                          type);
155                         break;
156                 }
157                 case NQ_BASE_TYPE_DBQ_EVENT:
158                         break;
159                 default:
160                         dev_warn(&nq->pdev->dev,
161                                  "QPLIB: nqe with type = 0x%x not handled",
162                                  type);
163                         break;
164                 }
165                 raw_cons++;
166         }
167         if (hwq->cons != raw_cons) {
168                 hwq->cons = raw_cons;
169                 NQ_DB_REARM(nq->bar_reg_iomem, hwq->cons, hwq->max_elements);
170         }
171 }
172
173 static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
174 {
175         struct bnxt_qplib_nq *nq = dev_instance;
176         struct bnxt_qplib_hwq *hwq = &nq->hwq;
177         struct nq_base **nq_ptr;
178         u32 sw_cons;
179
180         /* Prefetch the NQ element */
181         sw_cons = HWQ_CMP(hwq->cons, hwq);
182         nq_ptr = (struct nq_base **)nq->hwq.pbl_ptr;
183         prefetch(&nq_ptr[NQE_PG(sw_cons)][NQE_IDX(sw_cons)]);
184
185         /* Fan out to CPU affinitized kthreads? */
186         tasklet_schedule(&nq->worker);
187
188         return IRQ_HANDLED;
189 }
190
191 void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
192 {
193         /* Make sure the HW is stopped! */
194         synchronize_irq(nq->vector);
195         tasklet_disable(&nq->worker);
196         tasklet_kill(&nq->worker);
197
198         if (nq->requested) {
199                 free_irq(nq->vector, nq);
200                 nq->requested = false;
201         }
202         if (nq->bar_reg_iomem)
203                 iounmap(nq->bar_reg_iomem);
204         nq->bar_reg_iomem = NULL;
205
206         nq->cqn_handler = NULL;
207         nq->srqn_handler = NULL;
208         nq->vector = 0;
209 }
210
211 int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
212                          int msix_vector, int bar_reg_offset,
213                          int (*cqn_handler)(struct bnxt_qplib_nq *nq,
214                                             struct bnxt_qplib_cq *),
215                          int (*srqn_handler)(struct bnxt_qplib_nq *nq,
216                                              void *, u8 event))
217 {
218         resource_size_t nq_base;
219         int rc;
220
221         nq->pdev = pdev;
222         nq->vector = msix_vector;
223
224         nq->cqn_handler = cqn_handler;
225
226         nq->srqn_handler = srqn_handler;
227
228         tasklet_init(&nq->worker, bnxt_qplib_service_nq, (unsigned long)nq);
229
230         nq->requested = false;
231         rc = request_irq(nq->vector, bnxt_qplib_nq_irq, 0, "bnxt_qplib_nq", nq);
232         if (rc) {
233                 dev_err(&nq->pdev->dev,
234                         "Failed to request IRQ for NQ: %#x", rc);
235                 bnxt_qplib_disable_nq(nq);
236                 goto fail;
237         }
238         nq->requested = true;
239         nq->bar_reg = NQ_CONS_PCI_BAR_REGION;
240         nq->bar_reg_off = bar_reg_offset;
241         nq_base = pci_resource_start(pdev, nq->bar_reg);
242         if (!nq_base) {
243                 rc = -ENOMEM;
244                 goto fail;
245         }
246         nq->bar_reg_iomem = ioremap_nocache(nq_base + nq->bar_reg_off, 4);
247         if (!nq->bar_reg_iomem) {
248                 rc = -ENOMEM;
249                 goto fail;
250         }
251         NQ_DB_REARM(nq->bar_reg_iomem, nq->hwq.cons, nq->hwq.max_elements);
252
253         return 0;
254 fail:
255         bnxt_qplib_disable_nq(nq);
256         return rc;
257 }
258
259 void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq)
260 {
261         if (nq->hwq.max_elements)
262                 bnxt_qplib_free_hwq(nq->pdev, &nq->hwq);
263 }
264
265 int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq)
266 {
267         nq->pdev = pdev;
268         if (!nq->hwq.max_elements ||
269             nq->hwq.max_elements > BNXT_QPLIB_NQE_MAX_CNT)
270                 nq->hwq.max_elements = BNXT_QPLIB_NQE_MAX_CNT;
271
272         if (bnxt_qplib_alloc_init_hwq(nq->pdev, &nq->hwq, NULL, 0,
273                                       &nq->hwq.max_elements,
274                                       BNXT_QPLIB_MAX_NQE_ENTRY_SIZE, 0,
275                                       PAGE_SIZE, HWQ_TYPE_L2_CMPL))
276                 return -ENOMEM;
277
278         nq->budget = 8;
279         return 0;
280 }
281
282 /* QP */
283 int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
284 {
285         struct bnxt_qplib_rcfw *rcfw = res->rcfw;
286         struct cmdq_create_qp1 req;
287         struct creq_create_qp1_resp resp;
288         struct bnxt_qplib_pbl *pbl;
289         struct bnxt_qplib_q *sq = &qp->sq;
290         struct bnxt_qplib_q *rq = &qp->rq;
291         int rc;
292         u16 cmd_flags = 0;
293         u32 qp_flags = 0;
294
295         RCFW_CMD_PREP(req, CREATE_QP1, cmd_flags);
296
297         /* General */
298         req.type = qp->type;
299         req.dpi = cpu_to_le32(qp->dpi->dpi);
300         req.qp_handle = cpu_to_le64(qp->qp_handle);
301
302         /* SQ */
303         sq->hwq.max_elements = sq->max_wqe;
304         rc = bnxt_qplib_alloc_init_hwq(res->pdev, &sq->hwq, NULL, 0,
305                                        &sq->hwq.max_elements,
306                                        BNXT_QPLIB_MAX_SQE_ENTRY_SIZE, 0,
307                                        PAGE_SIZE, HWQ_TYPE_QUEUE);
308         if (rc)
309                 goto exit;
310
311         sq->swq = kcalloc(sq->hwq.max_elements, sizeof(*sq->swq), GFP_KERNEL);
312         if (!sq->swq) {
313                 rc = -ENOMEM;
314                 goto fail_sq;
315         }
316         pbl = &sq->hwq.pbl[PBL_LVL_0];
317         req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
318         req.sq_pg_size_sq_lvl =
319                 ((sq->hwq.level & CMDQ_CREATE_QP1_SQ_LVL_MASK)
320                                 <<  CMDQ_CREATE_QP1_SQ_LVL_SFT) |
321                 (pbl->pg_size == ROCE_PG_SIZE_4K ?
322                                 CMDQ_CREATE_QP1_SQ_PG_SIZE_PG_4K :
323                  pbl->pg_size == ROCE_PG_SIZE_8K ?
324                                 CMDQ_CREATE_QP1_SQ_PG_SIZE_PG_8K :
325                  pbl->pg_size == ROCE_PG_SIZE_64K ?
326                                 CMDQ_CREATE_QP1_SQ_PG_SIZE_PG_64K :
327                  pbl->pg_size == ROCE_PG_SIZE_2M ?
328                                 CMDQ_CREATE_QP1_SQ_PG_SIZE_PG_2M :
329                  pbl->pg_size == ROCE_PG_SIZE_8M ?
330                                 CMDQ_CREATE_QP1_SQ_PG_SIZE_PG_8M :
331                  pbl->pg_size == ROCE_PG_SIZE_1G ?
332                                 CMDQ_CREATE_QP1_SQ_PG_SIZE_PG_1G :
333                  CMDQ_CREATE_QP1_SQ_PG_SIZE_PG_4K);
334
335         if (qp->scq)
336                 req.scq_cid = cpu_to_le32(qp->scq->id);
337
338         qp_flags |= CMDQ_CREATE_QP1_QP_FLAGS_RESERVED_LKEY_ENABLE;
339
340         /* RQ */
341         if (rq->max_wqe) {
342                 rq->hwq.max_elements = qp->rq.max_wqe;
343                 rc = bnxt_qplib_alloc_init_hwq(res->pdev, &rq->hwq, NULL, 0,
344                                                &rq->hwq.max_elements,
345                                                BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0,
346                                                PAGE_SIZE, HWQ_TYPE_QUEUE);
347                 if (rc)
348                         goto fail_sq;
349
350                 rq->swq = kcalloc(rq->hwq.max_elements, sizeof(*rq->swq),
351                                   GFP_KERNEL);
352                 if (!rq->swq) {
353                         rc = -ENOMEM;
354                         goto fail_rq;
355                 }
356                 pbl = &rq->hwq.pbl[PBL_LVL_0];
357                 req.rq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
358                 req.rq_pg_size_rq_lvl =
359                         ((rq->hwq.level & CMDQ_CREATE_QP1_RQ_LVL_MASK) <<
360                          CMDQ_CREATE_QP1_RQ_LVL_SFT) |
361                                 (pbl->pg_size == ROCE_PG_SIZE_4K ?
362                                         CMDQ_CREATE_QP1_RQ_PG_SIZE_PG_4K :
363                                  pbl->pg_size == ROCE_PG_SIZE_8K ?
364                                         CMDQ_CREATE_QP1_RQ_PG_SIZE_PG_8K :
365                                  pbl->pg_size == ROCE_PG_SIZE_64K ?
366                                         CMDQ_CREATE_QP1_RQ_PG_SIZE_PG_64K :
367                                  pbl->pg_size == ROCE_PG_SIZE_2M ?
368                                         CMDQ_CREATE_QP1_RQ_PG_SIZE_PG_2M :
369                                  pbl->pg_size == ROCE_PG_SIZE_8M ?
370                                         CMDQ_CREATE_QP1_RQ_PG_SIZE_PG_8M :
371                                  pbl->pg_size == ROCE_PG_SIZE_1G ?
372                                         CMDQ_CREATE_QP1_RQ_PG_SIZE_PG_1G :
373                                  CMDQ_CREATE_QP1_RQ_PG_SIZE_PG_4K);
374                 if (qp->rcq)
375                         req.rcq_cid = cpu_to_le32(qp->rcq->id);
376         }
377
378         /* Header buffer - allow hdr_buf pass in */
379         rc = bnxt_qplib_alloc_qp_hdr_buf(res, qp);
380         if (rc) {
381                 rc = -ENOMEM;
382                 goto fail;
383         }
384         req.qp_flags = cpu_to_le32(qp_flags);
385         req.sq_size = cpu_to_le32(sq->hwq.max_elements);
386         req.rq_size = cpu_to_le32(rq->hwq.max_elements);
387
388         req.sq_fwo_sq_sge =
389                 cpu_to_le16((sq->max_sge & CMDQ_CREATE_QP1_SQ_SGE_MASK) <<
390                             CMDQ_CREATE_QP1_SQ_SGE_SFT);
391         req.rq_fwo_rq_sge =
392                 cpu_to_le16((rq->max_sge & CMDQ_CREATE_QP1_RQ_SGE_MASK) <<
393                             CMDQ_CREATE_QP1_RQ_SGE_SFT);
394
395         req.pd_id = cpu_to_le32(qp->pd->id);
396
397         rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
398                                           (void *)&resp, NULL, 0);
399         if (rc)
400                 goto fail;
401
402         qp->id = le32_to_cpu(resp.xid);
403         qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
404         sq->flush_in_progress = false;
405         rq->flush_in_progress = false;
406
407         return 0;
408
409 fail:
410         bnxt_qplib_free_qp_hdr_buf(res, qp);
411 fail_rq:
412         bnxt_qplib_free_hwq(res->pdev, &rq->hwq);
413         kfree(rq->swq);
414 fail_sq:
415         bnxt_qplib_free_hwq(res->pdev, &sq->hwq);
416         kfree(sq->swq);
417 exit:
418         return rc;
419 }
420
421 int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
422 {
423         struct bnxt_qplib_rcfw *rcfw = res->rcfw;
424         struct sq_send *hw_sq_send_hdr, **hw_sq_send_ptr;
425         struct cmdq_create_qp req;
426         struct creq_create_qp_resp resp;
427         struct bnxt_qplib_pbl *pbl;
428         struct sq_psn_search **psn_search_ptr;
429         unsigned long int psn_search, poff = 0;
430         struct bnxt_qplib_q *sq = &qp->sq;
431         struct bnxt_qplib_q *rq = &qp->rq;
432         struct bnxt_qplib_hwq *xrrq;
433         int i, rc, req_size, psn_sz;
434         u16 cmd_flags = 0, max_ssge;
435         u32 sw_prod, qp_flags = 0;
436
437         RCFW_CMD_PREP(req, CREATE_QP, cmd_flags);
438
439         /* General */
440         req.type = qp->type;
441         req.dpi = cpu_to_le32(qp->dpi->dpi);
442         req.qp_handle = cpu_to_le64(qp->qp_handle);
443
444         /* SQ */
445         psn_sz = (qp->type == CMDQ_CREATE_QP_TYPE_RC) ?
446                  sizeof(struct sq_psn_search) : 0;
447         sq->hwq.max_elements = sq->max_wqe;
448         rc = bnxt_qplib_alloc_init_hwq(res->pdev, &sq->hwq, sq->sglist,
449                                        sq->nmap, &sq->hwq.max_elements,
450                                        BNXT_QPLIB_MAX_SQE_ENTRY_SIZE,
451                                        psn_sz,
452                                        PAGE_SIZE, HWQ_TYPE_QUEUE);
453         if (rc)
454                 goto exit;
455
456         sq->swq = kcalloc(sq->hwq.max_elements, sizeof(*sq->swq), GFP_KERNEL);
457         if (!sq->swq) {
458                 rc = -ENOMEM;
459                 goto fail_sq;
460         }
461         hw_sq_send_ptr = (struct sq_send **)sq->hwq.pbl_ptr;
462         if (psn_sz) {
463                 psn_search_ptr = (struct sq_psn_search **)
464                                   &hw_sq_send_ptr[get_sqe_pg
465                                         (sq->hwq.max_elements)];
466                 psn_search = (unsigned long int)
467                               &hw_sq_send_ptr[get_sqe_pg(sq->hwq.max_elements)]
468                               [get_sqe_idx(sq->hwq.max_elements)];
469                 if (psn_search & ~PAGE_MASK) {
470                         /* If the psn_search does not start on a page boundary,
471                          * then calculate the offset
472                          */
473                         poff = (psn_search & ~PAGE_MASK) /
474                                 BNXT_QPLIB_MAX_PSNE_ENTRY_SIZE;
475                 }
476                 for (i = 0; i < sq->hwq.max_elements; i++)
477                         sq->swq[i].psn_search =
478                                 &psn_search_ptr[get_psne_pg(i + poff)]
479                                                [get_psne_idx(i + poff)];
480         }
481         pbl = &sq->hwq.pbl[PBL_LVL_0];
482         req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
483         req.sq_pg_size_sq_lvl =
484                 ((sq->hwq.level & CMDQ_CREATE_QP_SQ_LVL_MASK)
485                                  <<  CMDQ_CREATE_QP_SQ_LVL_SFT) |
486                 (pbl->pg_size == ROCE_PG_SIZE_4K ?
487                                 CMDQ_CREATE_QP_SQ_PG_SIZE_PG_4K :
488                  pbl->pg_size == ROCE_PG_SIZE_8K ?
489                                 CMDQ_CREATE_QP_SQ_PG_SIZE_PG_8K :
490                  pbl->pg_size == ROCE_PG_SIZE_64K ?
491                                 CMDQ_CREATE_QP_SQ_PG_SIZE_PG_64K :
492                  pbl->pg_size == ROCE_PG_SIZE_2M ?
493                                 CMDQ_CREATE_QP_SQ_PG_SIZE_PG_2M :
494                  pbl->pg_size == ROCE_PG_SIZE_8M ?
495                                 CMDQ_CREATE_QP_SQ_PG_SIZE_PG_8M :
496                  pbl->pg_size == ROCE_PG_SIZE_1G ?
497                                 CMDQ_CREATE_QP_SQ_PG_SIZE_PG_1G :
498                  CMDQ_CREATE_QP_SQ_PG_SIZE_PG_4K);
499
500         /* initialize all SQ WQEs to LOCAL_INVALID (sq prep for hw fetch) */
501         hw_sq_send_ptr = (struct sq_send **)sq->hwq.pbl_ptr;
502         for (sw_prod = 0; sw_prod < sq->hwq.max_elements; sw_prod++) {
503                 hw_sq_send_hdr = &hw_sq_send_ptr[get_sqe_pg(sw_prod)]
504                                                 [get_sqe_idx(sw_prod)];
505                 hw_sq_send_hdr->wqe_type = SQ_BASE_WQE_TYPE_LOCAL_INVALID;
506         }
507
508         if (qp->scq)
509                 req.scq_cid = cpu_to_le32(qp->scq->id);
510
511         qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_RESERVED_LKEY_ENABLE;
512         qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_FR_PMR_ENABLED;
513         if (qp->sig_type)
514                 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_FORCE_COMPLETION;
515
516         /* RQ */
517         if (rq->max_wqe) {
518                 rq->hwq.max_elements = rq->max_wqe;
519                 rc = bnxt_qplib_alloc_init_hwq(res->pdev, &rq->hwq, rq->sglist,
520                                                rq->nmap, &rq->hwq.max_elements,
521                                                BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0,
522                                                PAGE_SIZE, HWQ_TYPE_QUEUE);
523                 if (rc)
524                         goto fail_sq;
525
526                 rq->swq = kcalloc(rq->hwq.max_elements, sizeof(*rq->swq),
527                                   GFP_KERNEL);
528                 if (!rq->swq) {
529                         rc = -ENOMEM;
530                         goto fail_rq;
531                 }
532                 pbl = &rq->hwq.pbl[PBL_LVL_0];
533                 req.rq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
534                 req.rq_pg_size_rq_lvl =
535                         ((rq->hwq.level & CMDQ_CREATE_QP_RQ_LVL_MASK) <<
536                          CMDQ_CREATE_QP_RQ_LVL_SFT) |
537                                 (pbl->pg_size == ROCE_PG_SIZE_4K ?
538                                         CMDQ_CREATE_QP_RQ_PG_SIZE_PG_4K :
539                                  pbl->pg_size == ROCE_PG_SIZE_8K ?
540                                         CMDQ_CREATE_QP_RQ_PG_SIZE_PG_8K :
541                                  pbl->pg_size == ROCE_PG_SIZE_64K ?
542                                         CMDQ_CREATE_QP_RQ_PG_SIZE_PG_64K :
543                                  pbl->pg_size == ROCE_PG_SIZE_2M ?
544                                         CMDQ_CREATE_QP_RQ_PG_SIZE_PG_2M :
545                                  pbl->pg_size == ROCE_PG_SIZE_8M ?
546                                         CMDQ_CREATE_QP_RQ_PG_SIZE_PG_8M :
547                                  pbl->pg_size == ROCE_PG_SIZE_1G ?
548                                         CMDQ_CREATE_QP_RQ_PG_SIZE_PG_1G :
549                                  CMDQ_CREATE_QP_RQ_PG_SIZE_PG_4K);
550         }
551
552         if (qp->rcq)
553                 req.rcq_cid = cpu_to_le32(qp->rcq->id);
554         req.qp_flags = cpu_to_le32(qp_flags);
555         req.sq_size = cpu_to_le32(sq->hwq.max_elements);
556         req.rq_size = cpu_to_le32(rq->hwq.max_elements);
557         qp->sq_hdr_buf = NULL;
558         qp->rq_hdr_buf = NULL;
559
560         rc = bnxt_qplib_alloc_qp_hdr_buf(res, qp);
561         if (rc)
562                 goto fail_rq;
563
564         /* CTRL-22434: Irrespective of the requested SGE count on the SQ
565          * always create the QP with max send sges possible if the requested
566          * inline size is greater than 0.
567          */
568         max_ssge = qp->max_inline_data ? 6 : sq->max_sge;
569         req.sq_fwo_sq_sge = cpu_to_le16(
570                                 ((max_ssge & CMDQ_CREATE_QP_SQ_SGE_MASK)
571                                  << CMDQ_CREATE_QP_SQ_SGE_SFT) | 0);
572         req.rq_fwo_rq_sge = cpu_to_le16(
573                                 ((rq->max_sge & CMDQ_CREATE_QP_RQ_SGE_MASK)
574                                  << CMDQ_CREATE_QP_RQ_SGE_SFT) | 0);
575         /* ORRQ and IRRQ */
576         if (psn_sz) {
577                 xrrq = &qp->orrq;
578                 xrrq->max_elements =
579                         ORD_LIMIT_TO_ORRQ_SLOTS(qp->max_rd_atomic);
580                 req_size = xrrq->max_elements *
581                            BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE + PAGE_SIZE - 1;
582                 req_size &= ~(PAGE_SIZE - 1);
583                 rc = bnxt_qplib_alloc_init_hwq(res->pdev, xrrq, NULL, 0,
584                                                &xrrq->max_elements,
585                                                BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE,
586                                                0, req_size, HWQ_TYPE_CTX);
587                 if (rc)
588                         goto fail_buf_free;
589                 pbl = &xrrq->pbl[PBL_LVL_0];
590                 req.orrq_addr = cpu_to_le64(pbl->pg_map_arr[0]);
591
592                 xrrq = &qp->irrq;
593                 xrrq->max_elements = IRD_LIMIT_TO_IRRQ_SLOTS(
594                                                 qp->max_dest_rd_atomic);
595                 req_size = xrrq->max_elements *
596                            BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE + PAGE_SIZE - 1;
597                 req_size &= ~(PAGE_SIZE - 1);
598
599                 rc = bnxt_qplib_alloc_init_hwq(res->pdev, xrrq, NULL, 0,
600                                                &xrrq->max_elements,
601                                                BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE,
602                                                0, req_size, HWQ_TYPE_CTX);
603                 if (rc)
604                         goto fail_orrq;
605
606                 pbl = &xrrq->pbl[PBL_LVL_0];
607                 req.irrq_addr = cpu_to_le64(pbl->pg_map_arr[0]);
608         }
609         req.pd_id = cpu_to_le32(qp->pd->id);
610
611         rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
612                                           (void *)&resp, NULL, 0);
613         if (rc)
614                 goto fail;
615
616         qp->id = le32_to_cpu(resp.xid);
617         qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
618         sq->flush_in_progress = false;
619         rq->flush_in_progress = false;
620
621         return 0;
622
623 fail:
624         if (qp->irrq.max_elements)
625                 bnxt_qplib_free_hwq(res->pdev, &qp->irrq);
626 fail_orrq:
627         if (qp->orrq.max_elements)
628                 bnxt_qplib_free_hwq(res->pdev, &qp->orrq);
629 fail_buf_free:
630         bnxt_qplib_free_qp_hdr_buf(res, qp);
631 fail_rq:
632         bnxt_qplib_free_hwq(res->pdev, &rq->hwq);
633         kfree(rq->swq);
634 fail_sq:
635         bnxt_qplib_free_hwq(res->pdev, &sq->hwq);
636         kfree(sq->swq);
637 exit:
638         return rc;
639 }
640
641 static void __modify_flags_from_init_state(struct bnxt_qplib_qp *qp)
642 {
643         switch (qp->state) {
644         case CMDQ_MODIFY_QP_NEW_STATE_RTR:
645                 /* INIT->RTR, configure the path_mtu to the default
646                  * 2048 if not being requested
647                  */
648                 if (!(qp->modify_flags &
649                     CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU)) {
650                         qp->modify_flags |=
651                                 CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU;
652                         qp->path_mtu =
653                                 CMDQ_MODIFY_QP_PATH_MTU_MTU_2048;
654                 }
655                 qp->modify_flags &=
656                         ~CMDQ_MODIFY_QP_MODIFY_MASK_VLAN_ID;
657                 /* Bono FW require the max_dest_rd_atomic to be >= 1 */
658                 if (qp->max_dest_rd_atomic < 1)
659                         qp->max_dest_rd_atomic = 1;
660                 qp->modify_flags &= ~CMDQ_MODIFY_QP_MODIFY_MASK_SRC_MAC;
661                 /* Bono FW 20.6.5 requires SGID_INDEX configuration */
662                 if (!(qp->modify_flags &
663                     CMDQ_MODIFY_QP_MODIFY_MASK_SGID_INDEX)) {
664                         qp->modify_flags |=
665                                 CMDQ_MODIFY_QP_MODIFY_MASK_SGID_INDEX;
666                         qp->ah.sgid_index = 0;
667                 }
668                 break;
669         default:
670                 break;
671         }
672 }
673
674 static void __modify_flags_from_rtr_state(struct bnxt_qplib_qp *qp)
675 {
676         switch (qp->state) {
677         case CMDQ_MODIFY_QP_NEW_STATE_RTS:
678                 /* Bono FW requires the max_rd_atomic to be >= 1 */
679                 if (qp->max_rd_atomic < 1)
680                         qp->max_rd_atomic = 1;
681                 /* Bono FW does not allow PKEY_INDEX,
682                  * DGID, FLOW_LABEL, SGID_INDEX, HOP_LIMIT,
683                  * TRAFFIC_CLASS, DEST_MAC, PATH_MTU, RQ_PSN,
684                  * MIN_RNR_TIMER, MAX_DEST_RD_ATOMIC, DEST_QP_ID
685                  * modification
686                  */
687                 qp->modify_flags &=
688                         ~(CMDQ_MODIFY_QP_MODIFY_MASK_PKEY |
689                           CMDQ_MODIFY_QP_MODIFY_MASK_DGID |
690                           CMDQ_MODIFY_QP_MODIFY_MASK_FLOW_LABEL |
691                           CMDQ_MODIFY_QP_MODIFY_MASK_SGID_INDEX |
692                           CMDQ_MODIFY_QP_MODIFY_MASK_HOP_LIMIT |
693                           CMDQ_MODIFY_QP_MODIFY_MASK_TRAFFIC_CLASS |
694                           CMDQ_MODIFY_QP_MODIFY_MASK_DEST_MAC |
695                           CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU |
696                           CMDQ_MODIFY_QP_MODIFY_MASK_RQ_PSN |
697                           CMDQ_MODIFY_QP_MODIFY_MASK_MIN_RNR_TIMER |
698                           CMDQ_MODIFY_QP_MODIFY_MASK_MAX_DEST_RD_ATOMIC |
699                           CMDQ_MODIFY_QP_MODIFY_MASK_DEST_QP_ID);
700                 break;
701         default:
702                 break;
703         }
704 }
705
706 static void __filter_modify_flags(struct bnxt_qplib_qp *qp)
707 {
708         switch (qp->cur_qp_state) {
709         case CMDQ_MODIFY_QP_NEW_STATE_RESET:
710                 break;
711         case CMDQ_MODIFY_QP_NEW_STATE_INIT:
712                 __modify_flags_from_init_state(qp);
713                 break;
714         case CMDQ_MODIFY_QP_NEW_STATE_RTR:
715                 __modify_flags_from_rtr_state(qp);
716                 break;
717         case CMDQ_MODIFY_QP_NEW_STATE_RTS:
718                 break;
719         case CMDQ_MODIFY_QP_NEW_STATE_SQD:
720                 break;
721         case CMDQ_MODIFY_QP_NEW_STATE_SQE:
722                 break;
723         case CMDQ_MODIFY_QP_NEW_STATE_ERR:
724                 break;
725         default:
726                 break;
727         }
728 }
729
730 int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
731 {
732         struct bnxt_qplib_rcfw *rcfw = res->rcfw;
733         struct cmdq_modify_qp req;
734         struct creq_modify_qp_resp resp;
735         u16 cmd_flags = 0, pkey;
736         u32 temp32[4];
737         u32 bmask;
738         int rc;
739
740         RCFW_CMD_PREP(req, MODIFY_QP, cmd_flags);
741
742         /* Filter out the qp_attr_mask based on the state->new transition */
743         __filter_modify_flags(qp);
744         bmask = qp->modify_flags;
745         req.modify_mask = cpu_to_le32(qp->modify_flags);
746         req.qp_cid = cpu_to_le32(qp->id);
747         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_STATE) {
748                 req.network_type_en_sqd_async_notify_new_state =
749                                 (qp->state & CMDQ_MODIFY_QP_NEW_STATE_MASK) |
750                                 (qp->en_sqd_async_notify ?
751                                         CMDQ_MODIFY_QP_EN_SQD_ASYNC_NOTIFY : 0);
752         }
753         req.network_type_en_sqd_async_notify_new_state |= qp->nw_type;
754
755         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_ACCESS)
756                 req.access = qp->access;
757
758         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_PKEY) {
759                 if (!bnxt_qplib_get_pkey(res, &res->pkey_tbl,
760                                          qp->pkey_index, &pkey))
761                         req.pkey = cpu_to_le16(pkey);
762         }
763         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_QKEY)
764                 req.qkey = cpu_to_le32(qp->qkey);
765
766         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_DGID) {
767                 memcpy(temp32, qp->ah.dgid.data, sizeof(struct bnxt_qplib_gid));
768                 req.dgid[0] = cpu_to_le32(temp32[0]);
769                 req.dgid[1] = cpu_to_le32(temp32[1]);
770                 req.dgid[2] = cpu_to_le32(temp32[2]);
771                 req.dgid[3] = cpu_to_le32(temp32[3]);
772         }
773         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_FLOW_LABEL)
774                 req.flow_label = cpu_to_le32(qp->ah.flow_label);
775
776         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_SGID_INDEX)
777                 req.sgid_index = cpu_to_le16(res->sgid_tbl.hw_id
778                                              [qp->ah.sgid_index]);
779
780         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_HOP_LIMIT)
781                 req.hop_limit = qp->ah.hop_limit;
782
783         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_TRAFFIC_CLASS)
784                 req.traffic_class = qp->ah.traffic_class;
785
786         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_DEST_MAC)
787                 memcpy(req.dest_mac, qp->ah.dmac, 6);
788
789         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU)
790                 req.path_mtu = qp->path_mtu;
791
792         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_TIMEOUT)
793                 req.timeout = qp->timeout;
794
795         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_RETRY_CNT)
796                 req.retry_cnt = qp->retry_cnt;
797
798         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_RNR_RETRY)
799                 req.rnr_retry = qp->rnr_retry;
800
801         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_MIN_RNR_TIMER)
802                 req.min_rnr_timer = qp->min_rnr_timer;
803
804         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_RQ_PSN)
805                 req.rq_psn = cpu_to_le32(qp->rq.psn);
806
807         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_SQ_PSN)
808                 req.sq_psn = cpu_to_le32(qp->sq.psn);
809
810         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_MAX_RD_ATOMIC)
811                 req.max_rd_atomic =
812                         ORD_LIMIT_TO_ORRQ_SLOTS(qp->max_rd_atomic);
813
814         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_MAX_DEST_RD_ATOMIC)
815                 req.max_dest_rd_atomic =
816                         IRD_LIMIT_TO_IRRQ_SLOTS(qp->max_dest_rd_atomic);
817
818         req.sq_size = cpu_to_le32(qp->sq.hwq.max_elements);
819         req.rq_size = cpu_to_le32(qp->rq.hwq.max_elements);
820         req.sq_sge = cpu_to_le16(qp->sq.max_sge);
821         req.rq_sge = cpu_to_le16(qp->rq.max_sge);
822         req.max_inline_data = cpu_to_le32(qp->max_inline_data);
823         if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_DEST_QP_ID)
824                 req.dest_qp_id = cpu_to_le32(qp->dest_qpn);
825
826         req.vlan_pcp_vlan_dei_vlan_id = cpu_to_le16(qp->vlan_id);
827
828         rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
829                                           (void *)&resp, NULL, 0);
830         if (rc)
831                 return rc;
832         qp->cur_qp_state = qp->state;
833         return 0;
834 }
835
836 int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
837 {
838         struct bnxt_qplib_rcfw *rcfw = res->rcfw;
839         struct cmdq_query_qp req;
840         struct creq_query_qp_resp resp;
841         struct bnxt_qplib_rcfw_sbuf *sbuf;
842         struct creq_query_qp_resp_sb *sb;
843         u16 cmd_flags = 0;
844         u32 temp32[4];
845         int i, rc = 0;
846
847         RCFW_CMD_PREP(req, QUERY_QP, cmd_flags);
848
849         sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
850         if (!sbuf)
851                 return -ENOMEM;
852         sb = sbuf->sb;
853
854         req.qp_cid = cpu_to_le32(qp->id);
855         req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
856         rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
857                                           (void *)sbuf, 0);
858         if (rc)
859                 goto bail;
860         /* Extract the context from the side buffer */
861         qp->state = sb->en_sqd_async_notify_state &
862                         CREQ_QUERY_QP_RESP_SB_STATE_MASK;
863         qp->en_sqd_async_notify = sb->en_sqd_async_notify_state &
864                                   CREQ_QUERY_QP_RESP_SB_EN_SQD_ASYNC_NOTIFY ?
865                                   true : false;
866         qp->access = sb->access;
867         qp->pkey_index = le16_to_cpu(sb->pkey);
868         qp->qkey = le32_to_cpu(sb->qkey);
869
870         temp32[0] = le32_to_cpu(sb->dgid[0]);
871         temp32[1] = le32_to_cpu(sb->dgid[1]);
872         temp32[2] = le32_to_cpu(sb->dgid[2]);
873         temp32[3] = le32_to_cpu(sb->dgid[3]);
874         memcpy(qp->ah.dgid.data, temp32, sizeof(qp->ah.dgid.data));
875
876         qp->ah.flow_label = le32_to_cpu(sb->flow_label);
877
878         qp->ah.sgid_index = 0;
879         for (i = 0; i < res->sgid_tbl.max; i++) {
880                 if (res->sgid_tbl.hw_id[i] == le16_to_cpu(sb->sgid_index)) {
881                         qp->ah.sgid_index = i;
882                         break;
883                 }
884         }
885         if (i == res->sgid_tbl.max)
886                 dev_warn(&res->pdev->dev, "QPLIB: SGID not found??");
887
888         qp->ah.hop_limit = sb->hop_limit;
889         qp->ah.traffic_class = sb->traffic_class;
890         memcpy(qp->ah.dmac, sb->dest_mac, 6);
891         qp->ah.vlan_id = (le16_to_cpu(sb->path_mtu_dest_vlan_id) &
892                                 CREQ_QUERY_QP_RESP_SB_VLAN_ID_MASK) >>
893                                 CREQ_QUERY_QP_RESP_SB_VLAN_ID_SFT;
894         qp->path_mtu = (le16_to_cpu(sb->path_mtu_dest_vlan_id) &
895                                     CREQ_QUERY_QP_RESP_SB_PATH_MTU_MASK) >>
896                                     CREQ_QUERY_QP_RESP_SB_PATH_MTU_SFT;
897         qp->timeout = sb->timeout;
898         qp->retry_cnt = sb->retry_cnt;
899         qp->rnr_retry = sb->rnr_retry;
900         qp->min_rnr_timer = sb->min_rnr_timer;
901         qp->rq.psn = le32_to_cpu(sb->rq_psn);
902         qp->max_rd_atomic = ORRQ_SLOTS_TO_ORD_LIMIT(sb->max_rd_atomic);
903         qp->sq.psn = le32_to_cpu(sb->sq_psn);
904         qp->max_dest_rd_atomic =
905                         IRRQ_SLOTS_TO_IRD_LIMIT(sb->max_dest_rd_atomic);
906         qp->sq.max_wqe = qp->sq.hwq.max_elements;
907         qp->rq.max_wqe = qp->rq.hwq.max_elements;
908         qp->sq.max_sge = le16_to_cpu(sb->sq_sge);
909         qp->rq.max_sge = le16_to_cpu(sb->rq_sge);
910         qp->max_inline_data = le32_to_cpu(sb->max_inline_data);
911         qp->dest_qpn = le32_to_cpu(sb->dest_qp_id);
912         memcpy(qp->smac, sb->src_mac, 6);
913         qp->vlan_id = le16_to_cpu(sb->vlan_pcp_vlan_dei_vlan_id);
914 bail:
915         bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
916         return rc;
917 }
918
919 static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp)
920 {
921         struct bnxt_qplib_hwq *cq_hwq = &cq->hwq;
922         struct cq_base *hw_cqe, **hw_cqe_ptr;
923         int i;
924
925         for (i = 0; i < cq_hwq->max_elements; i++) {
926                 hw_cqe_ptr = (struct cq_base **)cq_hwq->pbl_ptr;
927                 hw_cqe = &hw_cqe_ptr[CQE_PG(i)][CQE_IDX(i)];
928                 if (!CQE_CMP_VALID(hw_cqe, i, cq_hwq->max_elements))
929                         continue;
930                 switch (hw_cqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK) {
931                 case CQ_BASE_CQE_TYPE_REQ:
932                 case CQ_BASE_CQE_TYPE_TERMINAL:
933                 {
934                         struct cq_req *cqe = (struct cq_req *)hw_cqe;
935
936                         if (qp == le64_to_cpu(cqe->qp_handle))
937                                 cqe->qp_handle = 0;
938                         break;
939                 }
940                 case CQ_BASE_CQE_TYPE_RES_RC:
941                 case CQ_BASE_CQE_TYPE_RES_UD:
942                 case CQ_BASE_CQE_TYPE_RES_RAWETH_QP1:
943                 {
944                         struct cq_res_rc *cqe = (struct cq_res_rc *)hw_cqe;
945
946                         if (qp == le64_to_cpu(cqe->qp_handle))
947                                 cqe->qp_handle = 0;
948                         break;
949                 }
950                 default:
951                         break;
952                 }
953         }
954 }
955
956 int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
957                           struct bnxt_qplib_qp *qp)
958 {
959         struct bnxt_qplib_rcfw *rcfw = res->rcfw;
960         struct cmdq_destroy_qp req;
961         struct creq_destroy_qp_resp resp;
962         unsigned long flags;
963         u16 cmd_flags = 0;
964         int rc;
965
966         RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags);
967
968         req.qp_cid = cpu_to_le32(qp->id);
969         rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
970                                           (void *)&resp, NULL, 0);
971         if (rc)
972                 return rc;
973
974         /* Must walk the associated CQs to nullified the QP ptr */
975         spin_lock_irqsave(&qp->scq->hwq.lock, flags);
976
977         __clean_cq(qp->scq, (u64)(unsigned long)qp);
978
979         if (qp->rcq && qp->rcq != qp->scq) {
980                 spin_lock(&qp->rcq->hwq.lock);
981                 __clean_cq(qp->rcq, (u64)(unsigned long)qp);
982                 spin_unlock(&qp->rcq->hwq.lock);
983         }
984
985         spin_unlock_irqrestore(&qp->scq->hwq.lock, flags);
986
987         bnxt_qplib_free_qp_hdr_buf(res, qp);
988         bnxt_qplib_free_hwq(res->pdev, &qp->sq.hwq);
989         kfree(qp->sq.swq);
990
991         bnxt_qplib_free_hwq(res->pdev, &qp->rq.hwq);
992         kfree(qp->rq.swq);
993
994         if (qp->irrq.max_elements)
995                 bnxt_qplib_free_hwq(res->pdev, &qp->irrq);
996         if (qp->orrq.max_elements)
997                 bnxt_qplib_free_hwq(res->pdev, &qp->orrq);
998
999         return 0;
1000 }
1001
1002 void *bnxt_qplib_get_qp1_sq_buf(struct bnxt_qplib_qp *qp,
1003                                 struct bnxt_qplib_sge *sge)
1004 {
1005         struct bnxt_qplib_q *sq = &qp->sq;
1006         u32 sw_prod;
1007
1008         memset(sge, 0, sizeof(*sge));
1009
1010         if (qp->sq_hdr_buf) {
1011                 sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);
1012                 sge->addr = (dma_addr_t)(qp->sq_hdr_buf_map +
1013                                          sw_prod * qp->sq_hdr_buf_size);
1014                 sge->lkey = 0xFFFFFFFF;
1015                 sge->size = qp->sq_hdr_buf_size;
1016                 return qp->sq_hdr_buf + sw_prod * sge->size;
1017         }
1018         return NULL;
1019 }
1020
1021 u32 bnxt_qplib_get_rq_prod_index(struct bnxt_qplib_qp *qp)
1022 {
1023         struct bnxt_qplib_q *rq = &qp->rq;
1024
1025         return HWQ_CMP(rq->hwq.prod, &rq->hwq);
1026 }
1027
1028 dma_addr_t bnxt_qplib_get_qp_buf_from_index(struct bnxt_qplib_qp *qp, u32 index)
1029 {
1030         return (qp->rq_hdr_buf_map + index * qp->rq_hdr_buf_size);
1031 }
1032
1033 void *bnxt_qplib_get_qp1_rq_buf(struct bnxt_qplib_qp *qp,
1034                                 struct bnxt_qplib_sge *sge)
1035 {
1036         struct bnxt_qplib_q *rq = &qp->rq;
1037         u32 sw_prod;
1038
1039         memset(sge, 0, sizeof(*sge));
1040
1041         if (qp->rq_hdr_buf) {
1042                 sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);
1043                 sge->addr = (dma_addr_t)(qp->rq_hdr_buf_map +
1044                                          sw_prod * qp->rq_hdr_buf_size);
1045                 sge->lkey = 0xFFFFFFFF;
1046                 sge->size = qp->rq_hdr_buf_size;
1047                 return qp->rq_hdr_buf + sw_prod * sge->size;
1048         }
1049         return NULL;
1050 }
1051
1052 void bnxt_qplib_post_send_db(struct bnxt_qplib_qp *qp)
1053 {
1054         struct bnxt_qplib_q *sq = &qp->sq;
1055         struct dbr_dbr db_msg = { 0 };
1056         u32 sw_prod;
1057
1058         sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);
1059
1060         db_msg.index = cpu_to_le32((sw_prod << DBR_DBR_INDEX_SFT) &
1061                                    DBR_DBR_INDEX_MASK);
1062         db_msg.type_xid =
1063                 cpu_to_le32(((qp->id << DBR_DBR_XID_SFT) & DBR_DBR_XID_MASK) |
1064                             DBR_DBR_TYPE_SQ);
1065         /* Flush all the WQE writes to HW */
1066         wmb();
1067         __iowrite64_copy(qp->dpi->dbr, &db_msg, sizeof(db_msg) / sizeof(u64));
1068 }
1069
1070 int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
1071                          struct bnxt_qplib_swqe *wqe)
1072 {
1073         struct bnxt_qplib_q *sq = &qp->sq;
1074         struct bnxt_qplib_swq *swq;
1075         struct sq_send *hw_sq_send_hdr, **hw_sq_send_ptr;
1076         struct sq_sge *hw_sge;
1077         u32 sw_prod;
1078         u8 wqe_size16;
1079         int i, rc = 0, data_len = 0, pkt_num = 0;
1080         __le32 temp32;
1081
1082         if (qp->state != CMDQ_MODIFY_QP_NEW_STATE_RTS) {
1083                 rc = -EINVAL;
1084                 goto done;
1085         }
1086
1087         if (bnxt_qplib_queue_full(sq)) {
1088                 dev_err(&sq->hwq.pdev->dev,
1089                         "QPLIB: prod = %#x cons = %#x qdepth = %#x delta = %#x",
1090                         sq->hwq.prod, sq->hwq.cons, sq->hwq.max_elements,
1091                         sq->q_full_delta);
1092                 rc = -ENOMEM;
1093                 goto done;
1094         }
1095         sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);
1096         swq = &sq->swq[sw_prod];
1097         swq->wr_id = wqe->wr_id;
1098         swq->type = wqe->type;
1099         swq->flags = wqe->flags;
1100         if (qp->sig_type)
1101                 swq->flags |= SQ_SEND_FLAGS_SIGNAL_COMP;
1102         swq->start_psn = sq->psn & BTH_PSN_MASK;
1103
1104         hw_sq_send_ptr = (struct sq_send **)sq->hwq.pbl_ptr;
1105         hw_sq_send_hdr = &hw_sq_send_ptr[get_sqe_pg(sw_prod)]
1106                                         [get_sqe_idx(sw_prod)];
1107
1108         memset(hw_sq_send_hdr, 0, BNXT_QPLIB_MAX_SQE_ENTRY_SIZE);
1109
1110         if (wqe->flags & BNXT_QPLIB_SWQE_FLAGS_INLINE) {
1111                 /* Copy the inline data */
1112                 if (wqe->inline_len > BNXT_QPLIB_SWQE_MAX_INLINE_LENGTH) {
1113                         dev_warn(&sq->hwq.pdev->dev,
1114                                  "QPLIB: Inline data length > 96 detected");
1115                         data_len = BNXT_QPLIB_SWQE_MAX_INLINE_LENGTH;
1116                 } else {
1117                         data_len = wqe->inline_len;
1118                 }
1119                 memcpy(hw_sq_send_hdr->data, wqe->inline_data, data_len);
1120                 wqe_size16 = (data_len + 15) >> 4;
1121         } else {
1122                 for (i = 0, hw_sge = (struct sq_sge *)hw_sq_send_hdr->data;
1123                      i < wqe->num_sge; i++, hw_sge++) {
1124                         hw_sge->va_or_pa = cpu_to_le64(wqe->sg_list[i].addr);
1125                         hw_sge->l_key = cpu_to_le32(wqe->sg_list[i].lkey);
1126                         hw_sge->size = cpu_to_le32(wqe->sg_list[i].size);
1127                         data_len += wqe->sg_list[i].size;
1128                 }
1129                 /* Each SGE entry = 1 WQE size16 */
1130                 wqe_size16 = wqe->num_sge;
1131         }
1132
1133         /* Specifics */
1134         switch (wqe->type) {
1135         case BNXT_QPLIB_SWQE_TYPE_SEND:
1136                 if (qp->type == CMDQ_CREATE_QP1_TYPE_GSI) {
1137                         /* Assemble info for Raw Ethertype QPs */
1138                         struct sq_send_raweth_qp1 *sqe =
1139                                 (struct sq_send_raweth_qp1 *)hw_sq_send_hdr;
1140
1141                         sqe->wqe_type = wqe->type;
1142                         sqe->flags = wqe->flags;
1143                         sqe->wqe_size = wqe_size16 +
1144                                 ((offsetof(typeof(*sqe), data) + 15) >> 4);
1145                         sqe->cfa_action = cpu_to_le16(wqe->rawqp1.cfa_action);
1146                         sqe->lflags = cpu_to_le16(wqe->rawqp1.lflags);
1147                         sqe->length = cpu_to_le32(data_len);
1148                         sqe->cfa_meta = cpu_to_le32((wqe->rawqp1.cfa_meta &
1149                                 SQ_SEND_RAWETH_QP1_CFA_META_VLAN_VID_MASK) <<
1150                                 SQ_SEND_RAWETH_QP1_CFA_META_VLAN_VID_SFT);
1151
1152                         break;
1153                 }
1154                 /* else, just fall thru */
1155         case BNXT_QPLIB_SWQE_TYPE_SEND_WITH_IMM:
1156         case BNXT_QPLIB_SWQE_TYPE_SEND_WITH_INV:
1157         {
1158                 struct sq_send *sqe = (struct sq_send *)hw_sq_send_hdr;
1159
1160                 sqe->wqe_type = wqe->type;
1161                 sqe->flags = wqe->flags;
1162                 sqe->wqe_size = wqe_size16 +
1163                                 ((offsetof(typeof(*sqe), data) + 15) >> 4);
1164                 sqe->inv_key_or_imm_data = cpu_to_le32(
1165                                                 wqe->send.inv_key);
1166                 if (qp->type == CMDQ_CREATE_QP_TYPE_UD) {
1167                         sqe->q_key = cpu_to_le32(wqe->send.q_key);
1168                         sqe->dst_qp = cpu_to_le32(
1169                                         wqe->send.dst_qp & SQ_SEND_DST_QP_MASK);
1170                         sqe->length = cpu_to_le32(data_len);
1171                         sqe->avid = cpu_to_le32(wqe->send.avid &
1172                                                 SQ_SEND_AVID_MASK);
1173                         sq->psn = (sq->psn + 1) & BTH_PSN_MASK;
1174                 } else {
1175                         sqe->length = cpu_to_le32(data_len);
1176                         sqe->dst_qp = 0;
1177                         sqe->avid = 0;
1178                         if (qp->mtu)
1179                                 pkt_num = (data_len + qp->mtu - 1) / qp->mtu;
1180                         if (!pkt_num)
1181                                 pkt_num = 1;
1182                         sq->psn = (sq->psn + pkt_num) & BTH_PSN_MASK;
1183                 }
1184                 break;
1185         }
1186         case BNXT_QPLIB_SWQE_TYPE_RDMA_WRITE:
1187         case BNXT_QPLIB_SWQE_TYPE_RDMA_WRITE_WITH_IMM:
1188         case BNXT_QPLIB_SWQE_TYPE_RDMA_READ:
1189         {
1190                 struct sq_rdma *sqe = (struct sq_rdma *)hw_sq_send_hdr;
1191
1192                 sqe->wqe_type = wqe->type;
1193                 sqe->flags = wqe->flags;
1194                 sqe->wqe_size = wqe_size16 +
1195                                 ((offsetof(typeof(*sqe), data) + 15) >> 4);
1196                 sqe->imm_data = cpu_to_le32(wqe->rdma.inv_key);
1197                 sqe->length = cpu_to_le32((u32)data_len);
1198                 sqe->remote_va = cpu_to_le64(wqe->rdma.remote_va);
1199                 sqe->remote_key = cpu_to_le32(wqe->rdma.r_key);
1200                 if (qp->mtu)
1201                         pkt_num = (data_len + qp->mtu - 1) / qp->mtu;
1202                 if (!pkt_num)
1203                         pkt_num = 1;
1204                 sq->psn = (sq->psn + pkt_num) & BTH_PSN_MASK;
1205                 break;
1206         }
1207         case BNXT_QPLIB_SWQE_TYPE_ATOMIC_CMP_AND_SWP:
1208         case BNXT_QPLIB_SWQE_TYPE_ATOMIC_FETCH_AND_ADD:
1209         {
1210                 struct sq_atomic *sqe = (struct sq_atomic *)hw_sq_send_hdr;
1211
1212                 sqe->wqe_type = wqe->type;
1213                 sqe->flags = wqe->flags;
1214                 sqe->remote_key = cpu_to_le32(wqe->atomic.r_key);
1215                 sqe->remote_va = cpu_to_le64(wqe->atomic.remote_va);
1216                 sqe->swap_data = cpu_to_le64(wqe->atomic.swap_data);
1217                 sqe->cmp_data = cpu_to_le64(wqe->atomic.cmp_data);
1218                 if (qp->mtu)
1219                         pkt_num = (data_len + qp->mtu - 1) / qp->mtu;
1220                 if (!pkt_num)
1221                         pkt_num = 1;
1222                 sq->psn = (sq->psn + pkt_num) & BTH_PSN_MASK;
1223                 break;
1224         }
1225         case BNXT_QPLIB_SWQE_TYPE_LOCAL_INV:
1226         {
1227                 struct sq_localinvalidate *sqe =
1228                                 (struct sq_localinvalidate *)hw_sq_send_hdr;
1229
1230                 sqe->wqe_type = wqe->type;
1231                 sqe->flags = wqe->flags;
1232                 sqe->inv_l_key = cpu_to_le32(wqe->local_inv.inv_l_key);
1233
1234                 break;
1235         }
1236         case BNXT_QPLIB_SWQE_TYPE_FAST_REG_MR:
1237         {
1238                 struct sq_fr_pmr *sqe = (struct sq_fr_pmr *)hw_sq_send_hdr;
1239
1240                 sqe->wqe_type = wqe->type;
1241                 sqe->flags = wqe->flags;
1242                 sqe->access_cntl = wqe->frmr.access_cntl |
1243                                    SQ_FR_PMR_ACCESS_CNTL_LOCAL_WRITE;
1244                 sqe->zero_based_page_size_log =
1245                         (wqe->frmr.pg_sz_log & SQ_FR_PMR_PAGE_SIZE_LOG_MASK) <<
1246                         SQ_FR_PMR_PAGE_SIZE_LOG_SFT |
1247                         (wqe->frmr.zero_based ? SQ_FR_PMR_ZERO_BASED : 0);
1248                 sqe->l_key = cpu_to_le32(wqe->frmr.l_key);
1249                 temp32 = cpu_to_le32(wqe->frmr.length);
1250                 memcpy(sqe->length, &temp32, sizeof(wqe->frmr.length));
1251                 sqe->numlevels_pbl_page_size_log =
1252                         ((wqe->frmr.pbl_pg_sz_log <<
1253                                         SQ_FR_PMR_PBL_PAGE_SIZE_LOG_SFT) &
1254                                         SQ_FR_PMR_PBL_PAGE_SIZE_LOG_MASK) |
1255                         ((wqe->frmr.levels << SQ_FR_PMR_NUMLEVELS_SFT) &
1256                                         SQ_FR_PMR_NUMLEVELS_MASK);
1257
1258                 for (i = 0; i < wqe->frmr.page_list_len; i++)
1259                         wqe->frmr.pbl_ptr[i] = cpu_to_le64(
1260                                                 wqe->frmr.page_list[i] |
1261                                                 PTU_PTE_VALID);
1262                 sqe->pblptr = cpu_to_le64(wqe->frmr.pbl_dma_ptr);
1263                 sqe->va = cpu_to_le64(wqe->frmr.va);
1264
1265                 break;
1266         }
1267         case BNXT_QPLIB_SWQE_TYPE_BIND_MW:
1268         {
1269                 struct sq_bind *sqe = (struct sq_bind *)hw_sq_send_hdr;
1270
1271                 sqe->wqe_type = wqe->type;
1272                 sqe->flags = wqe->flags;
1273                 sqe->access_cntl = wqe->bind.access_cntl;
1274                 sqe->mw_type_zero_based = wqe->bind.mw_type |
1275                         (wqe->bind.zero_based ? SQ_BIND_ZERO_BASED : 0);
1276                 sqe->parent_l_key = cpu_to_le32(wqe->bind.parent_l_key);
1277                 sqe->l_key = cpu_to_le32(wqe->bind.r_key);
1278                 sqe->va = cpu_to_le64(wqe->bind.va);
1279                 temp32 = cpu_to_le32(wqe->bind.length);
1280                 memcpy(&sqe->length, &temp32, sizeof(wqe->bind.length));
1281                 break;
1282         }
1283         default:
1284                 /* Bad wqe, return error */
1285                 rc = -EINVAL;
1286                 goto done;
1287         }
1288         swq->next_psn = sq->psn & BTH_PSN_MASK;
1289         if (swq->psn_search) {
1290                 swq->psn_search->opcode_start_psn = cpu_to_le32(
1291                         ((swq->start_psn << SQ_PSN_SEARCH_START_PSN_SFT) &
1292                          SQ_PSN_SEARCH_START_PSN_MASK) |
1293                         ((wqe->type << SQ_PSN_SEARCH_OPCODE_SFT) &
1294                          SQ_PSN_SEARCH_OPCODE_MASK));
1295                 swq->psn_search->flags_next_psn = cpu_to_le32(
1296                         ((swq->next_psn << SQ_PSN_SEARCH_NEXT_PSN_SFT) &
1297                          SQ_PSN_SEARCH_NEXT_PSN_MASK));
1298         }
1299
1300         sq->hwq.prod++;
1301 done:
1302         return rc;
1303 }
1304
1305 void bnxt_qplib_post_recv_db(struct bnxt_qplib_qp *qp)
1306 {
1307         struct bnxt_qplib_q *rq = &qp->rq;
1308         struct dbr_dbr db_msg = { 0 };
1309         u32 sw_prod;
1310
1311         sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);
1312         db_msg.index = cpu_to_le32((sw_prod << DBR_DBR_INDEX_SFT) &
1313                                    DBR_DBR_INDEX_MASK);
1314         db_msg.type_xid =
1315                 cpu_to_le32(((qp->id << DBR_DBR_XID_SFT) & DBR_DBR_XID_MASK) |
1316                             DBR_DBR_TYPE_RQ);
1317
1318         /* Flush the writes to HW Rx WQE before the ringing Rx DB */
1319         wmb();
1320         __iowrite64_copy(qp->dpi->dbr, &db_msg, sizeof(db_msg) / sizeof(u64));
1321 }
1322
1323 int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
1324                          struct bnxt_qplib_swqe *wqe)
1325 {
1326         struct bnxt_qplib_q *rq = &qp->rq;
1327         struct rq_wqe *rqe, **rqe_ptr;
1328         struct sq_sge *hw_sge;
1329         u32 sw_prod;
1330         int i, rc = 0;
1331
1332         if (qp->state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
1333                 dev_err(&rq->hwq.pdev->dev,
1334                         "QPLIB: FP: QP (0x%x) is in the 0x%x state",
1335                         qp->id, qp->state);
1336                 rc = -EINVAL;
1337                 goto done;
1338         }
1339         if (bnxt_qplib_queue_full(rq)) {
1340                 dev_err(&rq->hwq.pdev->dev,
1341                         "QPLIB: FP: QP (0x%x) RQ is full!", qp->id);
1342                 rc = -EINVAL;
1343                 goto done;
1344         }
1345         sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);
1346         rq->swq[sw_prod].wr_id = wqe->wr_id;
1347
1348         rqe_ptr = (struct rq_wqe **)rq->hwq.pbl_ptr;
1349         rqe = &rqe_ptr[RQE_PG(sw_prod)][RQE_IDX(sw_prod)];
1350
1351         memset(rqe, 0, BNXT_QPLIB_MAX_RQE_ENTRY_SIZE);
1352
1353         /* Calculate wqe_size16 and data_len */
1354         for (i = 0, hw_sge = (struct sq_sge *)rqe->data;
1355              i < wqe->num_sge; i++, hw_sge++) {
1356                 hw_sge->va_or_pa = cpu_to_le64(wqe->sg_list[i].addr);
1357                 hw_sge->l_key = cpu_to_le32(wqe->sg_list[i].lkey);
1358                 hw_sge->size = cpu_to_le32(wqe->sg_list[i].size);
1359         }
1360         rqe->wqe_type = wqe->type;
1361         rqe->flags = wqe->flags;
1362         rqe->wqe_size = wqe->num_sge +
1363                         ((offsetof(typeof(*rqe), data) + 15) >> 4);
1364
1365         /* Supply the rqe->wr_id index to the wr_id_tbl for now */
1366         rqe->wr_id[0] = cpu_to_le32(sw_prod);
1367
1368         rq->hwq.prod++;
1369 done:
1370         return rc;
1371 }
1372
1373 /* CQ */
1374
1375 /* Spinlock must be held */
1376 static void bnxt_qplib_arm_cq_enable(struct bnxt_qplib_cq *cq)
1377 {
1378         struct dbr_dbr db_msg = { 0 };
1379
1380         db_msg.type_xid =
1381                 cpu_to_le32(((cq->id << DBR_DBR_XID_SFT) & DBR_DBR_XID_MASK) |
1382                             DBR_DBR_TYPE_CQ_ARMENA);
1383         /* Flush memory writes before enabling the CQ */
1384         wmb();
1385         __iowrite64_copy(cq->dbr_base, &db_msg, sizeof(db_msg) / sizeof(u64));
1386 }
1387
1388 static void bnxt_qplib_arm_cq(struct bnxt_qplib_cq *cq, u32 arm_type)
1389 {
1390         struct bnxt_qplib_hwq *cq_hwq = &cq->hwq;
1391         struct dbr_dbr db_msg = { 0 };
1392         u32 sw_cons;
1393
1394         /* Ring DB */
1395         sw_cons = HWQ_CMP(cq_hwq->cons, cq_hwq);
1396         db_msg.index = cpu_to_le32((sw_cons << DBR_DBR_INDEX_SFT) &
1397                                     DBR_DBR_INDEX_MASK);
1398         db_msg.type_xid =
1399                 cpu_to_le32(((cq->id << DBR_DBR_XID_SFT) & DBR_DBR_XID_MASK) |
1400                             arm_type);
1401         /* flush memory writes before arming the CQ */
1402         wmb();
1403         __iowrite64_copy(cq->dpi->dbr, &db_msg, sizeof(db_msg) / sizeof(u64));
1404 }
1405
1406 int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
1407 {
1408         struct bnxt_qplib_rcfw *rcfw = res->rcfw;
1409         struct cmdq_create_cq req;
1410         struct creq_create_cq_resp resp;
1411         struct bnxt_qplib_pbl *pbl;
1412         u16 cmd_flags = 0;
1413         int rc;
1414
1415         cq->hwq.max_elements = cq->max_wqe;
1416         rc = bnxt_qplib_alloc_init_hwq(res->pdev, &cq->hwq, cq->sghead,
1417                                        cq->nmap, &cq->hwq.max_elements,
1418                                        BNXT_QPLIB_MAX_CQE_ENTRY_SIZE, 0,
1419                                        PAGE_SIZE, HWQ_TYPE_QUEUE);
1420         if (rc)
1421                 goto exit;
1422
1423         RCFW_CMD_PREP(req, CREATE_CQ, cmd_flags);
1424
1425         if (!cq->dpi) {
1426                 dev_err(&rcfw->pdev->dev,
1427                         "QPLIB: FP: CREATE_CQ failed due to NULL DPI");
1428                 return -EINVAL;
1429         }
1430         req.dpi = cpu_to_le32(cq->dpi->dpi);
1431         req.cq_handle = cpu_to_le64(cq->cq_handle);
1432
1433         req.cq_size = cpu_to_le32(cq->hwq.max_elements);
1434         pbl = &cq->hwq.pbl[PBL_LVL_0];
1435         req.pg_size_lvl = cpu_to_le32(
1436             ((cq->hwq.level & CMDQ_CREATE_CQ_LVL_MASK) <<
1437                                                 CMDQ_CREATE_CQ_LVL_SFT) |
1438             (pbl->pg_size == ROCE_PG_SIZE_4K ? CMDQ_CREATE_CQ_PG_SIZE_PG_4K :
1439              pbl->pg_size == ROCE_PG_SIZE_8K ? CMDQ_CREATE_CQ_PG_SIZE_PG_8K :
1440              pbl->pg_size == ROCE_PG_SIZE_64K ? CMDQ_CREATE_CQ_PG_SIZE_PG_64K :
1441              pbl->pg_size == ROCE_PG_SIZE_2M ? CMDQ_CREATE_CQ_PG_SIZE_PG_2M :
1442              pbl->pg_size == ROCE_PG_SIZE_8M ? CMDQ_CREATE_CQ_PG_SIZE_PG_8M :
1443              pbl->pg_size == ROCE_PG_SIZE_1G ? CMDQ_CREATE_CQ_PG_SIZE_PG_1G :
1444              CMDQ_CREATE_CQ_PG_SIZE_PG_4K));
1445
1446         req.pbl = cpu_to_le64(pbl->pg_map_arr[0]);
1447
1448         req.cq_fco_cnq_id = cpu_to_le32(
1449                         (cq->cnq_hw_ring_id & CMDQ_CREATE_CQ_CNQ_ID_MASK) <<
1450                          CMDQ_CREATE_CQ_CNQ_ID_SFT);
1451
1452         rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
1453                                           (void *)&resp, NULL, 0);
1454         if (rc)
1455                 goto fail;
1456
1457         cq->id = le32_to_cpu(resp.xid);
1458         cq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem;
1459         cq->period = BNXT_QPLIB_QUEUE_START_PERIOD;
1460         init_waitqueue_head(&cq->waitq);
1461
1462         bnxt_qplib_arm_cq_enable(cq);
1463         return 0;
1464
1465 fail:
1466         bnxt_qplib_free_hwq(res->pdev, &cq->hwq);
1467 exit:
1468         return rc;
1469 }
1470
1471 int bnxt_qplib_destroy_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
1472 {
1473         struct bnxt_qplib_rcfw *rcfw = res->rcfw;
1474         struct cmdq_destroy_cq req;
1475         struct creq_destroy_cq_resp resp;
1476         u16 cmd_flags = 0;
1477         int rc;
1478
1479         RCFW_CMD_PREP(req, DESTROY_CQ, cmd_flags);
1480
1481         req.cq_cid = cpu_to_le32(cq->id);
1482         rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
1483                                           (void *)&resp, NULL, 0);
1484         if (rc)
1485                 return rc;
1486         bnxt_qplib_free_hwq(res->pdev, &cq->hwq);
1487         return 0;
1488 }
1489
1490 static int __flush_sq(struct bnxt_qplib_q *sq, struct bnxt_qplib_qp *qp,
1491                       struct bnxt_qplib_cqe **pcqe, int *budget)
1492 {
1493         u32 sw_prod, sw_cons;
1494         struct bnxt_qplib_cqe *cqe;
1495         int rc = 0;
1496
1497         /* Now complete all outstanding SQEs with FLUSHED_ERR */
1498         sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);
1499         cqe = *pcqe;
1500         while (*budget) {
1501                 sw_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);
1502                 if (sw_cons == sw_prod) {
1503                         sq->flush_in_progress = false;
1504                         break;
1505                 }
1506                 memset(cqe, 0, sizeof(*cqe));
1507                 cqe->status = CQ_REQ_STATUS_WORK_REQUEST_FLUSHED_ERR;
1508                 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
1509                 cqe->qp_handle = (u64)(unsigned long)qp;
1510                 cqe->wr_id = sq->swq[sw_cons].wr_id;
1511                 cqe->src_qp = qp->id;
1512                 cqe->type = sq->swq[sw_cons].type;
1513                 cqe++;
1514                 (*budget)--;
1515                 sq->hwq.cons++;
1516         }
1517         *pcqe = cqe;
1518         if (!(*budget) && HWQ_CMP(sq->hwq.cons, &sq->hwq) != sw_prod)
1519                 /* Out of budget */
1520                 rc = -EAGAIN;
1521
1522         return rc;
1523 }
1524
1525 static int __flush_rq(struct bnxt_qplib_q *rq, struct bnxt_qplib_qp *qp,
1526                       int opcode, struct bnxt_qplib_cqe **pcqe, int *budget)
1527 {
1528         struct bnxt_qplib_cqe *cqe;
1529         u32 sw_prod, sw_cons;
1530         int rc = 0;
1531
1532         /* Flush the rest of the RQ */
1533         sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);
1534         cqe = *pcqe;
1535         while (*budget) {
1536                 sw_cons = HWQ_CMP(rq->hwq.cons, &rq->hwq);
1537                 if (sw_cons == sw_prod)
1538                         break;
1539                 memset(cqe, 0, sizeof(*cqe));
1540                 cqe->status =
1541                     CQ_RES_RC_STATUS_WORK_REQUEST_FLUSHED_ERR;
1542                 cqe->opcode = opcode;
1543                 cqe->qp_handle = (unsigned long)qp;
1544                 cqe->wr_id = rq->swq[sw_cons].wr_id;
1545                 cqe++;
1546                 (*budget)--;
1547                 rq->hwq.cons++;
1548         }
1549         *pcqe = cqe;
1550         if (!*budget && HWQ_CMP(rq->hwq.cons, &rq->hwq) != sw_prod)
1551                 /* Out of budget */
1552                 rc = -EAGAIN;
1553
1554         return rc;
1555 }
1556
1557 /* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive)
1558  *       CQE is track from sw_cq_cons to max_element but valid only if VALID=1
1559  */
1560 static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
1561                      u32 cq_cons, u32 sw_sq_cons, u32 cqe_sq_cons)
1562 {
1563         struct bnxt_qplib_q *sq = &qp->sq;
1564         struct bnxt_qplib_swq *swq;
1565         u32 peek_sw_cq_cons, peek_raw_cq_cons, peek_sq_cons_idx;
1566         struct cq_base *peek_hwcqe, **peek_hw_cqe_ptr;
1567         struct cq_req *peek_req_hwcqe;
1568         struct bnxt_qplib_qp *peek_qp;
1569         struct bnxt_qplib_q *peek_sq;
1570         int i, rc = 0;
1571
1572         /* Normal mode */
1573         /* Check for the psn_search marking before completing */
1574         swq = &sq->swq[sw_sq_cons];
1575         if (swq->psn_search &&
1576             le32_to_cpu(swq->psn_search->flags_next_psn) & 0x80000000) {
1577                 /* Unmark */
1578                 swq->psn_search->flags_next_psn = cpu_to_le32
1579                         (le32_to_cpu(swq->psn_search->flags_next_psn)
1580                                      & ~0x80000000);
1581                 dev_dbg(&cq->hwq.pdev->dev,
1582                         "FP: Process Req cq_cons=0x%x qp=0x%x sq cons sw=0x%x cqe=0x%x marked!\n",
1583                         cq_cons, qp->id, sw_sq_cons, cqe_sq_cons);
1584                 sq->condition = true;
1585                 sq->send_phantom = true;
1586
1587                 /* TODO: Only ARM if the previous SQE is ARMALL */
1588                 bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ_ARMALL);
1589
1590                 rc = -EAGAIN;
1591                 goto out;
1592         }
1593         if (sq->condition) {
1594                 /* Peek at the completions */
1595                 peek_raw_cq_cons = cq->hwq.cons;
1596                 peek_sw_cq_cons = cq_cons;
1597                 i = cq->hwq.max_elements;
1598                 while (i--) {
1599                         peek_sw_cq_cons = HWQ_CMP((peek_sw_cq_cons), &cq->hwq);
1600                         peek_hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr;
1601                         peek_hwcqe = &peek_hw_cqe_ptr[CQE_PG(peek_sw_cq_cons)]
1602                                                      [CQE_IDX(peek_sw_cq_cons)];
1603                         /* If the next hwcqe is VALID */
1604                         if (CQE_CMP_VALID(peek_hwcqe, peek_raw_cq_cons,
1605                                           cq->hwq.max_elements)) {
1606                                 /* If the next hwcqe is a REQ */
1607                                 if ((peek_hwcqe->cqe_type_toggle &
1608                                     CQ_BASE_CQE_TYPE_MASK) ==
1609                                     CQ_BASE_CQE_TYPE_REQ) {
1610                                         peek_req_hwcqe = (struct cq_req *)
1611                                                          peek_hwcqe;
1612                                         peek_qp = (struct bnxt_qplib_qp *)
1613                                                 ((unsigned long)
1614                                                  le64_to_cpu
1615                                                  (peek_req_hwcqe->qp_handle));
1616                                         peek_sq = &peek_qp->sq;
1617                                         peek_sq_cons_idx = HWQ_CMP(le16_to_cpu(
1618                                                 peek_req_hwcqe->sq_cons_idx) - 1
1619                                                 , &sq->hwq);
1620                                         /* If the hwcqe's sq's wr_id matches */
1621                                         if (peek_sq == sq &&
1622                                             sq->swq[peek_sq_cons_idx].wr_id ==
1623                                             BNXT_QPLIB_FENCE_WRID) {
1624                                                 /*
1625                                                  *  Unbreak only if the phantom
1626                                                  *  comes back
1627                                                  */
1628                                                 dev_dbg(&cq->hwq.pdev->dev,
1629                                                         "FP:Got Phantom CQE");
1630                                                 sq->condition = false;
1631                                                 sq->single = true;
1632                                                 rc = 0;
1633                                                 goto out;
1634                                         }
1635                                 }
1636                                 /* Valid but not the phantom, so keep looping */
1637                         } else {
1638                                 /* Not valid yet, just exit and wait */
1639                                 rc = -EINVAL;
1640                                 goto out;
1641                         }
1642                         peek_sw_cq_cons++;
1643                         peek_raw_cq_cons++;
1644                 }
1645                 dev_err(&cq->hwq.pdev->dev,
1646                         "Should not have come here! cq_cons=0x%x qp=0x%x sq cons sw=0x%x hw=0x%x",
1647                         cq_cons, qp->id, sw_sq_cons, cqe_sq_cons);
1648                 rc = -EINVAL;
1649         }
1650 out:
1651         return rc;
1652 }
1653
1654 static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
1655                                      struct cq_req *hwcqe,
1656                                      struct bnxt_qplib_cqe **pcqe, int *budget,
1657                                      u32 cq_cons, struct bnxt_qplib_qp **lib_qp)
1658 {
1659         struct bnxt_qplib_qp *qp;
1660         struct bnxt_qplib_q *sq;
1661         struct bnxt_qplib_cqe *cqe;
1662         u32 sw_sq_cons, cqe_sq_cons;
1663         struct bnxt_qplib_swq *swq;
1664         int rc = 0;
1665
1666         qp = (struct bnxt_qplib_qp *)((unsigned long)
1667                                       le64_to_cpu(hwcqe->qp_handle));
1668         if (!qp) {
1669                 dev_err(&cq->hwq.pdev->dev,
1670                         "QPLIB: FP: Process Req qp is NULL");
1671                 return -EINVAL;
1672         }
1673         sq = &qp->sq;
1674
1675         cqe_sq_cons = HWQ_CMP(le16_to_cpu(hwcqe->sq_cons_idx), &sq->hwq);
1676         if (cqe_sq_cons > sq->hwq.max_elements) {
1677                 dev_err(&cq->hwq.pdev->dev,
1678                         "QPLIB: FP: CQ Process req reported ");
1679                 dev_err(&cq->hwq.pdev->dev,
1680                         "QPLIB: sq_cons_idx 0x%x which exceeded max 0x%x",
1681                         cqe_sq_cons, sq->hwq.max_elements);
1682                 return -EINVAL;
1683         }
1684         /* If we were in the middle of flushing the SQ, continue */
1685         if (sq->flush_in_progress)
1686                 goto flush;
1687
1688         /* Require to walk the sq's swq to fabricate CQEs for all previously
1689          * signaled SWQEs due to CQE aggregation from the current sq cons
1690          * to the cqe_sq_cons
1691          */
1692         cqe = *pcqe;
1693         while (*budget) {
1694                 sw_sq_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);
1695                 if (sw_sq_cons == cqe_sq_cons)
1696                         /* Done */
1697                         break;
1698
1699                 swq = &sq->swq[sw_sq_cons];
1700                 memset(cqe, 0, sizeof(*cqe));
1701                 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
1702                 cqe->qp_handle = (u64)(unsigned long)qp;
1703                 cqe->src_qp = qp->id;
1704                 cqe->wr_id = swq->wr_id;
1705                 if (cqe->wr_id == BNXT_QPLIB_FENCE_WRID)
1706                         goto skip;
1707                 cqe->type = swq->type;
1708
1709                 /* For the last CQE, check for status.  For errors, regardless
1710                  * of the request being signaled or not, it must complete with
1711                  * the hwcqe error status
1712                  */
1713                 if (HWQ_CMP((sw_sq_cons + 1), &sq->hwq) == cqe_sq_cons &&
1714                     hwcqe->status != CQ_REQ_STATUS_OK) {
1715                         cqe->status = hwcqe->status;
1716                         dev_err(&cq->hwq.pdev->dev,
1717                                 "QPLIB: FP: CQ Processed Req ");
1718                         dev_err(&cq->hwq.pdev->dev,
1719                                 "QPLIB: wr_id[%d] = 0x%llx with status 0x%x",
1720                                 sw_sq_cons, cqe->wr_id, cqe->status);
1721                         cqe++;
1722                         (*budget)--;
1723                         sq->flush_in_progress = true;
1724                         /* Must block new posting of SQ and RQ */
1725                         qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
1726                         sq->condition = false;
1727                         sq->single = false;
1728                 } else {
1729                         if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
1730                                 /* Before we complete, do WA 9060 */
1731                                 if (do_wa9060(qp, cq, cq_cons, sw_sq_cons,
1732                                               cqe_sq_cons)) {
1733                                         *lib_qp = qp;
1734                                         goto out;
1735                                 }
1736                                 cqe->status = CQ_REQ_STATUS_OK;
1737                                 cqe++;
1738                                 (*budget)--;
1739                         }
1740                 }
1741 skip:
1742                 sq->hwq.cons++;
1743                 if (sq->single)
1744                         break;
1745         }
1746 out:
1747         *pcqe = cqe;
1748         if (HWQ_CMP(sq->hwq.cons, &sq->hwq) != cqe_sq_cons) {
1749                 /* Out of budget */
1750                 rc = -EAGAIN;
1751                 goto done;
1752         }
1753         /*
1754          * Back to normal completion mode only after it has completed all of
1755          * the WC for this CQE
1756          */
1757         sq->single = false;
1758         if (!sq->flush_in_progress)
1759                 goto done;
1760 flush:
1761         /* Require to walk the sq's swq to fabricate CQEs for all
1762          * previously posted SWQEs due to the error CQE received
1763          */
1764         rc = __flush_sq(sq, qp, pcqe, budget);
1765         if (!rc)
1766                 sq->flush_in_progress = false;
1767 done:
1768         return rc;
1769 }
1770
1771 static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq,
1772                                         struct cq_res_rc *hwcqe,
1773                                         struct bnxt_qplib_cqe **pcqe,
1774                                         int *budget)
1775 {
1776         struct bnxt_qplib_qp *qp;
1777         struct bnxt_qplib_q *rq;
1778         struct bnxt_qplib_cqe *cqe;
1779         u32 wr_id_idx;
1780         int rc = 0;
1781
1782         qp = (struct bnxt_qplib_qp *)((unsigned long)
1783                                       le64_to_cpu(hwcqe->qp_handle));
1784         if (!qp) {
1785                 dev_err(&cq->hwq.pdev->dev, "QPLIB: process_cq RC qp is NULL");
1786                 return -EINVAL;
1787         }
1788         cqe = *pcqe;
1789         cqe->opcode = hwcqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK;
1790         cqe->length = le32_to_cpu(hwcqe->length);
1791         cqe->invrkey = le32_to_cpu(hwcqe->imm_data_or_inv_r_key);
1792         cqe->mr_handle = le64_to_cpu(hwcqe->mr_handle);
1793         cqe->flags = le16_to_cpu(hwcqe->flags);
1794         cqe->status = hwcqe->status;
1795         cqe->qp_handle = (u64)(unsigned long)qp;
1796
1797         wr_id_idx = le32_to_cpu(hwcqe->srq_or_rq_wr_id) &
1798                                 CQ_RES_RC_SRQ_OR_RQ_WR_ID_MASK;
1799         rq = &qp->rq;
1800         if (wr_id_idx > rq->hwq.max_elements) {
1801                 dev_err(&cq->hwq.pdev->dev, "QPLIB: FP: CQ Process RC ");
1802                 dev_err(&cq->hwq.pdev->dev,
1803                         "QPLIB: wr_id idx 0x%x exceeded RQ max 0x%x",
1804                         wr_id_idx, rq->hwq.max_elements);
1805                 return -EINVAL;
1806         }
1807         if (rq->flush_in_progress)
1808                 goto flush_rq;
1809
1810         cqe->wr_id = rq->swq[wr_id_idx].wr_id;
1811         cqe++;
1812         (*budget)--;
1813         rq->hwq.cons++;
1814         *pcqe = cqe;
1815
1816         if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
1817                 rq->flush_in_progress = true;
1818 flush_rq:
1819                 rc = __flush_rq(rq, qp, CQ_BASE_CQE_TYPE_RES_RC, pcqe, budget);
1820                 if (!rc)
1821                         rq->flush_in_progress = false;
1822         }
1823         return rc;
1824 }
1825
1826 static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq,
1827                                         struct cq_res_ud *hwcqe,
1828                                         struct bnxt_qplib_cqe **pcqe,
1829                                         int *budget)
1830 {
1831         struct bnxt_qplib_qp *qp;
1832         struct bnxt_qplib_q *rq;
1833         struct bnxt_qplib_cqe *cqe;
1834         u32 wr_id_idx;
1835         int rc = 0;
1836
1837         qp = (struct bnxt_qplib_qp *)((unsigned long)
1838                                       le64_to_cpu(hwcqe->qp_handle));
1839         if (!qp) {
1840                 dev_err(&cq->hwq.pdev->dev, "QPLIB: process_cq UD qp is NULL");
1841                 return -EINVAL;
1842         }
1843         cqe = *pcqe;
1844         cqe->opcode = hwcqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK;
1845         cqe->length = le32_to_cpu(hwcqe->length);
1846         cqe->invrkey = le32_to_cpu(hwcqe->imm_data);
1847         cqe->flags = le16_to_cpu(hwcqe->flags);
1848         cqe->status = hwcqe->status;
1849         cqe->qp_handle = (u64)(unsigned long)qp;
1850         memcpy(cqe->smac, hwcqe->src_mac, 6);
1851         wr_id_idx = le32_to_cpu(hwcqe->src_qp_high_srq_or_rq_wr_id)
1852                                 & CQ_RES_UD_SRQ_OR_RQ_WR_ID_MASK;
1853         cqe->src_qp = le16_to_cpu(hwcqe->src_qp_low) |
1854                                   ((le32_to_cpu(
1855                                   hwcqe->src_qp_high_srq_or_rq_wr_id) &
1856                                  CQ_RES_UD_SRC_QP_HIGH_MASK) >> 8);
1857
1858         rq = &qp->rq;
1859         if (wr_id_idx > rq->hwq.max_elements) {
1860                 dev_err(&cq->hwq.pdev->dev, "QPLIB: FP: CQ Process UD ");
1861                 dev_err(&cq->hwq.pdev->dev,
1862                         "QPLIB: wr_id idx %#x exceeded RQ max %#x",
1863                         wr_id_idx, rq->hwq.max_elements);
1864                 return -EINVAL;
1865         }
1866         if (rq->flush_in_progress)
1867                 goto flush_rq;
1868
1869         cqe->wr_id = rq->swq[wr_id_idx].wr_id;
1870         cqe++;
1871         (*budget)--;
1872         rq->hwq.cons++;
1873         *pcqe = cqe;
1874
1875         if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
1876                 rq->flush_in_progress = true;
1877 flush_rq:
1878                 rc = __flush_rq(rq, qp, CQ_BASE_CQE_TYPE_RES_UD, pcqe, budget);
1879                 if (!rc)
1880                         rq->flush_in_progress = false;
1881         }
1882         return rc;
1883 }
1884
1885 static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq,
1886                                                 struct cq_res_raweth_qp1 *hwcqe,
1887                                                 struct bnxt_qplib_cqe **pcqe,
1888                                                 int *budget)
1889 {
1890         struct bnxt_qplib_qp *qp;
1891         struct bnxt_qplib_q *rq;
1892         struct bnxt_qplib_cqe *cqe;
1893         u32 wr_id_idx;
1894         int rc = 0;
1895
1896         qp = (struct bnxt_qplib_qp *)((unsigned long)
1897                                       le64_to_cpu(hwcqe->qp_handle));
1898         if (!qp) {
1899                 dev_err(&cq->hwq.pdev->dev,
1900                         "QPLIB: process_cq Raw/QP1 qp is NULL");
1901                 return -EINVAL;
1902         }
1903         cqe = *pcqe;
1904         cqe->opcode = hwcqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK;
1905         cqe->flags = le16_to_cpu(hwcqe->flags);
1906         cqe->qp_handle = (u64)(unsigned long)qp;
1907
1908         wr_id_idx =
1909                 le32_to_cpu(hwcqe->raweth_qp1_payload_offset_srq_or_rq_wr_id)
1910                                 & CQ_RES_RAWETH_QP1_SRQ_OR_RQ_WR_ID_MASK;
1911         cqe->src_qp = qp->id;
1912         if (qp->id == 1 && !cqe->length) {
1913                 /* Add workaround for the length misdetection */
1914                 cqe->length = 296;
1915         } else {
1916                 cqe->length = le16_to_cpu(hwcqe->length);
1917         }
1918         cqe->pkey_index = qp->pkey_index;
1919         memcpy(cqe->smac, qp->smac, 6);
1920
1921         cqe->raweth_qp1_flags = le16_to_cpu(hwcqe->raweth_qp1_flags);
1922         cqe->raweth_qp1_flags2 = le32_to_cpu(hwcqe->raweth_qp1_flags2);
1923
1924         rq = &qp->rq;
1925         if (wr_id_idx > rq->hwq.max_elements) {
1926                 dev_err(&cq->hwq.pdev->dev, "QPLIB: FP: CQ Process Raw/QP1 RQ wr_id ");
1927                 dev_err(&cq->hwq.pdev->dev, "QPLIB: ix 0x%x exceeded RQ max 0x%x",
1928                         wr_id_idx, rq->hwq.max_elements);
1929                 return -EINVAL;
1930         }
1931         if (rq->flush_in_progress)
1932                 goto flush_rq;
1933
1934         cqe->wr_id = rq->swq[wr_id_idx].wr_id;
1935         cqe++;
1936         (*budget)--;
1937         rq->hwq.cons++;
1938         *pcqe = cqe;
1939
1940         if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
1941                 rq->flush_in_progress = true;
1942 flush_rq:
1943                 rc = __flush_rq(rq, qp, CQ_BASE_CQE_TYPE_RES_RAWETH_QP1, pcqe,
1944                                 budget);
1945                 if (!rc)
1946                         rq->flush_in_progress = false;
1947         }
1948         return rc;
1949 }
1950
1951 static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
1952                                           struct cq_terminal *hwcqe,
1953                                           struct bnxt_qplib_cqe **pcqe,
1954                                           int *budget)
1955 {
1956         struct bnxt_qplib_qp *qp;
1957         struct bnxt_qplib_q *sq, *rq;
1958         struct bnxt_qplib_cqe *cqe;
1959         u32 sw_cons = 0, cqe_cons;
1960         int rc = 0;
1961         u8 opcode = 0;
1962
1963         /* Check the Status */
1964         if (hwcqe->status != CQ_TERMINAL_STATUS_OK)
1965                 dev_warn(&cq->hwq.pdev->dev,
1966                          "QPLIB: FP: CQ Process Terminal Error status = 0x%x",
1967                          hwcqe->status);
1968
1969         qp = (struct bnxt_qplib_qp *)((unsigned long)
1970                                       le64_to_cpu(hwcqe->qp_handle));
1971         if (!qp) {
1972                 dev_err(&cq->hwq.pdev->dev,
1973                         "QPLIB: FP: CQ Process terminal qp is NULL");
1974                 return -EINVAL;
1975         }
1976         /* Must block new posting of SQ and RQ */
1977         qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
1978
1979         sq = &qp->sq;
1980         rq = &qp->rq;
1981
1982         cqe_cons = le16_to_cpu(hwcqe->sq_cons_idx);
1983         if (cqe_cons == 0xFFFF)
1984                 goto do_rq;
1985
1986         if (cqe_cons > sq->hwq.max_elements) {
1987                 dev_err(&cq->hwq.pdev->dev,
1988                         "QPLIB: FP: CQ Process terminal reported ");
1989                 dev_err(&cq->hwq.pdev->dev,
1990                         "QPLIB: sq_cons_idx 0x%x which exceeded max 0x%x",
1991                         cqe_cons, sq->hwq.max_elements);
1992                 goto do_rq;
1993         }
1994         /* If we were in the middle of flushing, continue */
1995         if (sq->flush_in_progress)
1996                 goto flush_sq;
1997
1998         /* Terminal CQE can also include aggregated successful CQEs prior.
1999          * So we must complete all CQEs from the current sq's cons to the
2000          * cq_cons with status OK
2001          */
2002         cqe = *pcqe;
2003         while (*budget) {
2004                 sw_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);
2005                 if (sw_cons == cqe_cons)
2006                         break;
2007                 if (sq->swq[sw_cons].flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
2008                         memset(cqe, 0, sizeof(*cqe));
2009                         cqe->status = CQ_REQ_STATUS_OK;
2010                         cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
2011                         cqe->qp_handle = (u64)(unsigned long)qp;
2012                         cqe->src_qp = qp->id;
2013                         cqe->wr_id = sq->swq[sw_cons].wr_id;
2014                         cqe->type = sq->swq[sw_cons].type;
2015                         cqe++;
2016                         (*budget)--;
2017                 }
2018                 sq->hwq.cons++;
2019         }
2020         *pcqe = cqe;
2021         if (!(*budget) && sw_cons != cqe_cons) {
2022                 /* Out of budget */
2023                 rc = -EAGAIN;
2024                 goto sq_done;
2025         }
2026         sq->flush_in_progress = true;
2027 flush_sq:
2028         rc = __flush_sq(sq, qp, pcqe, budget);
2029         if (!rc)
2030                 sq->flush_in_progress = false;
2031 sq_done:
2032         if (rc)
2033                 return rc;
2034 do_rq:
2035         cqe_cons = le16_to_cpu(hwcqe->rq_cons_idx);
2036         if (cqe_cons == 0xFFFF) {
2037                 goto done;
2038         } else if (cqe_cons > rq->hwq.max_elements) {
2039                 dev_err(&cq->hwq.pdev->dev,
2040                         "QPLIB: FP: CQ Processed terminal ");
2041                 dev_err(&cq->hwq.pdev->dev,
2042                         "QPLIB: reported rq_cons_idx 0x%x exceeds max 0x%x",
2043                         cqe_cons, rq->hwq.max_elements);
2044                 goto done;
2045         }
2046         /* Terminal CQE requires all posted RQEs to complete with FLUSHED_ERR
2047          * from the current rq->cons to the rq->prod regardless what the
2048          * rq->cons the terminal CQE indicates
2049          */
2050         rq->flush_in_progress = true;
2051         switch (qp->type) {
2052         case CMDQ_CREATE_QP1_TYPE_GSI:
2053                 opcode = CQ_BASE_CQE_TYPE_RES_RAWETH_QP1;
2054                 break;
2055         case CMDQ_CREATE_QP_TYPE_RC:
2056                 opcode = CQ_BASE_CQE_TYPE_RES_RC;
2057                 break;
2058         case CMDQ_CREATE_QP_TYPE_UD:
2059                 opcode = CQ_BASE_CQE_TYPE_RES_UD;
2060                 break;
2061         }
2062
2063         rc = __flush_rq(rq, qp, opcode, pcqe, budget);
2064         if (!rc)
2065                 rq->flush_in_progress = false;
2066 done:
2067         return rc;
2068 }
2069
2070 static int bnxt_qplib_cq_process_cutoff(struct bnxt_qplib_cq *cq,
2071                                         struct cq_cutoff *hwcqe)
2072 {
2073         /* Check the Status */
2074         if (hwcqe->status != CQ_CUTOFF_STATUS_OK) {
2075                 dev_err(&cq->hwq.pdev->dev,
2076                         "QPLIB: FP: CQ Process Cutoff Error status = 0x%x",
2077                         hwcqe->status);
2078                 return -EINVAL;
2079         }
2080         clear_bit(CQ_FLAGS_RESIZE_IN_PROG, &cq->flags);
2081         wake_up_interruptible(&cq->waitq);
2082
2083         return 0;
2084 }
2085
2086 int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
2087                        int num_cqes, struct bnxt_qplib_qp **lib_qp)
2088 {
2089         struct cq_base *hw_cqe, **hw_cqe_ptr;
2090         unsigned long flags;
2091         u32 sw_cons, raw_cons;
2092         int budget, rc = 0;
2093
2094         spin_lock_irqsave(&cq->hwq.lock, flags);
2095         raw_cons = cq->hwq.cons;
2096         budget = num_cqes;
2097
2098         while (budget) {
2099                 sw_cons = HWQ_CMP(raw_cons, &cq->hwq);
2100                 hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr;
2101                 hw_cqe = &hw_cqe_ptr[CQE_PG(sw_cons)][CQE_IDX(sw_cons)];
2102
2103                 /* Check for Valid bit */
2104                 if (!CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements))
2105                         break;
2106
2107                 /* From the device's respective CQE format to qplib_wc*/
2108                 switch (hw_cqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK) {
2109                 case CQ_BASE_CQE_TYPE_REQ:
2110                         rc = bnxt_qplib_cq_process_req(cq,
2111                                                        (struct cq_req *)hw_cqe,
2112                                                        &cqe, &budget,
2113                                                        sw_cons, lib_qp);
2114                         break;
2115                 case CQ_BASE_CQE_TYPE_RES_RC:
2116                         rc = bnxt_qplib_cq_process_res_rc(cq,
2117                                                           (struct cq_res_rc *)
2118                                                           hw_cqe, &cqe,
2119                                                           &budget);
2120                         break;
2121                 case CQ_BASE_CQE_TYPE_RES_UD:
2122                         rc = bnxt_qplib_cq_process_res_ud
2123                                         (cq, (struct cq_res_ud *)hw_cqe, &cqe,
2124                                          &budget);
2125                         break;
2126                 case CQ_BASE_CQE_TYPE_RES_RAWETH_QP1:
2127                         rc = bnxt_qplib_cq_process_res_raweth_qp1
2128                                         (cq, (struct cq_res_raweth_qp1 *)
2129                                          hw_cqe, &cqe, &budget);
2130                         break;
2131                 case CQ_BASE_CQE_TYPE_TERMINAL:
2132                         rc = bnxt_qplib_cq_process_terminal
2133                                         (cq, (struct cq_terminal *)hw_cqe,
2134                                          &cqe, &budget);
2135                         break;
2136                 case CQ_BASE_CQE_TYPE_CUT_OFF:
2137                         bnxt_qplib_cq_process_cutoff
2138                                         (cq, (struct cq_cutoff *)hw_cqe);
2139                         /* Done processing this CQ */
2140                         goto exit;
2141                 default:
2142                         dev_err(&cq->hwq.pdev->dev,
2143                                 "QPLIB: process_cq unknown type 0x%lx",
2144                                 hw_cqe->cqe_type_toggle &
2145                                 CQ_BASE_CQE_TYPE_MASK);
2146                         rc = -EINVAL;
2147                         break;
2148                 }
2149                 if (rc < 0) {
2150                         if (rc == -EAGAIN)
2151                                 break;
2152                         /* Error while processing the CQE, just skip to the
2153                          * next one
2154                          */
2155                         dev_err(&cq->hwq.pdev->dev,
2156                                 "QPLIB: process_cqe error rc = 0x%x", rc);
2157                 }
2158                 raw_cons++;
2159         }
2160         if (cq->hwq.cons != raw_cons) {
2161                 cq->hwq.cons = raw_cons;
2162                 bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ);
2163         }
2164 exit:
2165         spin_unlock_irqrestore(&cq->hwq.lock, flags);
2166         return num_cqes - budget;
2167 }
2168
2169 void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type)
2170 {
2171         unsigned long flags;
2172
2173         spin_lock_irqsave(&cq->hwq.lock, flags);
2174         if (arm_type)
2175                 bnxt_qplib_arm_cq(cq, arm_type);
2176
2177         spin_unlock_irqrestore(&cq->hwq.lock, flags);
2178 }