13f49d684SMustafa Ismail // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
23f49d684SMustafa Ismail /* Copyright (c) 2015 - 2021 Intel Corporation */
3b6459415SJakub Kicinski #include <linux/etherdevice.h>
4b6459415SJakub Kicinski
53f49d684SMustafa Ismail #include "osdep.h"
63f49d684SMustafa Ismail #include "hmc.h"
73f49d684SMustafa Ismail #include "defs.h"
83f49d684SMustafa Ismail #include "type.h"
93f49d684SMustafa Ismail #include "ws.h"
103f49d684SMustafa Ismail #include "protos.h"
113f49d684SMustafa Ismail
123f49d684SMustafa Ismail /**
133f49d684SMustafa Ismail * irdma_get_qp_from_list - get next qp from a list
143f49d684SMustafa Ismail * @head: Listhead of qp's
153f49d684SMustafa Ismail * @qp: current qp
163f49d684SMustafa Ismail */
irdma_get_qp_from_list(struct list_head * head,struct irdma_sc_qp * qp)173f49d684SMustafa Ismail struct irdma_sc_qp *irdma_get_qp_from_list(struct list_head *head,
183f49d684SMustafa Ismail struct irdma_sc_qp *qp)
193f49d684SMustafa Ismail {
203f49d684SMustafa Ismail struct list_head *lastentry;
213f49d684SMustafa Ismail struct list_head *entry = NULL;
223f49d684SMustafa Ismail
233f49d684SMustafa Ismail if (list_empty(head))
243f49d684SMustafa Ismail return NULL;
253f49d684SMustafa Ismail
263f49d684SMustafa Ismail if (!qp) {
273f49d684SMustafa Ismail entry = head->next;
283f49d684SMustafa Ismail } else {
293f49d684SMustafa Ismail lastentry = &qp->list;
303f49d684SMustafa Ismail entry = lastentry->next;
313f49d684SMustafa Ismail if (entry == head)
323f49d684SMustafa Ismail return NULL;
333f49d684SMustafa Ismail }
343f49d684SMustafa Ismail
353f49d684SMustafa Ismail return container_of(entry, struct irdma_sc_qp, list);
363f49d684SMustafa Ismail }
373f49d684SMustafa Ismail
383f49d684SMustafa Ismail /**
393f49d684SMustafa Ismail * irdma_sc_suspend_resume_qps - suspend/resume all qp's on VSI
403f49d684SMustafa Ismail * @vsi: the VSI struct pointer
413f49d684SMustafa Ismail * @op: Set to IRDMA_OP_RESUME or IRDMA_OP_SUSPEND
423f49d684SMustafa Ismail */
irdma_sc_suspend_resume_qps(struct irdma_sc_vsi * vsi,u8 op)433f49d684SMustafa Ismail void irdma_sc_suspend_resume_qps(struct irdma_sc_vsi *vsi, u8 op)
443f49d684SMustafa Ismail {
453f49d684SMustafa Ismail struct irdma_sc_qp *qp = NULL;
463f49d684SMustafa Ismail u8 i;
473f49d684SMustafa Ismail
483f49d684SMustafa Ismail for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
493f49d684SMustafa Ismail mutex_lock(&vsi->qos[i].qos_mutex);
503f49d684SMustafa Ismail qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp);
513f49d684SMustafa Ismail while (qp) {
523f49d684SMustafa Ismail if (op == IRDMA_OP_RESUME) {
533f49d684SMustafa Ismail if (!qp->dev->ws_add(vsi, i)) {
543f49d684SMustafa Ismail qp->qs_handle =
553f49d684SMustafa Ismail vsi->qos[qp->user_pri].qs_handle;
563f49d684SMustafa Ismail irdma_cqp_qp_suspend_resume(qp, op);
573f49d684SMustafa Ismail } else {
583f49d684SMustafa Ismail irdma_cqp_qp_suspend_resume(qp, op);
593f49d684SMustafa Ismail irdma_modify_qp_to_err(qp);
603f49d684SMustafa Ismail }
613f49d684SMustafa Ismail } else if (op == IRDMA_OP_SUSPEND) {
623f49d684SMustafa Ismail /* issue cqp suspend command */
633f49d684SMustafa Ismail if (!irdma_cqp_qp_suspend_resume(qp, op))
643f49d684SMustafa Ismail atomic_inc(&vsi->qp_suspend_reqs);
653f49d684SMustafa Ismail }
663f49d684SMustafa Ismail qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp);
673f49d684SMustafa Ismail }
683f49d684SMustafa Ismail mutex_unlock(&vsi->qos[i].qos_mutex);
693f49d684SMustafa Ismail }
703f49d684SMustafa Ismail }
713f49d684SMustafa Ismail
irdma_set_qos_info(struct irdma_sc_vsi * vsi,struct irdma_l2params * l2p)7283483055SMustafa Ismail static void irdma_set_qos_info(struct irdma_sc_vsi *vsi,
7383483055SMustafa Ismail struct irdma_l2params *l2p)
7483483055SMustafa Ismail {
7583483055SMustafa Ismail u8 i;
7683483055SMustafa Ismail
7783483055SMustafa Ismail vsi->qos_rel_bw = l2p->vsi_rel_bw;
7883483055SMustafa Ismail vsi->qos_prio_type = l2p->vsi_prio_type;
794b860c91SMustafa Ismail vsi->dscp_mode = l2p->dscp_mode;
804b860c91SMustafa Ismail if (l2p->dscp_mode) {
814b860c91SMustafa Ismail memcpy(vsi->dscp_map, l2p->dscp_map, sizeof(vsi->dscp_map));
824b860c91SMustafa Ismail for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++)
834b860c91SMustafa Ismail l2p->up2tc[i] = i;
844b860c91SMustafa Ismail }
8583483055SMustafa Ismail for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
8683483055SMustafa Ismail if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
8783483055SMustafa Ismail vsi->qos[i].qs_handle = l2p->qs_handle_list[i];
8883483055SMustafa Ismail vsi->qos[i].traffic_class = l2p->up2tc[i];
8983483055SMustafa Ismail vsi->qos[i].rel_bw =
9083483055SMustafa Ismail l2p->tc_info[vsi->qos[i].traffic_class].rel_bw;
9183483055SMustafa Ismail vsi->qos[i].prio_type =
9283483055SMustafa Ismail l2p->tc_info[vsi->qos[i].traffic_class].prio_type;
9383483055SMustafa Ismail vsi->qos[i].valid = false;
9483483055SMustafa Ismail }
9583483055SMustafa Ismail }
9683483055SMustafa Ismail
973f49d684SMustafa Ismail /**
983f49d684SMustafa Ismail * irdma_change_l2params - given the new l2 parameters, change all qp
993f49d684SMustafa Ismail * @vsi: RDMA VSI pointer
1003f49d684SMustafa Ismail * @l2params: New parameters from l2
1013f49d684SMustafa Ismail */
irdma_change_l2params(struct irdma_sc_vsi * vsi,struct irdma_l2params * l2params)1023f49d684SMustafa Ismail void irdma_change_l2params(struct irdma_sc_vsi *vsi,
1033f49d684SMustafa Ismail struct irdma_l2params *l2params)
1043f49d684SMustafa Ismail {
1053f49d684SMustafa Ismail if (l2params->mtu_changed) {
1063f49d684SMustafa Ismail vsi->mtu = l2params->mtu;
1073f49d684SMustafa Ismail if (vsi->ieq)
1083f49d684SMustafa Ismail irdma_reinitialize_ieq(vsi);
1093f49d684SMustafa Ismail }
1103f49d684SMustafa Ismail
1113f49d684SMustafa Ismail if (!l2params->tc_changed)
1123f49d684SMustafa Ismail return;
1133f49d684SMustafa Ismail
1143f49d684SMustafa Ismail vsi->tc_change_pending = false;
11583483055SMustafa Ismail irdma_set_qos_info(vsi, l2params);
1163f49d684SMustafa Ismail irdma_sc_suspend_resume_qps(vsi, IRDMA_OP_RESUME);
1173f49d684SMustafa Ismail }
1183f49d684SMustafa Ismail
1193f49d684SMustafa Ismail /**
1203f49d684SMustafa Ismail * irdma_qp_rem_qos - remove qp from qos lists during destroy qp
1213f49d684SMustafa Ismail * @qp: qp to be removed from qos
1223f49d684SMustafa Ismail */
irdma_qp_rem_qos(struct irdma_sc_qp * qp)1233f49d684SMustafa Ismail void irdma_qp_rem_qos(struct irdma_sc_qp *qp)
1243f49d684SMustafa Ismail {
1253f49d684SMustafa Ismail struct irdma_sc_vsi *vsi = qp->vsi;
1263f49d684SMustafa Ismail
1273f49d684SMustafa Ismail ibdev_dbg(to_ibdev(qp->dev),
1283f49d684SMustafa Ismail "DCB: DCB: Remove qp[%d] UP[%d] qset[%d] on_qoslist[%d]\n",
1293f49d684SMustafa Ismail qp->qp_uk.qp_id, qp->user_pri, qp->qs_handle,
1303f49d684SMustafa Ismail qp->on_qoslist);
1313f49d684SMustafa Ismail mutex_lock(&vsi->qos[qp->user_pri].qos_mutex);
1323f49d684SMustafa Ismail if (qp->on_qoslist) {
1333f49d684SMustafa Ismail qp->on_qoslist = false;
1343f49d684SMustafa Ismail list_del(&qp->list);
1353f49d684SMustafa Ismail }
1363f49d684SMustafa Ismail mutex_unlock(&vsi->qos[qp->user_pri].qos_mutex);
1373f49d684SMustafa Ismail }
1383f49d684SMustafa Ismail
1393f49d684SMustafa Ismail /**
1403f49d684SMustafa Ismail * irdma_qp_add_qos - called during setctx for qp to be added to qos
1413f49d684SMustafa Ismail * @qp: qp to be added to qos
1423f49d684SMustafa Ismail */
irdma_qp_add_qos(struct irdma_sc_qp * qp)1433f49d684SMustafa Ismail void irdma_qp_add_qos(struct irdma_sc_qp *qp)
1443f49d684SMustafa Ismail {
1453f49d684SMustafa Ismail struct irdma_sc_vsi *vsi = qp->vsi;
1463f49d684SMustafa Ismail
1473f49d684SMustafa Ismail ibdev_dbg(to_ibdev(qp->dev),
1483f49d684SMustafa Ismail "DCB: DCB: Add qp[%d] UP[%d] qset[%d] on_qoslist[%d]\n",
1493f49d684SMustafa Ismail qp->qp_uk.qp_id, qp->user_pri, qp->qs_handle,
1503f49d684SMustafa Ismail qp->on_qoslist);
1513f49d684SMustafa Ismail mutex_lock(&vsi->qos[qp->user_pri].qos_mutex);
1523f49d684SMustafa Ismail if (!qp->on_qoslist) {
1533f49d684SMustafa Ismail list_add(&qp->list, &vsi->qos[qp->user_pri].qplist);
1543f49d684SMustafa Ismail qp->on_qoslist = true;
1553f49d684SMustafa Ismail qp->qs_handle = vsi->qos[qp->user_pri].qs_handle;
1563f49d684SMustafa Ismail }
1573f49d684SMustafa Ismail mutex_unlock(&vsi->qos[qp->user_pri].qos_mutex);
1583f49d684SMustafa Ismail }
1593f49d684SMustafa Ismail
1603f49d684SMustafa Ismail /**
1613f49d684SMustafa Ismail * irdma_sc_pd_init - initialize sc pd struct
1623f49d684SMustafa Ismail * @dev: sc device struct
1633f49d684SMustafa Ismail * @pd: sc pd ptr
1643f49d684SMustafa Ismail * @pd_id: pd_id for allocated pd
1653f49d684SMustafa Ismail * @abi_ver: User/Kernel ABI version
1663f49d684SMustafa Ismail */
irdma_sc_pd_init(struct irdma_sc_dev * dev,struct irdma_sc_pd * pd,u32 pd_id,int abi_ver)1673f49d684SMustafa Ismail void irdma_sc_pd_init(struct irdma_sc_dev *dev, struct irdma_sc_pd *pd, u32 pd_id,
1683f49d684SMustafa Ismail int abi_ver)
1693f49d684SMustafa Ismail {
1703f49d684SMustafa Ismail pd->pd_id = pd_id;
1713f49d684SMustafa Ismail pd->abi_ver = abi_ver;
1723f49d684SMustafa Ismail pd->dev = dev;
1733f49d684SMustafa Ismail }
1743f49d684SMustafa Ismail
1753f49d684SMustafa Ismail /**
1763f49d684SMustafa Ismail * irdma_sc_add_arp_cache_entry - cqp wqe add arp cache entry
1773f49d684SMustafa Ismail * @cqp: struct for cqp hw
1783f49d684SMustafa Ismail * @info: arp entry information
1793f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
1803f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
1813f49d684SMustafa Ismail */
irdma_sc_add_arp_cache_entry(struct irdma_sc_cqp * cqp,struct irdma_add_arp_cache_entry_info * info,u64 scratch,bool post_sq)1822c4b14eaSShiraz Saleem static int irdma_sc_add_arp_cache_entry(struct irdma_sc_cqp *cqp,
1833f49d684SMustafa Ismail struct irdma_add_arp_cache_entry_info *info,
1843f49d684SMustafa Ismail u64 scratch, bool post_sq)
1853f49d684SMustafa Ismail {
1863f49d684SMustafa Ismail __le64 *wqe;
1873f49d684SMustafa Ismail u64 hdr;
1883f49d684SMustafa Ismail
1893f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
1903f49d684SMustafa Ismail if (!wqe)
1912c4b14eaSShiraz Saleem return -ENOMEM;
1923f49d684SMustafa Ismail set_64bit_val(wqe, 8, info->reach_max);
1933f49d684SMustafa Ismail set_64bit_val(wqe, 16, ether_addr_to_u64(info->mac_addr));
1943f49d684SMustafa Ismail
1953f49d684SMustafa Ismail hdr = info->arp_index |
1963f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MANAGE_ARP) |
1973f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_MAT_PERMANENT, (info->permanent ? 1 : 0)) |
1983f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_MAT_ENTRYVALID, 1) |
1993f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
2003f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
2013f49d684SMustafa Ismail
2023f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
2033f49d684SMustafa Ismail
2043f49d684SMustafa Ismail print_hex_dump_debug("WQE: ARP_CACHE_ENTRY WQE", DUMP_PREFIX_OFFSET,
2053f49d684SMustafa Ismail 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
2063f49d684SMustafa Ismail if (post_sq)
2073f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
2083f49d684SMustafa Ismail
2093f49d684SMustafa Ismail return 0;
2103f49d684SMustafa Ismail }
2113f49d684SMustafa Ismail
2123f49d684SMustafa Ismail /**
2133f49d684SMustafa Ismail * irdma_sc_del_arp_cache_entry - dele arp cache entry
2143f49d684SMustafa Ismail * @cqp: struct for cqp hw
2153f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
2163f49d684SMustafa Ismail * @arp_index: arp index to delete arp entry
2173f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
2183f49d684SMustafa Ismail */
irdma_sc_del_arp_cache_entry(struct irdma_sc_cqp * cqp,u64 scratch,u16 arp_index,bool post_sq)2192c4b14eaSShiraz Saleem static int irdma_sc_del_arp_cache_entry(struct irdma_sc_cqp *cqp, u64 scratch,
2203f49d684SMustafa Ismail u16 arp_index, bool post_sq)
2213f49d684SMustafa Ismail {
2223f49d684SMustafa Ismail __le64 *wqe;
2233f49d684SMustafa Ismail u64 hdr;
2243f49d684SMustafa Ismail
2253f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2263f49d684SMustafa Ismail if (!wqe)
2272c4b14eaSShiraz Saleem return -ENOMEM;
2283f49d684SMustafa Ismail
2293f49d684SMustafa Ismail hdr = arp_index |
2303f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MANAGE_ARP) |
2313f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
2323f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
2333f49d684SMustafa Ismail
2343f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
2353f49d684SMustafa Ismail
2363f49d684SMustafa Ismail print_hex_dump_debug("WQE: ARP_CACHE_DEL_ENTRY WQE",
2373f49d684SMustafa Ismail DUMP_PREFIX_OFFSET, 16, 8, wqe,
2383f49d684SMustafa Ismail IRDMA_CQP_WQE_SIZE * 8, false);
2393f49d684SMustafa Ismail if (post_sq)
2403f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
2413f49d684SMustafa Ismail
2423f49d684SMustafa Ismail return 0;
2433f49d684SMustafa Ismail }
2443f49d684SMustafa Ismail
2453f49d684SMustafa Ismail /**
2463f49d684SMustafa Ismail * irdma_sc_manage_apbvt_entry - for adding and deleting apbvt entries
2473f49d684SMustafa Ismail * @cqp: struct for cqp hw
2483f49d684SMustafa Ismail * @info: info for apbvt entry to add or delete
2493f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
2503f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
2513f49d684SMustafa Ismail */
irdma_sc_manage_apbvt_entry(struct irdma_sc_cqp * cqp,struct irdma_apbvt_info * info,u64 scratch,bool post_sq)2522c4b14eaSShiraz Saleem static int irdma_sc_manage_apbvt_entry(struct irdma_sc_cqp *cqp,
2532c4b14eaSShiraz Saleem struct irdma_apbvt_info *info,
2542c4b14eaSShiraz Saleem u64 scratch, bool post_sq)
2553f49d684SMustafa Ismail {
2563f49d684SMustafa Ismail __le64 *wqe;
2573f49d684SMustafa Ismail u64 hdr;
2583f49d684SMustafa Ismail
2593f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2603f49d684SMustafa Ismail if (!wqe)
2612c4b14eaSShiraz Saleem return -ENOMEM;
2623f49d684SMustafa Ismail
2633f49d684SMustafa Ismail set_64bit_val(wqe, 16, info->port);
2643f49d684SMustafa Ismail
2653f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MANAGE_APBVT) |
2663f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_MAPT_ADDPORT, info->add) |
2673f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
2683f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
2693f49d684SMustafa Ismail
2703f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
2713f49d684SMustafa Ismail
2723f49d684SMustafa Ismail print_hex_dump_debug("WQE: MANAGE_APBVT WQE", DUMP_PREFIX_OFFSET, 16,
2733f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
2743f49d684SMustafa Ismail if (post_sq)
2753f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
2763f49d684SMustafa Ismail
2773f49d684SMustafa Ismail return 0;
2783f49d684SMustafa Ismail }
2793f49d684SMustafa Ismail
2803f49d684SMustafa Ismail /**
2813f49d684SMustafa Ismail * irdma_sc_manage_qhash_table_entry - manage quad hash entries
2823f49d684SMustafa Ismail * @cqp: struct for cqp hw
2833f49d684SMustafa Ismail * @info: info for quad hash to manage
2843f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
2853f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
2863f49d684SMustafa Ismail *
2873f49d684SMustafa Ismail * This is called before connection establishment is started.
2883f49d684SMustafa Ismail * For passive connections, when listener is created, it will
2893f49d684SMustafa Ismail * call with entry type of IRDMA_QHASH_TYPE_TCP_SYN with local
2903f49d684SMustafa Ismail * ip address and tcp port. When SYN is received (passive
2913f49d684SMustafa Ismail * connections) or sent (active connections), this routine is
2923f49d684SMustafa Ismail * called with entry type of IRDMA_QHASH_TYPE_TCP_ESTABLISHED
2933f49d684SMustafa Ismail * and quad is passed in info.
2943f49d684SMustafa Ismail *
2953f49d684SMustafa Ismail * When iwarp connection is done and its state moves to RTS, the
2963f49d684SMustafa Ismail * quad hash entry in the hardware will point to iwarp's qp
2973f49d684SMustafa Ismail * number and requires no calls from the driver.
2983f49d684SMustafa Ismail */
2992c4b14eaSShiraz Saleem static int
irdma_sc_manage_qhash_table_entry(struct irdma_sc_cqp * cqp,struct irdma_qhash_table_info * info,u64 scratch,bool post_sq)3003f49d684SMustafa Ismail irdma_sc_manage_qhash_table_entry(struct irdma_sc_cqp *cqp,
3013f49d684SMustafa Ismail struct irdma_qhash_table_info *info,
3023f49d684SMustafa Ismail u64 scratch, bool post_sq)
3033f49d684SMustafa Ismail {
3043f49d684SMustafa Ismail __le64 *wqe;
3053f49d684SMustafa Ismail u64 qw1 = 0;
3063f49d684SMustafa Ismail u64 qw2 = 0;
3073f49d684SMustafa Ismail u64 temp;
3083f49d684SMustafa Ismail struct irdma_sc_vsi *vsi = info->vsi;
3093f49d684SMustafa Ismail
3103f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
3113f49d684SMustafa Ismail if (!wqe)
3122c4b14eaSShiraz Saleem return -ENOMEM;
3133f49d684SMustafa Ismail
3143f49d684SMustafa Ismail set_64bit_val(wqe, 0, ether_addr_to_u64(info->mac_addr));
3153f49d684SMustafa Ismail
3163f49d684SMustafa Ismail qw1 = FIELD_PREP(IRDMA_CQPSQ_QHASH_QPN, info->qp_num) |
3173f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_DEST_PORT, info->dest_port);
3183f49d684SMustafa Ismail if (info->ipv4_valid) {
3193f49d684SMustafa Ismail set_64bit_val(wqe, 48,
3203f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR3, info->dest_ip[0]));
3213f49d684SMustafa Ismail } else {
3223f49d684SMustafa Ismail set_64bit_val(wqe, 56,
3233f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR0, info->dest_ip[0]) |
3243f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR1, info->dest_ip[1]));
3253f49d684SMustafa Ismail
3263f49d684SMustafa Ismail set_64bit_val(wqe, 48,
3273f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR2, info->dest_ip[2]) |
3283f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR3, info->dest_ip[3]));
3293f49d684SMustafa Ismail }
3303f49d684SMustafa Ismail qw2 = FIELD_PREP(IRDMA_CQPSQ_QHASH_QS_HANDLE,
3313f49d684SMustafa Ismail vsi->qos[info->user_pri].qs_handle);
3323f49d684SMustafa Ismail if (info->vlan_valid)
3333f49d684SMustafa Ismail qw2 |= FIELD_PREP(IRDMA_CQPSQ_QHASH_VLANID, info->vlan_id);
3343f49d684SMustafa Ismail set_64bit_val(wqe, 16, qw2);
3353f49d684SMustafa Ismail if (info->entry_type == IRDMA_QHASH_TYPE_TCP_ESTABLISHED) {
3363f49d684SMustafa Ismail qw1 |= FIELD_PREP(IRDMA_CQPSQ_QHASH_SRC_PORT, info->src_port);
3373f49d684SMustafa Ismail if (!info->ipv4_valid) {
3383f49d684SMustafa Ismail set_64bit_val(wqe, 40,
3393f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR0, info->src_ip[0]) |
3403f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR1, info->src_ip[1]));
3413f49d684SMustafa Ismail set_64bit_val(wqe, 32,
3423f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR2, info->src_ip[2]) |
3433f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR3, info->src_ip[3]));
3443f49d684SMustafa Ismail } else {
3453f49d684SMustafa Ismail set_64bit_val(wqe, 32,
3463f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR3, info->src_ip[0]));
3473f49d684SMustafa Ismail }
3483f49d684SMustafa Ismail }
3493f49d684SMustafa Ismail
3503f49d684SMustafa Ismail set_64bit_val(wqe, 8, qw1);
3513f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPSQ_QHASH_WQEVALID, cqp->polarity) |
3523f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_OPCODE,
3533f49d684SMustafa Ismail IRDMA_CQP_OP_MANAGE_QUAD_HASH_TABLE_ENTRY) |
3543f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_MANAGE, info->manage) |
3553f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_IPV4VALID, info->ipv4_valid) |
3563f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_VLANVALID, info->vlan_valid) |
3573f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QHASH_ENTRYTYPE, info->entry_type);
3583f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
3593f49d684SMustafa Ismail
3603f49d684SMustafa Ismail set_64bit_val(wqe, 24, temp);
3613f49d684SMustafa Ismail
3623f49d684SMustafa Ismail print_hex_dump_debug("WQE: MANAGE_QHASH WQE", DUMP_PREFIX_OFFSET, 16,
3633f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
3643f49d684SMustafa Ismail if (post_sq)
3653f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
3663f49d684SMustafa Ismail
3673f49d684SMustafa Ismail return 0;
3683f49d684SMustafa Ismail }
3693f49d684SMustafa Ismail
3703f49d684SMustafa Ismail /**
3713f49d684SMustafa Ismail * irdma_sc_qp_init - initialize qp
3723f49d684SMustafa Ismail * @qp: sc qp
3733f49d684SMustafa Ismail * @info: initialization qp info
3743f49d684SMustafa Ismail */
irdma_sc_qp_init(struct irdma_sc_qp * qp,struct irdma_qp_init_info * info)3752c4b14eaSShiraz Saleem int irdma_sc_qp_init(struct irdma_sc_qp *qp, struct irdma_qp_init_info *info)
3763f49d684SMustafa Ismail {
3772c4b14eaSShiraz Saleem int ret_code;
3783f49d684SMustafa Ismail u32 pble_obj_cnt;
3793f49d684SMustafa Ismail u16 wqe_size;
3803f49d684SMustafa Ismail
3813f49d684SMustafa Ismail if (info->qp_uk_init_info.max_sq_frag_cnt >
3823f49d684SMustafa Ismail info->pd->dev->hw_attrs.uk_attrs.max_hw_wq_frags ||
3833f49d684SMustafa Ismail info->qp_uk_init_info.max_rq_frag_cnt >
3843f49d684SMustafa Ismail info->pd->dev->hw_attrs.uk_attrs.max_hw_wq_frags)
3852c4b14eaSShiraz Saleem return -EINVAL;
3863f49d684SMustafa Ismail
3873f49d684SMustafa Ismail qp->dev = info->pd->dev;
3883f49d684SMustafa Ismail qp->vsi = info->vsi;
3893f49d684SMustafa Ismail qp->ieq_qp = info->vsi->exception_lan_q;
3903f49d684SMustafa Ismail qp->sq_pa = info->sq_pa;
3913f49d684SMustafa Ismail qp->rq_pa = info->rq_pa;
3923f49d684SMustafa Ismail qp->hw_host_ctx_pa = info->host_ctx_pa;
3933f49d684SMustafa Ismail qp->q2_pa = info->q2_pa;
3943f49d684SMustafa Ismail qp->shadow_area_pa = info->shadow_area_pa;
3953f49d684SMustafa Ismail qp->q2_buf = info->q2;
3963f49d684SMustafa Ismail qp->pd = info->pd;
3973f49d684SMustafa Ismail qp->hw_host_ctx = info->host_ctx;
3983f49d684SMustafa Ismail info->qp_uk_init_info.wqe_alloc_db = qp->pd->dev->wqe_alloc_db;
3993f49d684SMustafa Ismail ret_code = irdma_uk_qp_init(&qp->qp_uk, &info->qp_uk_init_info);
4003f49d684SMustafa Ismail if (ret_code)
4013f49d684SMustafa Ismail return ret_code;
4023f49d684SMustafa Ismail
4033f49d684SMustafa Ismail qp->virtual_map = info->virtual_map;
4043f49d684SMustafa Ismail pble_obj_cnt = info->pd->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
4053f49d684SMustafa Ismail
4063f49d684SMustafa Ismail if ((info->virtual_map && info->sq_pa >= pble_obj_cnt) ||
4073f49d684SMustafa Ismail (info->virtual_map && info->rq_pa >= pble_obj_cnt))
4082c4b14eaSShiraz Saleem return -EINVAL;
4093f49d684SMustafa Ismail
4103f49d684SMustafa Ismail qp->llp_stream_handle = (void *)(-1);
4113f49d684SMustafa Ismail qp->hw_sq_size = irdma_get_encoded_wqe_size(qp->qp_uk.sq_ring.size,
4123f49d684SMustafa Ismail IRDMA_QUEUE_TYPE_SQ_RQ);
4133f49d684SMustafa Ismail ibdev_dbg(to_ibdev(qp->dev),
4143f49d684SMustafa Ismail "WQE: hw_sq_size[%04d] sq_ring.size[%04d]\n",
4153f49d684SMustafa Ismail qp->hw_sq_size, qp->qp_uk.sq_ring.size);
4163f49d684SMustafa Ismail if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1 && qp->pd->abi_ver > 4)
4173f49d684SMustafa Ismail wqe_size = IRDMA_WQE_SIZE_128;
4183f49d684SMustafa Ismail else
4193f49d684SMustafa Ismail ret_code = irdma_fragcnt_to_wqesize_rq(qp->qp_uk.max_rq_frag_cnt,
4203f49d684SMustafa Ismail &wqe_size);
4213f49d684SMustafa Ismail if (ret_code)
4223f49d684SMustafa Ismail return ret_code;
4233f49d684SMustafa Ismail
4243f49d684SMustafa Ismail qp->hw_rq_size = irdma_get_encoded_wqe_size(qp->qp_uk.rq_size *
4253f49d684SMustafa Ismail (wqe_size / IRDMA_QP_WQE_MIN_SIZE), IRDMA_QUEUE_TYPE_SQ_RQ);
4263f49d684SMustafa Ismail ibdev_dbg(to_ibdev(qp->dev),
4273f49d684SMustafa Ismail "WQE: hw_rq_size[%04d] qp_uk.rq_size[%04d] wqe_size[%04d]\n",
4283f49d684SMustafa Ismail qp->hw_rq_size, qp->qp_uk.rq_size, wqe_size);
4293f49d684SMustafa Ismail qp->sq_tph_val = info->sq_tph_val;
4303f49d684SMustafa Ismail qp->rq_tph_val = info->rq_tph_val;
4313f49d684SMustafa Ismail qp->sq_tph_en = info->sq_tph_en;
4323f49d684SMustafa Ismail qp->rq_tph_en = info->rq_tph_en;
4333f49d684SMustafa Ismail qp->rcv_tph_en = info->rcv_tph_en;
4343f49d684SMustafa Ismail qp->xmit_tph_en = info->xmit_tph_en;
4353f49d684SMustafa Ismail qp->qp_uk.first_sq_wq = info->qp_uk_init_info.first_sq_wq;
4363f49d684SMustafa Ismail qp->qs_handle = qp->vsi->qos[qp->user_pri].qs_handle;
4373f49d684SMustafa Ismail
4383f49d684SMustafa Ismail return 0;
4393f49d684SMustafa Ismail }
4403f49d684SMustafa Ismail
4413f49d684SMustafa Ismail /**
4423f49d684SMustafa Ismail * irdma_sc_qp_create - create qp
4433f49d684SMustafa Ismail * @qp: sc qp
4443f49d684SMustafa Ismail * @info: qp create info
4453f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
4463f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
4473f49d684SMustafa Ismail */
irdma_sc_qp_create(struct irdma_sc_qp * qp,struct irdma_create_qp_info * info,u64 scratch,bool post_sq)4482c4b14eaSShiraz Saleem int irdma_sc_qp_create(struct irdma_sc_qp *qp, struct irdma_create_qp_info *info,
4493f49d684SMustafa Ismail u64 scratch, bool post_sq)
4503f49d684SMustafa Ismail {
4513f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
4523f49d684SMustafa Ismail __le64 *wqe;
4533f49d684SMustafa Ismail u64 hdr;
4543f49d684SMustafa Ismail
4553f49d684SMustafa Ismail cqp = qp->dev->cqp;
4563f49d684SMustafa Ismail if (qp->qp_uk.qp_id < cqp->dev->hw_attrs.min_hw_qp_id ||
4576f6dbb81SDan Carpenter qp->qp_uk.qp_id >= cqp->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt)
4582c4b14eaSShiraz Saleem return -EINVAL;
4593f49d684SMustafa Ismail
4603f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
4613f49d684SMustafa Ismail if (!wqe)
4622c4b14eaSShiraz Saleem return -ENOMEM;
4633f49d684SMustafa Ismail
4643f49d684SMustafa Ismail set_64bit_val(wqe, 16, qp->hw_host_ctx_pa);
4653f49d684SMustafa Ismail set_64bit_val(wqe, 40, qp->shadow_area_pa);
4663f49d684SMustafa Ismail
4673f49d684SMustafa Ismail hdr = qp->qp_uk.qp_id |
4683f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_QP) |
4693f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_ORDVALID, (info->ord_valid ? 1 : 0)) |
4703f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_TOECTXVALID, info->tcp_ctx_valid) |
4713f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_MACVALID, info->mac_valid) |
4723f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_QPTYPE, qp->qp_uk.qp_type) |
4733f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_VQ, qp->virtual_map) |
4743f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_FORCELOOPBACK, info->force_lpb) |
4753f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_CQNUMVALID, info->cq_num_valid) |
4763f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_ARPTABIDXVALID,
4773f49d684SMustafa Ismail info->arp_cache_idx_valid) |
4783f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_NEXTIWSTATE, info->next_iwarp_state) |
4793f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
4803f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
4813f49d684SMustafa Ismail
4823f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
4833f49d684SMustafa Ismail
4843f49d684SMustafa Ismail print_hex_dump_debug("WQE: QP_CREATE WQE", DUMP_PREFIX_OFFSET, 16, 8,
4853f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
4863f49d684SMustafa Ismail if (post_sq)
4873f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
4883f49d684SMustafa Ismail
4893f49d684SMustafa Ismail return 0;
4903f49d684SMustafa Ismail }
4913f49d684SMustafa Ismail
4923f49d684SMustafa Ismail /**
4933f49d684SMustafa Ismail * irdma_sc_qp_modify - modify qp cqp wqe
4943f49d684SMustafa Ismail * @qp: sc qp
4953f49d684SMustafa Ismail * @info: modify qp info
4963f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
4973f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
4983f49d684SMustafa Ismail */
irdma_sc_qp_modify(struct irdma_sc_qp * qp,struct irdma_modify_qp_info * info,u64 scratch,bool post_sq)4992c4b14eaSShiraz Saleem int irdma_sc_qp_modify(struct irdma_sc_qp *qp, struct irdma_modify_qp_info *info,
5003f49d684SMustafa Ismail u64 scratch, bool post_sq)
5013f49d684SMustafa Ismail {
5023f49d684SMustafa Ismail __le64 *wqe;
5033f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
5043f49d684SMustafa Ismail u64 hdr;
5053f49d684SMustafa Ismail u8 term_actions = 0;
5063f49d684SMustafa Ismail u8 term_len = 0;
5073f49d684SMustafa Ismail
5083f49d684SMustafa Ismail cqp = qp->dev->cqp;
5093f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
5103f49d684SMustafa Ismail if (!wqe)
5112c4b14eaSShiraz Saleem return -ENOMEM;
5123f49d684SMustafa Ismail
5133f49d684SMustafa Ismail if (info->next_iwarp_state == IRDMA_QP_STATE_TERMINATE) {
5143f49d684SMustafa Ismail if (info->dont_send_fin)
5153f49d684SMustafa Ismail term_actions += IRDMAQP_TERM_SEND_TERM_ONLY;
5163f49d684SMustafa Ismail if (info->dont_send_term)
5173f49d684SMustafa Ismail term_actions += IRDMAQP_TERM_SEND_FIN_ONLY;
5183f49d684SMustafa Ismail if (term_actions == IRDMAQP_TERM_SEND_TERM_AND_FIN ||
5193f49d684SMustafa Ismail term_actions == IRDMAQP_TERM_SEND_TERM_ONLY)
5203f49d684SMustafa Ismail term_len = info->termlen;
5213f49d684SMustafa Ismail }
5223f49d684SMustafa Ismail
5233f49d684SMustafa Ismail set_64bit_val(wqe, 8,
5243f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_NEWMSS, info->new_mss) |
5253f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_TERMLEN, term_len));
5263f49d684SMustafa Ismail set_64bit_val(wqe, 16, qp->hw_host_ctx_pa);
5273f49d684SMustafa Ismail set_64bit_val(wqe, 40, qp->shadow_area_pa);
5283f49d684SMustafa Ismail
5293f49d684SMustafa Ismail hdr = qp->qp_uk.qp_id |
5303f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MODIFY_QP) |
5313f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_ORDVALID, info->ord_valid) |
5323f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_TOECTXVALID, info->tcp_ctx_valid) |
5333f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_CACHEDVARVALID,
5343f49d684SMustafa Ismail info->cached_var_valid) |
5353f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_VQ, qp->virtual_map) |
5363f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_FORCELOOPBACK, info->force_lpb) |
5373f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_CQNUMVALID, info->cq_num_valid) |
5383f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_MACVALID, info->mac_valid) |
5393f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_QPTYPE, qp->qp_uk.qp_type) |
5403f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_MSSCHANGE, info->mss_change) |
5413f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_REMOVEHASHENTRY,
5423f49d684SMustafa Ismail info->remove_hash_idx) |
5433f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_TERMACT, term_actions) |
5443f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_RESETCON, info->reset_tcp_conn) |
5453f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_ARPTABIDXVALID,
5463f49d684SMustafa Ismail info->arp_cache_idx_valid) |
5473f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_NEXTIWSTATE, info->next_iwarp_state) |
5483f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
5493f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
5503f49d684SMustafa Ismail
5513f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
5523f49d684SMustafa Ismail
5533f49d684SMustafa Ismail print_hex_dump_debug("WQE: QP_MODIFY WQE", DUMP_PREFIX_OFFSET, 16, 8,
5543f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
5553f49d684SMustafa Ismail if (post_sq)
5563f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
5573f49d684SMustafa Ismail
5583f49d684SMustafa Ismail return 0;
5593f49d684SMustafa Ismail }
5603f49d684SMustafa Ismail
5613f49d684SMustafa Ismail /**
5623f49d684SMustafa Ismail * irdma_sc_qp_destroy - cqp destroy qp
5633f49d684SMustafa Ismail * @qp: sc qp
5643f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
5653f49d684SMustafa Ismail * @remove_hash_idx: flag if to remove hash idx
5663f49d684SMustafa Ismail * @ignore_mw_bnd: memory window bind flag
5673f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
5683f49d684SMustafa Ismail */
irdma_sc_qp_destroy(struct irdma_sc_qp * qp,u64 scratch,bool remove_hash_idx,bool ignore_mw_bnd,bool post_sq)5692c4b14eaSShiraz Saleem int irdma_sc_qp_destroy(struct irdma_sc_qp *qp, u64 scratch,
5702c4b14eaSShiraz Saleem bool remove_hash_idx, bool ignore_mw_bnd, bool post_sq)
5713f49d684SMustafa Ismail {
5723f49d684SMustafa Ismail __le64 *wqe;
5733f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
5743f49d684SMustafa Ismail u64 hdr;
5753f49d684SMustafa Ismail
5763f49d684SMustafa Ismail cqp = qp->dev->cqp;
5773f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
5783f49d684SMustafa Ismail if (!wqe)
5792c4b14eaSShiraz Saleem return -ENOMEM;
5803f49d684SMustafa Ismail
5813f49d684SMustafa Ismail set_64bit_val(wqe, 16, qp->hw_host_ctx_pa);
5823f49d684SMustafa Ismail set_64bit_val(wqe, 40, qp->shadow_area_pa);
5833f49d684SMustafa Ismail
5843f49d684SMustafa Ismail hdr = qp->qp_uk.qp_id |
5853f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_QP) |
5863f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_QPTYPE, qp->qp_uk.qp_type) |
5873f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_IGNOREMWBOUND, ignore_mw_bnd) |
5883f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QP_REMOVEHASHENTRY, remove_hash_idx) |
5893f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
5903f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
5913f49d684SMustafa Ismail
5923f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
5933f49d684SMustafa Ismail
5943f49d684SMustafa Ismail print_hex_dump_debug("WQE: QP_DESTROY WQE", DUMP_PREFIX_OFFSET, 16, 8,
5953f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
5963f49d684SMustafa Ismail if (post_sq)
5973f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
5983f49d684SMustafa Ismail
5993f49d684SMustafa Ismail return 0;
6003f49d684SMustafa Ismail }
6013f49d684SMustafa Ismail
6023f49d684SMustafa Ismail /**
6033f49d684SMustafa Ismail * irdma_sc_get_encoded_ird_size -
6043f49d684SMustafa Ismail * @ird_size: IRD size
6053f49d684SMustafa Ismail * The ird from the connection is rounded to a supported HW setting and then encoded
6063f49d684SMustafa Ismail * for ird_size field of qp_ctx. Consumers are expected to provide valid ird size based
6073f49d684SMustafa Ismail * on hardware attributes. IRD size defaults to a value of 4 in case of invalid input
6083f49d684SMustafa Ismail */
irdma_sc_get_encoded_ird_size(u16 ird_size)6093f49d684SMustafa Ismail static u8 irdma_sc_get_encoded_ird_size(u16 ird_size)
6103f49d684SMustafa Ismail {
6113f49d684SMustafa Ismail switch (ird_size ?
6123f49d684SMustafa Ismail roundup_pow_of_two(2 * ird_size) : 4) {
6133f49d684SMustafa Ismail case 256:
6143f49d684SMustafa Ismail return IRDMA_IRD_HW_SIZE_256;
6153f49d684SMustafa Ismail case 128:
6163f49d684SMustafa Ismail return IRDMA_IRD_HW_SIZE_128;
6173f49d684SMustafa Ismail case 64:
6183f49d684SMustafa Ismail case 32:
6193f49d684SMustafa Ismail return IRDMA_IRD_HW_SIZE_64;
6203f49d684SMustafa Ismail case 16:
6213f49d684SMustafa Ismail case 8:
6223f49d684SMustafa Ismail return IRDMA_IRD_HW_SIZE_16;
6233f49d684SMustafa Ismail case 4:
6243f49d684SMustafa Ismail default:
6253f49d684SMustafa Ismail break;
6263f49d684SMustafa Ismail }
6273f49d684SMustafa Ismail
6283f49d684SMustafa Ismail return IRDMA_IRD_HW_SIZE_4;
6293f49d684SMustafa Ismail }
6303f49d684SMustafa Ismail
6313f49d684SMustafa Ismail /**
6323f49d684SMustafa Ismail * irdma_sc_qp_setctx_roce - set qp's context
6333f49d684SMustafa Ismail * @qp: sc qp
6343f49d684SMustafa Ismail * @qp_ctx: context ptr
6353f49d684SMustafa Ismail * @info: ctx info
6363f49d684SMustafa Ismail */
irdma_sc_qp_setctx_roce(struct irdma_sc_qp * qp,__le64 * qp_ctx,struct irdma_qp_host_ctx_info * info)6373f49d684SMustafa Ismail void irdma_sc_qp_setctx_roce(struct irdma_sc_qp *qp, __le64 *qp_ctx,
6383f49d684SMustafa Ismail struct irdma_qp_host_ctx_info *info)
6393f49d684SMustafa Ismail {
6403f49d684SMustafa Ismail struct irdma_roce_offload_info *roce_info;
6413f49d684SMustafa Ismail struct irdma_udp_offload_info *udp;
6423f49d684SMustafa Ismail u8 push_mode_en;
6433f49d684SMustafa Ismail u32 push_idx;
6443f49d684SMustafa Ismail
6453f49d684SMustafa Ismail roce_info = info->roce_info;
6463f49d684SMustafa Ismail udp = info->udp_info;
6473f49d684SMustafa Ismail qp->user_pri = info->user_pri;
6483f49d684SMustafa Ismail if (qp->push_idx == IRDMA_INVALID_PUSH_PAGE_INDEX) {
6493f49d684SMustafa Ismail push_mode_en = 0;
6503f49d684SMustafa Ismail push_idx = 0;
6513f49d684SMustafa Ismail } else {
6523f49d684SMustafa Ismail push_mode_en = 1;
6533f49d684SMustafa Ismail push_idx = qp->push_idx;
6543f49d684SMustafa Ismail }
6553f49d684SMustafa Ismail set_64bit_val(qp_ctx, 0,
6563f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RQWQESIZE, qp->qp_uk.rq_wqe_size) |
6573f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVTPHEN, qp->rcv_tph_en) |
6583f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_XMITTPHEN, qp->xmit_tph_en) |
6593f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RQTPHEN, qp->rq_tph_en) |
6603f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SQTPHEN, qp->sq_tph_en) |
6613f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PPIDX, push_idx) |
6623f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PMENA, push_mode_en) |
6633f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PDIDXHI, roce_info->pd_id >> 16) |
6643f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DC_TCP_EN, roce_info->dctcp_en) |
6653f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ERR_RQ_IDX_VALID, roce_info->err_rq_idx_valid) |
6663f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ISQP1, roce_info->is_qp1) |
6673f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ROCE_TVER, roce_info->roce_tver) |
6683f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_IPV4, udp->ipv4) |
6693f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_INSERTVLANTAG, udp->insert_vlan_tag));
6703f49d684SMustafa Ismail set_64bit_val(qp_ctx, 8, qp->sq_pa);
6713f49d684SMustafa Ismail set_64bit_val(qp_ctx, 16, qp->rq_pa);
6723f49d684SMustafa Ismail if ((roce_info->dcqcn_en || roce_info->dctcp_en) &&
6733f49d684SMustafa Ismail !(udp->tos & 0x03))
6743f49d684SMustafa Ismail udp->tos |= ECN_CODE_PT_VAL;
6753f49d684SMustafa Ismail set_64bit_val(qp_ctx, 24,
6763f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RQSIZE, qp->hw_rq_size) |
6773f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SQSIZE, qp->hw_sq_size) |
6783f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TTL, udp->ttl) | FIELD_PREP(IRDMAQPC_TOS, udp->tos) |
6793f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SRCPORTNUM, udp->src_port) |
6803f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTPORTNUM, udp->dst_port));
6813f49d684SMustafa Ismail set_64bit_val(qp_ctx, 32,
6823f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTIPADDR2, udp->dest_ip_addr[2]) |
6833f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTIPADDR3, udp->dest_ip_addr[3]));
6843f49d684SMustafa Ismail set_64bit_val(qp_ctx, 40,
6853f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTIPADDR0, udp->dest_ip_addr[0]) |
6863f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTIPADDR1, udp->dest_ip_addr[1]));
6873f49d684SMustafa Ismail set_64bit_val(qp_ctx, 48,
6883f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDMSS, udp->snd_mss) |
6893f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_VLANTAG, udp->vlan_tag) |
6903f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ARPIDX, udp->arp_idx));
6913f49d684SMustafa Ismail set_64bit_val(qp_ctx, 56,
6923f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PKEY, roce_info->p_key) |
6933f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PDIDX, roce_info->pd_id) |
6943f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ACKCREDITS, roce_info->ack_credits) |
6953f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_FLOWLABEL, udp->flow_label));
6963f49d684SMustafa Ismail set_64bit_val(qp_ctx, 64,
6973f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_QKEY, roce_info->qkey) |
6983f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTQP, roce_info->dest_qp));
6993f49d684SMustafa Ismail set_64bit_val(qp_ctx, 80,
7003f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PSNNXT, udp->psn_nxt) |
7013f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LSN, udp->lsn));
7023f49d684SMustafa Ismail set_64bit_val(qp_ctx, 88,
7033f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_EPSN, udp->epsn));
7043f49d684SMustafa Ismail set_64bit_val(qp_ctx, 96,
7053f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PSNMAX, udp->psn_max) |
7063f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PSNUNA, udp->psn_una));
7073f49d684SMustafa Ismail set_64bit_val(qp_ctx, 112,
7083f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_CWNDROCE, udp->cwnd));
7093f49d684SMustafa Ismail set_64bit_val(qp_ctx, 128,
7103f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ERR_RQ_IDX, roce_info->err_rq_idx) |
7113f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RNRNAK_THRESH, udp->rnr_nak_thresh) |
7123f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_REXMIT_THRESH, udp->rexmit_thresh) |
7133f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RTOMIN, roce_info->rtomin));
7143f49d684SMustafa Ismail set_64bit_val(qp_ctx, 136,
7153f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TXCQNUM, info->send_cq_num) |
7163f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RXCQNUM, info->rcv_cq_num));
7173f49d684SMustafa Ismail set_64bit_val(qp_ctx, 144,
7183f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_STAT_INDEX, info->stats_idx));
7193f49d684SMustafa Ismail set_64bit_val(qp_ctx, 152, ether_addr_to_u64(roce_info->mac_addr) << 16);
7203f49d684SMustafa Ismail set_64bit_val(qp_ctx, 160,
7213f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ORDSIZE, roce_info->ord_size) |
7223f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_IRDSIZE, irdma_sc_get_encoded_ird_size(roce_info->ird_size)) |
7233f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_WRRDRSPOK, roce_info->wr_rdresp_en) |
7243f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RDOK, roce_info->rd_en) |
7253f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_USESTATSINSTANCE, info->stats_idx_valid) |
7263f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_BINDEN, roce_info->bind_en) |
7273f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_FASTREGEN, roce_info->fast_reg_en) |
7283f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DCQCNENABLE, roce_info->dcqcn_en) |
7293f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVNOICRC, roce_info->rcv_no_icrc) |
7303f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_FW_CC_ENABLE, roce_info->fw_cc_enable) |
7313f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_UDPRIVCQENABLE, roce_info->udprivcq_en) |
7323f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PRIVEN, roce_info->priv_mode_en) |
7333f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TIMELYENABLE, roce_info->timely_en));
7343f49d684SMustafa Ismail set_64bit_val(qp_ctx, 168,
7353f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_QPCOMPCTX, info->qp_compl_ctx));
7363f49d684SMustafa Ismail set_64bit_val(qp_ctx, 176,
7373f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SQTPHVAL, qp->sq_tph_val) |
7383f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RQTPHVAL, qp->rq_tph_val) |
7393f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_QSHANDLE, qp->qs_handle));
7403f49d684SMustafa Ismail set_64bit_val(qp_ctx, 184,
7413f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LOCAL_IPADDR3, udp->local_ipaddr[3]) |
7423f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LOCAL_IPADDR2, udp->local_ipaddr[2]));
7433f49d684SMustafa Ismail set_64bit_val(qp_ctx, 192,
7443f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LOCAL_IPADDR1, udp->local_ipaddr[1]) |
7453f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LOCAL_IPADDR0, udp->local_ipaddr[0]));
7463f49d684SMustafa Ismail set_64bit_val(qp_ctx, 200,
7473f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_THIGH, roce_info->t_high) |
7483f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TLOW, roce_info->t_low));
7493f49d684SMustafa Ismail set_64bit_val(qp_ctx, 208,
7503f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_REMENDPOINTIDX, info->rem_endpoint_idx));
7513f49d684SMustafa Ismail
7523f49d684SMustafa Ismail print_hex_dump_debug("WQE: QP_HOST CTX WQE", DUMP_PREFIX_OFFSET, 16,
7533f49d684SMustafa Ismail 8, qp_ctx, IRDMA_QP_CTX_SIZE, false);
7543f49d684SMustafa Ismail }
7553f49d684SMustafa Ismail
7563f49d684SMustafa Ismail /* irdma_sc_alloc_local_mac_entry - allocate a mac entry
7573f49d684SMustafa Ismail * @cqp: struct for cqp hw
7583f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
7593f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
7603f49d684SMustafa Ismail */
irdma_sc_alloc_local_mac_entry(struct irdma_sc_cqp * cqp,u64 scratch,bool post_sq)7612c4b14eaSShiraz Saleem static int irdma_sc_alloc_local_mac_entry(struct irdma_sc_cqp *cqp, u64 scratch,
7623f49d684SMustafa Ismail bool post_sq)
7633f49d684SMustafa Ismail {
7643f49d684SMustafa Ismail __le64 *wqe;
7653f49d684SMustafa Ismail u64 hdr;
7663f49d684SMustafa Ismail
7673f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
7683f49d684SMustafa Ismail if (!wqe)
7692c4b14eaSShiraz Saleem return -ENOMEM;
7703f49d684SMustafa Ismail
7713f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE,
7723f49d684SMustafa Ismail IRDMA_CQP_OP_ALLOCATE_LOC_MAC_TABLE_ENTRY) |
7733f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
7743f49d684SMustafa Ismail
7753f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
7763f49d684SMustafa Ismail
7773f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
7783f49d684SMustafa Ismail
7793f49d684SMustafa Ismail print_hex_dump_debug("WQE: ALLOCATE_LOCAL_MAC WQE",
7803f49d684SMustafa Ismail DUMP_PREFIX_OFFSET, 16, 8, wqe,
7813f49d684SMustafa Ismail IRDMA_CQP_WQE_SIZE * 8, false);
7823f49d684SMustafa Ismail
7833f49d684SMustafa Ismail if (post_sq)
7843f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
7853f49d684SMustafa Ismail return 0;
7863f49d684SMustafa Ismail }
7873f49d684SMustafa Ismail
7883f49d684SMustafa Ismail /**
7893f49d684SMustafa Ismail * irdma_sc_add_local_mac_entry - add mac enry
7903f49d684SMustafa Ismail * @cqp: struct for cqp hw
7913f49d684SMustafa Ismail * @info:mac addr info
7923f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
7933f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
7943f49d684SMustafa Ismail */
irdma_sc_add_local_mac_entry(struct irdma_sc_cqp * cqp,struct irdma_local_mac_entry_info * info,u64 scratch,bool post_sq)7952c4b14eaSShiraz Saleem static int irdma_sc_add_local_mac_entry(struct irdma_sc_cqp *cqp,
7963f49d684SMustafa Ismail struct irdma_local_mac_entry_info *info,
7973f49d684SMustafa Ismail u64 scratch, bool post_sq)
7983f49d684SMustafa Ismail {
7993f49d684SMustafa Ismail __le64 *wqe;
8003f49d684SMustafa Ismail u64 header;
8013f49d684SMustafa Ismail
8023f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
8033f49d684SMustafa Ismail if (!wqe)
8042c4b14eaSShiraz Saleem return -ENOMEM;
8053f49d684SMustafa Ismail
8063f49d684SMustafa Ismail set_64bit_val(wqe, 32, ether_addr_to_u64(info->mac_addr));
8073f49d684SMustafa Ismail
8083f49d684SMustafa Ismail header = FIELD_PREP(IRDMA_CQPSQ_MLM_TABLEIDX, info->entry_idx) |
8093f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE,
8103f49d684SMustafa Ismail IRDMA_CQP_OP_MANAGE_LOC_MAC_TABLE) |
8113f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
8123f49d684SMustafa Ismail
8133f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
8143f49d684SMustafa Ismail
8153f49d684SMustafa Ismail set_64bit_val(wqe, 24, header);
8163f49d684SMustafa Ismail
8173f49d684SMustafa Ismail print_hex_dump_debug("WQE: ADD_LOCAL_MAC WQE", DUMP_PREFIX_OFFSET, 16,
8183f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
8193f49d684SMustafa Ismail
8203f49d684SMustafa Ismail if (post_sq)
8213f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
8223f49d684SMustafa Ismail return 0;
8233f49d684SMustafa Ismail }
8243f49d684SMustafa Ismail
8253f49d684SMustafa Ismail /**
8263f49d684SMustafa Ismail * irdma_sc_del_local_mac_entry - cqp wqe to dele local mac
8273f49d684SMustafa Ismail * @cqp: struct for cqp hw
8283f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
8293f49d684SMustafa Ismail * @entry_idx: index of mac entry
8303f49d684SMustafa Ismail * @ignore_ref_count: to force mac adde delete
8313f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
8323f49d684SMustafa Ismail */
irdma_sc_del_local_mac_entry(struct irdma_sc_cqp * cqp,u64 scratch,u16 entry_idx,u8 ignore_ref_count,bool post_sq)8332c4b14eaSShiraz Saleem static int irdma_sc_del_local_mac_entry(struct irdma_sc_cqp *cqp, u64 scratch,
8342c4b14eaSShiraz Saleem u16 entry_idx, u8 ignore_ref_count,
8352c4b14eaSShiraz Saleem bool post_sq)
8363f49d684SMustafa Ismail {
8373f49d684SMustafa Ismail __le64 *wqe;
8383f49d684SMustafa Ismail u64 header;
8393f49d684SMustafa Ismail
8403f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
8413f49d684SMustafa Ismail if (!wqe)
8422c4b14eaSShiraz Saleem return -ENOMEM;
8433f49d684SMustafa Ismail header = FIELD_PREP(IRDMA_CQPSQ_MLM_TABLEIDX, entry_idx) |
8443f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE,
8453f49d684SMustafa Ismail IRDMA_CQP_OP_MANAGE_LOC_MAC_TABLE) |
8463f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_MLM_FREEENTRY, 1) |
8473f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity) |
8483f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_MLM_IGNORE_REF_CNT, ignore_ref_count);
8493f49d684SMustafa Ismail
8503f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
8513f49d684SMustafa Ismail
8523f49d684SMustafa Ismail set_64bit_val(wqe, 24, header);
8533f49d684SMustafa Ismail
8543f49d684SMustafa Ismail print_hex_dump_debug("WQE: DEL_LOCAL_MAC_IPADDR WQE",
8553f49d684SMustafa Ismail DUMP_PREFIX_OFFSET, 16, 8, wqe,
8563f49d684SMustafa Ismail IRDMA_CQP_WQE_SIZE * 8, false);
8573f49d684SMustafa Ismail
8583f49d684SMustafa Ismail if (post_sq)
8593f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
8603f49d684SMustafa Ismail return 0;
8613f49d684SMustafa Ismail }
8623f49d684SMustafa Ismail
8633f49d684SMustafa Ismail /**
8643f49d684SMustafa Ismail * irdma_sc_qp_setctx - set qp's context
8653f49d684SMustafa Ismail * @qp: sc qp
8663f49d684SMustafa Ismail * @qp_ctx: context ptr
8673f49d684SMustafa Ismail * @info: ctx info
8683f49d684SMustafa Ismail */
irdma_sc_qp_setctx(struct irdma_sc_qp * qp,__le64 * qp_ctx,struct irdma_qp_host_ctx_info * info)8693f49d684SMustafa Ismail void irdma_sc_qp_setctx(struct irdma_sc_qp *qp, __le64 *qp_ctx,
8703f49d684SMustafa Ismail struct irdma_qp_host_ctx_info *info)
8713f49d684SMustafa Ismail {
8723f49d684SMustafa Ismail struct irdma_iwarp_offload_info *iw;
8733f49d684SMustafa Ismail struct irdma_tcp_offload_info *tcp;
8743f49d684SMustafa Ismail struct irdma_sc_dev *dev;
8753f49d684SMustafa Ismail u8 push_mode_en;
8763f49d684SMustafa Ismail u32 push_idx;
8773f49d684SMustafa Ismail u64 qw0, qw3, qw7 = 0, qw16 = 0;
8783f49d684SMustafa Ismail u64 mac = 0;
8793f49d684SMustafa Ismail
8803f49d684SMustafa Ismail iw = info->iwarp_info;
8813f49d684SMustafa Ismail tcp = info->tcp_info;
8823f49d684SMustafa Ismail dev = qp->dev;
8833f49d684SMustafa Ismail if (iw->rcv_mark_en) {
8843f49d684SMustafa Ismail qp->pfpdu.marker_len = 4;
8853f49d684SMustafa Ismail qp->pfpdu.rcv_start_seq = tcp->rcv_nxt;
8863f49d684SMustafa Ismail }
8873f49d684SMustafa Ismail qp->user_pri = info->user_pri;
8883f49d684SMustafa Ismail if (qp->push_idx == IRDMA_INVALID_PUSH_PAGE_INDEX) {
8893f49d684SMustafa Ismail push_mode_en = 0;
8903f49d684SMustafa Ismail push_idx = 0;
8913f49d684SMustafa Ismail } else {
8923f49d684SMustafa Ismail push_mode_en = 1;
8933f49d684SMustafa Ismail push_idx = qp->push_idx;
8943f49d684SMustafa Ismail }
8953f49d684SMustafa Ismail qw0 = FIELD_PREP(IRDMAQPC_RQWQESIZE, qp->qp_uk.rq_wqe_size) |
8963f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVTPHEN, qp->rcv_tph_en) |
8973f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_XMITTPHEN, qp->xmit_tph_en) |
8983f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RQTPHEN, qp->rq_tph_en) |
8993f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SQTPHEN, qp->sq_tph_en) |
9003f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PPIDX, push_idx) |
9013f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PMENA, push_mode_en);
9023f49d684SMustafa Ismail
9033f49d684SMustafa Ismail set_64bit_val(qp_ctx, 8, qp->sq_pa);
9043f49d684SMustafa Ismail set_64bit_val(qp_ctx, 16, qp->rq_pa);
9053f49d684SMustafa Ismail
9063f49d684SMustafa Ismail qw3 = FIELD_PREP(IRDMAQPC_RQSIZE, qp->hw_rq_size) |
9073f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SQSIZE, qp->hw_sq_size);
9083f49d684SMustafa Ismail if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
9093f49d684SMustafa Ismail qw3 |= FIELD_PREP(IRDMAQPC_GEN1_SRCMACADDRIDX,
9103f49d684SMustafa Ismail qp->src_mac_addr_idx);
9113f49d684SMustafa Ismail set_64bit_val(qp_ctx, 136,
9123f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TXCQNUM, info->send_cq_num) |
9133f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RXCQNUM, info->rcv_cq_num));
9143f49d684SMustafa Ismail set_64bit_val(qp_ctx, 168,
9153f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_QPCOMPCTX, info->qp_compl_ctx));
9163f49d684SMustafa Ismail set_64bit_val(qp_ctx, 176,
9173f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SQTPHVAL, qp->sq_tph_val) |
9183f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RQTPHVAL, qp->rq_tph_val) |
9193f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_QSHANDLE, qp->qs_handle) |
9203f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_EXCEPTION_LAN_QUEUE, qp->ieq_qp));
9213f49d684SMustafa Ismail if (info->iwarp_info_valid) {
9223f49d684SMustafa Ismail qw0 |= FIELD_PREP(IRDMAQPC_DDP_VER, iw->ddp_ver) |
9233f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RDMAP_VER, iw->rdmap_ver) |
9243f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DC_TCP_EN, iw->dctcp_en) |
9253f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ECN_EN, iw->ecn_en) |
9263f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_IBRDENABLE, iw->ib_rd_en) |
9273f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PDIDXHI, iw->pd_id >> 16) |
9283f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ERR_RQ_IDX_VALID,
9293f49d684SMustafa Ismail iw->err_rq_idx_valid);
9303f49d684SMustafa Ismail qw7 |= FIELD_PREP(IRDMAQPC_PDIDX, iw->pd_id);
9313f49d684SMustafa Ismail qw16 |= FIELD_PREP(IRDMAQPC_ERR_RQ_IDX, iw->err_rq_idx) |
9323f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RTOMIN, iw->rtomin);
9333f49d684SMustafa Ismail set_64bit_val(qp_ctx, 144,
9343f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_Q2ADDR, qp->q2_pa >> 8) |
9353f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_STAT_INDEX, info->stats_idx));
9363f49d684SMustafa Ismail
9373f49d684SMustafa Ismail if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2)
9383f49d684SMustafa Ismail mac = ether_addr_to_u64(iw->mac_addr);
9393f49d684SMustafa Ismail
9403f49d684SMustafa Ismail set_64bit_val(qp_ctx, 152,
9413f49d684SMustafa Ismail mac << 16 | FIELD_PREP(IRDMAQPC_LASTBYTESENT, iw->last_byte_sent));
9423f49d684SMustafa Ismail set_64bit_val(qp_ctx, 160,
9433f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ORDSIZE, iw->ord_size) |
9443f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_IRDSIZE, irdma_sc_get_encoded_ird_size(iw->ird_size)) |
9453f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_WRRDRSPOK, iw->wr_rdresp_en) |
9463f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RDOK, iw->rd_en) |
9473f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDMARKERS, iw->snd_mark_en) |
9483f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_BINDEN, iw->bind_en) |
9493f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_FASTREGEN, iw->fast_reg_en) |
9503f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_PRIVEN, iw->priv_mode_en) |
9513f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_USESTATSINSTANCE, info->stats_idx_valid) |
9523f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_IWARPMODE, 1) |
9533f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVMARKERS, iw->rcv_mark_en) |
9543f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ALIGNHDRS, iw->align_hdrs) |
9553f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVNOMPACRC, iw->rcv_no_mpa_crc) |
9563f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVMARKOFFSET, iw->rcv_mark_offset || !tcp ? iw->rcv_mark_offset : tcp->rcv_nxt) |
9573f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDMARKOFFSET, iw->snd_mark_offset || !tcp ? iw->snd_mark_offset : tcp->snd_nxt) |
9583f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TIMELYENABLE, iw->timely_en));
9593f49d684SMustafa Ismail }
9603f49d684SMustafa Ismail if (info->tcp_info_valid) {
9613f49d684SMustafa Ismail qw0 |= FIELD_PREP(IRDMAQPC_IPV4, tcp->ipv4) |
9623f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_NONAGLE, tcp->no_nagle) |
9633f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_INSERTVLANTAG,
9643f49d684SMustafa Ismail tcp->insert_vlan_tag) |
9653f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TIMESTAMP, tcp->time_stamp) |
9663f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LIMIT, tcp->cwnd_inc_limit) |
9673f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DROPOOOSEG, tcp->drop_ooo_seg) |
9683f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DUPACK_THRESH, tcp->dup_ack_thresh);
9693f49d684SMustafa Ismail
9703f49d684SMustafa Ismail if ((iw->ecn_en || iw->dctcp_en) && !(tcp->tos & 0x03))
9713f49d684SMustafa Ismail tcp->tos |= ECN_CODE_PT_VAL;
9723f49d684SMustafa Ismail
9733f49d684SMustafa Ismail qw3 |= FIELD_PREP(IRDMAQPC_TTL, tcp->ttl) |
9743f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_AVOIDSTRETCHACK, tcp->avoid_stretch_ack) |
9753f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TOS, tcp->tos) |
9763f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SRCPORTNUM, tcp->src_port) |
9773f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTPORTNUM, tcp->dst_port);
9783f49d684SMustafa Ismail if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) {
9793f49d684SMustafa Ismail qw3 |= FIELD_PREP(IRDMAQPC_GEN1_SRCMACADDRIDX, tcp->src_mac_addr_idx);
9803f49d684SMustafa Ismail
9813f49d684SMustafa Ismail qp->src_mac_addr_idx = tcp->src_mac_addr_idx;
9823f49d684SMustafa Ismail }
9833f49d684SMustafa Ismail set_64bit_val(qp_ctx, 32,
9843f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTIPADDR2, tcp->dest_ip_addr[2]) |
9853f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTIPADDR3, tcp->dest_ip_addr[3]));
9863f49d684SMustafa Ismail set_64bit_val(qp_ctx, 40,
9873f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTIPADDR0, tcp->dest_ip_addr[0]) |
9883f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_DESTIPADDR1, tcp->dest_ip_addr[1]));
9893f49d684SMustafa Ismail set_64bit_val(qp_ctx, 48,
9903f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDMSS, tcp->snd_mss) |
9913f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SYN_RST_HANDLING, tcp->syn_rst_handling) |
9923f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_VLANTAG, tcp->vlan_tag) |
9933f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_ARPIDX, tcp->arp_idx));
9943f49d684SMustafa Ismail qw7 |= FIELD_PREP(IRDMAQPC_FLOWLABEL, tcp->flow_label) |
9953f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_WSCALE, tcp->wscale) |
9963f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_IGNORE_TCP_OPT,
9973f49d684SMustafa Ismail tcp->ignore_tcp_opt) |
9983f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_IGNORE_TCP_UNS_OPT,
9993f49d684SMustafa Ismail tcp->ignore_tcp_uns_opt) |
10003f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TCPSTATE, tcp->tcp_state) |
10013f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVSCALE, tcp->rcv_wscale) |
10023f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDSCALE, tcp->snd_wscale);
10033f49d684SMustafa Ismail set_64bit_val(qp_ctx, 72,
10043f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TIMESTAMP_RECENT, tcp->time_stamp_recent) |
10053f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TIMESTAMP_AGE, tcp->time_stamp_age));
10063f49d684SMustafa Ismail set_64bit_val(qp_ctx, 80,
10073f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDNXT, tcp->snd_nxt) |
10083f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDWND, tcp->snd_wnd));
10093f49d684SMustafa Ismail set_64bit_val(qp_ctx, 88,
10103f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVNXT, tcp->rcv_nxt) |
10113f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RCVWND, tcp->rcv_wnd));
10123f49d684SMustafa Ismail set_64bit_val(qp_ctx, 96,
10133f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDMAX, tcp->snd_max) |
10143f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDUNA, tcp->snd_una));
10153f49d684SMustafa Ismail set_64bit_val(qp_ctx, 104,
10163f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SRTT, tcp->srtt) |
10173f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_RTTVAR, tcp->rtt_var));
10183f49d684SMustafa Ismail set_64bit_val(qp_ctx, 112,
10193f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SSTHRESH, tcp->ss_thresh) |
10203f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_CWND, tcp->cwnd));
10213f49d684SMustafa Ismail set_64bit_val(qp_ctx, 120,
10223f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDWL1, tcp->snd_wl1) |
10233f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_SNDWL2, tcp->snd_wl2));
10243f49d684SMustafa Ismail qw16 |= FIELD_PREP(IRDMAQPC_MAXSNDWND, tcp->max_snd_window) |
10253f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_REXMIT_THRESH, tcp->rexmit_thresh);
10263f49d684SMustafa Ismail set_64bit_val(qp_ctx, 184,
10273f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LOCAL_IPADDR3, tcp->local_ipaddr[3]) |
10283f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LOCAL_IPADDR2, tcp->local_ipaddr[2]));
10293f49d684SMustafa Ismail set_64bit_val(qp_ctx, 192,
10303f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LOCAL_IPADDR1, tcp->local_ipaddr[1]) |
10313f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_LOCAL_IPADDR0, tcp->local_ipaddr[0]));
10323f49d684SMustafa Ismail set_64bit_val(qp_ctx, 200,
10333f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_THIGH, iw->t_high) |
10343f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_TLOW, iw->t_low));
10353f49d684SMustafa Ismail set_64bit_val(qp_ctx, 208,
10363f49d684SMustafa Ismail FIELD_PREP(IRDMAQPC_REMENDPOINTIDX, info->rem_endpoint_idx));
10373f49d684SMustafa Ismail }
10383f49d684SMustafa Ismail
10393f49d684SMustafa Ismail set_64bit_val(qp_ctx, 0, qw0);
10403f49d684SMustafa Ismail set_64bit_val(qp_ctx, 24, qw3);
10413f49d684SMustafa Ismail set_64bit_val(qp_ctx, 56, qw7);
10423f49d684SMustafa Ismail set_64bit_val(qp_ctx, 128, qw16);
10433f49d684SMustafa Ismail
10443f49d684SMustafa Ismail print_hex_dump_debug("WQE: QP_HOST CTX", DUMP_PREFIX_OFFSET, 16, 8,
10453f49d684SMustafa Ismail qp_ctx, IRDMA_QP_CTX_SIZE, false);
10463f49d684SMustafa Ismail }
10473f49d684SMustafa Ismail
10483f49d684SMustafa Ismail /**
10493f49d684SMustafa Ismail * irdma_sc_alloc_stag - mr stag alloc
10503f49d684SMustafa Ismail * @dev: sc device struct
10513f49d684SMustafa Ismail * @info: stag info
10523f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
10533f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
10543f49d684SMustafa Ismail */
irdma_sc_alloc_stag(struct irdma_sc_dev * dev,struct irdma_allocate_stag_info * info,u64 scratch,bool post_sq)10552c4b14eaSShiraz Saleem static int irdma_sc_alloc_stag(struct irdma_sc_dev *dev,
10562c4b14eaSShiraz Saleem struct irdma_allocate_stag_info *info,
10572c4b14eaSShiraz Saleem u64 scratch, bool post_sq)
10583f49d684SMustafa Ismail {
10593f49d684SMustafa Ismail __le64 *wqe;
10603f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
10613f49d684SMustafa Ismail u64 hdr;
10623f49d684SMustafa Ismail enum irdma_page_size page_size;
10633f49d684SMustafa Ismail
1064*bb6d73d9SChristopher Bednarz if (!info->total_len && !info->all_memory)
1065*bb6d73d9SChristopher Bednarz return -EINVAL;
1066*bb6d73d9SChristopher Bednarz
10673f49d684SMustafa Ismail if (info->page_size == 0x40000000)
10683f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_1G;
10693f49d684SMustafa Ismail else if (info->page_size == 0x200000)
10703f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_2M;
10713f49d684SMustafa Ismail else
10723f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_4K;
10733f49d684SMustafa Ismail
10743f49d684SMustafa Ismail cqp = dev->cqp;
10753f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
10763f49d684SMustafa Ismail if (!wqe)
10772c4b14eaSShiraz Saleem return -ENOMEM;
10783f49d684SMustafa Ismail
10793f49d684SMustafa Ismail set_64bit_val(wqe, 8,
10803f49d684SMustafa Ismail FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID) |
10813f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_STAGLEN, info->total_len));
10823f49d684SMustafa Ismail set_64bit_val(wqe, 16,
10833f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx));
10843f49d684SMustafa Ismail set_64bit_val(wqe, 40,
10853f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_HMCFNIDX, info->hmc_fcn_index));
10863f49d684SMustafa Ismail
10873f49d684SMustafa Ismail if (info->chunk_size)
10883f49d684SMustafa Ismail set_64bit_val(wqe, 48,
10893f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_FIRSTPMPBLIDX, info->first_pm_pbl_idx));
10903f49d684SMustafa Ismail
10913f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_ALLOC_STAG) |
10923f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_MR, 1) |
10933f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_ARIGHTS, info->access_rights) |
10943f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_LPBLSIZE, info->chunk_size) |
10953f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_HPAGESIZE, page_size) |
10963f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_REMACCENABLED, info->remote_access) |
10973f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_USEHMCFNIDX, info->use_hmc_fcn_index) |
10983f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_USEPFRID, info->use_pf_rid) |
10993f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
11003f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
11013f49d684SMustafa Ismail
11023f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
11033f49d684SMustafa Ismail
11043f49d684SMustafa Ismail print_hex_dump_debug("WQE: ALLOC_STAG WQE", DUMP_PREFIX_OFFSET, 16, 8,
11053f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
11063f49d684SMustafa Ismail if (post_sq)
11073f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
11083f49d684SMustafa Ismail
11093f49d684SMustafa Ismail return 0;
11103f49d684SMustafa Ismail }
11113f49d684SMustafa Ismail
11123f49d684SMustafa Ismail /**
11133f49d684SMustafa Ismail * irdma_sc_mr_reg_non_shared - non-shared mr registration
11143f49d684SMustafa Ismail * @dev: sc device struct
11153f49d684SMustafa Ismail * @info: mr info
11163f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
11173f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
11183f49d684SMustafa Ismail */
irdma_sc_mr_reg_non_shared(struct irdma_sc_dev * dev,struct irdma_reg_ns_stag_info * info,u64 scratch,bool post_sq)11192c4b14eaSShiraz Saleem static int irdma_sc_mr_reg_non_shared(struct irdma_sc_dev *dev,
11202c4b14eaSShiraz Saleem struct irdma_reg_ns_stag_info *info,
11212c4b14eaSShiraz Saleem u64 scratch, bool post_sq)
11223f49d684SMustafa Ismail {
11233f49d684SMustafa Ismail __le64 *wqe;
11243f49d684SMustafa Ismail u64 fbo;
11253f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
11263f49d684SMustafa Ismail u64 hdr;
11273f49d684SMustafa Ismail u32 pble_obj_cnt;
11283f49d684SMustafa Ismail bool remote_access;
11293f49d684SMustafa Ismail u8 addr_type;
11303f49d684SMustafa Ismail enum irdma_page_size page_size;
11313f49d684SMustafa Ismail
1132*bb6d73d9SChristopher Bednarz if (!info->total_len && !info->all_memory)
1133*bb6d73d9SChristopher Bednarz return -EINVAL;
1134*bb6d73d9SChristopher Bednarz
11353f49d684SMustafa Ismail if (info->page_size == 0x40000000)
11363f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_1G;
11373f49d684SMustafa Ismail else if (info->page_size == 0x200000)
11383f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_2M;
11393f49d684SMustafa Ismail else if (info->page_size == 0x1000)
11403f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_4K;
11413f49d684SMustafa Ismail else
11422c4b14eaSShiraz Saleem return -EINVAL;
11433f49d684SMustafa Ismail
11443f49d684SMustafa Ismail if (info->access_rights & (IRDMA_ACCESS_FLAGS_REMOTEREAD_ONLY |
11453f49d684SMustafa Ismail IRDMA_ACCESS_FLAGS_REMOTEWRITE_ONLY))
11463f49d684SMustafa Ismail remote_access = true;
11473f49d684SMustafa Ismail else
11483f49d684SMustafa Ismail remote_access = false;
11493f49d684SMustafa Ismail
11503f49d684SMustafa Ismail pble_obj_cnt = dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
11513f49d684SMustafa Ismail if (info->chunk_size && info->first_pm_pbl_index >= pble_obj_cnt)
11522c4b14eaSShiraz Saleem return -EINVAL;
11533f49d684SMustafa Ismail
11543f49d684SMustafa Ismail cqp = dev->cqp;
11553f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
11563f49d684SMustafa Ismail if (!wqe)
11572c4b14eaSShiraz Saleem return -ENOMEM;
11583f49d684SMustafa Ismail fbo = info->va & (info->page_size - 1);
11593f49d684SMustafa Ismail
11603f49d684SMustafa Ismail set_64bit_val(wqe, 0,
11613f49d684SMustafa Ismail (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED ?
11623f49d684SMustafa Ismail info->va : fbo));
11633f49d684SMustafa Ismail set_64bit_val(wqe, 8,
11643f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_STAGLEN, info->total_len) |
11653f49d684SMustafa Ismail FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID));
11663f49d684SMustafa Ismail set_64bit_val(wqe, 16,
11673f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_KEY, info->stag_key) |
11683f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx));
11693f49d684SMustafa Ismail if (!info->chunk_size) {
11703f49d684SMustafa Ismail set_64bit_val(wqe, 32, info->reg_addr_pa);
11713f49d684SMustafa Ismail set_64bit_val(wqe, 48, 0);
11723f49d684SMustafa Ismail } else {
11733f49d684SMustafa Ismail set_64bit_val(wqe, 32, 0);
11743f49d684SMustafa Ismail set_64bit_val(wqe, 48,
11753f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_FIRSTPMPBLIDX, info->first_pm_pbl_index));
11763f49d684SMustafa Ismail }
11773f49d684SMustafa Ismail set_64bit_val(wqe, 40, info->hmc_fcn_index);
11783f49d684SMustafa Ismail set_64bit_val(wqe, 56, 0);
11793f49d684SMustafa Ismail
11803f49d684SMustafa Ismail addr_type = (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED) ? 1 : 0;
11813f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_REG_MR) |
11823f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_MR, 1) |
11833f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_LPBLSIZE, info->chunk_size) |
11843f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_HPAGESIZE, page_size) |
11853f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_ARIGHTS, info->access_rights) |
11863f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_REMACCENABLED, remote_access) |
11873f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_VABASEDTO, addr_type) |
11883f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_USEHMCFNIDX, info->use_hmc_fcn_index) |
11893f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_USEPFRID, info->use_pf_rid) |
11903f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
11913f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
11923f49d684SMustafa Ismail
11933f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
11943f49d684SMustafa Ismail
11953f49d684SMustafa Ismail print_hex_dump_debug("WQE: MR_REG_NS WQE", DUMP_PREFIX_OFFSET, 16, 8,
11963f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
11973f49d684SMustafa Ismail if (post_sq)
11983f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
11993f49d684SMustafa Ismail
12003f49d684SMustafa Ismail return 0;
12013f49d684SMustafa Ismail }
12023f49d684SMustafa Ismail
12033f49d684SMustafa Ismail /**
12043f49d684SMustafa Ismail * irdma_sc_dealloc_stag - deallocate stag
12053f49d684SMustafa Ismail * @dev: sc device struct
12063f49d684SMustafa Ismail * @info: dealloc stag info
12073f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
12083f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
12093f49d684SMustafa Ismail */
irdma_sc_dealloc_stag(struct irdma_sc_dev * dev,struct irdma_dealloc_stag_info * info,u64 scratch,bool post_sq)12102c4b14eaSShiraz Saleem static int irdma_sc_dealloc_stag(struct irdma_sc_dev *dev,
12112c4b14eaSShiraz Saleem struct irdma_dealloc_stag_info *info,
12122c4b14eaSShiraz Saleem u64 scratch, bool post_sq)
12133f49d684SMustafa Ismail {
12143f49d684SMustafa Ismail u64 hdr;
12153f49d684SMustafa Ismail __le64 *wqe;
12163f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
12173f49d684SMustafa Ismail
12183f49d684SMustafa Ismail cqp = dev->cqp;
12193f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
12203f49d684SMustafa Ismail if (!wqe)
12212c4b14eaSShiraz Saleem return -ENOMEM;
12223f49d684SMustafa Ismail
12233f49d684SMustafa Ismail set_64bit_val(wqe, 8,
12243f49d684SMustafa Ismail FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID));
12253f49d684SMustafa Ismail set_64bit_val(wqe, 16,
12263f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx));
12273f49d684SMustafa Ismail
12283f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DEALLOC_STAG) |
12293f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_MR, info->mr) |
12303f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
12313f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
12323f49d684SMustafa Ismail
12333f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
12343f49d684SMustafa Ismail
12353f49d684SMustafa Ismail print_hex_dump_debug("WQE: DEALLOC_STAG WQE", DUMP_PREFIX_OFFSET, 16,
12363f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
12373f49d684SMustafa Ismail if (post_sq)
12383f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
12393f49d684SMustafa Ismail
12403f49d684SMustafa Ismail return 0;
12413f49d684SMustafa Ismail }
12423f49d684SMustafa Ismail
12433f49d684SMustafa Ismail /**
12443f49d684SMustafa Ismail * irdma_sc_mw_alloc - mw allocate
12453f49d684SMustafa Ismail * @dev: sc device struct
12463f49d684SMustafa Ismail * @info: memory window allocation information
12473f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
12483f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
12493f49d684SMustafa Ismail */
irdma_sc_mw_alloc(struct irdma_sc_dev * dev,struct irdma_mw_alloc_info * info,u64 scratch,bool post_sq)12502c4b14eaSShiraz Saleem static int irdma_sc_mw_alloc(struct irdma_sc_dev *dev,
12512c4b14eaSShiraz Saleem struct irdma_mw_alloc_info *info, u64 scratch,
12522c4b14eaSShiraz Saleem bool post_sq)
12533f49d684SMustafa Ismail {
12543f49d684SMustafa Ismail u64 hdr;
12553f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
12563f49d684SMustafa Ismail __le64 *wqe;
12573f49d684SMustafa Ismail
12583f49d684SMustafa Ismail cqp = dev->cqp;
12593f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
12603f49d684SMustafa Ismail if (!wqe)
12612c4b14eaSShiraz Saleem return -ENOMEM;
12623f49d684SMustafa Ismail
12633f49d684SMustafa Ismail set_64bit_val(wqe, 8,
12643f49d684SMustafa Ismail FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID));
12653f49d684SMustafa Ismail set_64bit_val(wqe, 16,
12663f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->mw_stag_index));
12673f49d684SMustafa Ismail
12683f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_ALLOC_STAG) |
12693f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_MWTYPE, info->mw_wide) |
12703f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STAG_MW1_BIND_DONT_VLDT_KEY,
12713f49d684SMustafa Ismail info->mw1_bind_dont_vldt_key) |
12723f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
12733f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
12743f49d684SMustafa Ismail
12753f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
12763f49d684SMustafa Ismail
12773f49d684SMustafa Ismail print_hex_dump_debug("WQE: MW_ALLOC WQE", DUMP_PREFIX_OFFSET, 16, 8,
12783f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
12793f49d684SMustafa Ismail if (post_sq)
12803f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
12813f49d684SMustafa Ismail
12823f49d684SMustafa Ismail return 0;
12833f49d684SMustafa Ismail }
12843f49d684SMustafa Ismail
12853f49d684SMustafa Ismail /**
12863f49d684SMustafa Ismail * irdma_sc_mr_fast_register - Posts RDMA fast register mr WR to iwarp qp
12873f49d684SMustafa Ismail * @qp: sc qp struct
12883f49d684SMustafa Ismail * @info: fast mr info
12893f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
12903f49d684SMustafa Ismail */
irdma_sc_mr_fast_register(struct irdma_sc_qp * qp,struct irdma_fast_reg_stag_info * info,bool post_sq)12912c4b14eaSShiraz Saleem int irdma_sc_mr_fast_register(struct irdma_sc_qp *qp,
12922c4b14eaSShiraz Saleem struct irdma_fast_reg_stag_info *info,
12932c4b14eaSShiraz Saleem bool post_sq)
12943f49d684SMustafa Ismail {
12953f49d684SMustafa Ismail u64 temp, hdr;
12963f49d684SMustafa Ismail __le64 *wqe;
12973f49d684SMustafa Ismail u32 wqe_idx;
12983f49d684SMustafa Ismail enum irdma_page_size page_size;
12993f49d684SMustafa Ismail struct irdma_post_sq_info sq_info = {};
13003f49d684SMustafa Ismail
13013f49d684SMustafa Ismail if (info->page_size == 0x40000000)
13023f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_1G;
13033f49d684SMustafa Ismail else if (info->page_size == 0x200000)
13043f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_2M;
13053f49d684SMustafa Ismail else
13063f49d684SMustafa Ismail page_size = IRDMA_PAGE_SIZE_4K;
13073f49d684SMustafa Ismail
13083f49d684SMustafa Ismail sq_info.wr_id = info->wr_id;
13093f49d684SMustafa Ismail sq_info.signaled = info->signaled;
13103f49d684SMustafa Ismail
13113f49d684SMustafa Ismail wqe = irdma_qp_get_next_send_wqe(&qp->qp_uk, &wqe_idx,
13123f49d684SMustafa Ismail IRDMA_QP_WQE_MIN_QUANTA, 0, &sq_info);
13133f49d684SMustafa Ismail if (!wqe)
13142c4b14eaSShiraz Saleem return -ENOMEM;
13153f49d684SMustafa Ismail
13163f49d684SMustafa Ismail irdma_clr_wqes(&qp->qp_uk, wqe_idx);
13173f49d684SMustafa Ismail
13183f49d684SMustafa Ismail ibdev_dbg(to_ibdev(qp->dev),
13193f49d684SMustafa Ismail "MR: wr_id[%llxh] wqe_idx[%04d] location[%p]\n",
13203f49d684SMustafa Ismail info->wr_id, wqe_idx,
13213f49d684SMustafa Ismail &qp->qp_uk.sq_wrtrk_array[wqe_idx].wrid);
13223f49d684SMustafa Ismail
13233f49d684SMustafa Ismail temp = (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED) ?
13243f49d684SMustafa Ismail (uintptr_t)info->va : info->fbo;
13253f49d684SMustafa Ismail set_64bit_val(wqe, 0, temp);
13263f49d684SMustafa Ismail
13273f49d684SMustafa Ismail temp = FIELD_GET(IRDMAQPSQ_FIRSTPMPBLIDXHI,
13283f49d684SMustafa Ismail info->first_pm_pbl_index >> 16);
13293f49d684SMustafa Ismail set_64bit_val(wqe, 8,
13303f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_FIRSTPMPBLIDXHI, temp) |
13313f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_PBLADDR >> IRDMA_HW_PAGE_SHIFT, info->reg_addr_pa));
13323f49d684SMustafa Ismail set_64bit_val(wqe, 16,
13333f49d684SMustafa Ismail info->total_len |
13343f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_FIRSTPMPBLIDXLO, info->first_pm_pbl_index));
13353f49d684SMustafa Ismail
13363f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_STAGKEY, info->stag_key) |
13373f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_STAGINDEX, info->stag_idx) |
13383f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_FAST_REGISTER) |
13393f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_LPBLSIZE, info->chunk_size) |
13403f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_HPAGESIZE, page_size) |
13413f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_STAGRIGHTS, info->access_rights) |
13423f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VABASEDTO, info->addr_type) |
13433f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) |
13443f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
13453f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
13463f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity);
13473f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
13483f49d684SMustafa Ismail
13493f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
13503f49d684SMustafa Ismail
13513f49d684SMustafa Ismail print_hex_dump_debug("WQE: FAST_REG WQE", DUMP_PREFIX_OFFSET, 16, 8,
13523f49d684SMustafa Ismail wqe, IRDMA_QP_WQE_MIN_SIZE, false);
1353295c95aaSShiraz Saleem
13543f49d684SMustafa Ismail if (post_sq)
13553f49d684SMustafa Ismail irdma_uk_qp_post_wr(&qp->qp_uk);
13563f49d684SMustafa Ismail
13573f49d684SMustafa Ismail return 0;
13583f49d684SMustafa Ismail }
13593f49d684SMustafa Ismail
13603f49d684SMustafa Ismail /**
13613f49d684SMustafa Ismail * irdma_sc_gen_rts_ae - request AE generated after RTS
13623f49d684SMustafa Ismail * @qp: sc qp struct
13633f49d684SMustafa Ismail */
irdma_sc_gen_rts_ae(struct irdma_sc_qp * qp)13643f49d684SMustafa Ismail static void irdma_sc_gen_rts_ae(struct irdma_sc_qp *qp)
13653f49d684SMustafa Ismail {
13663f49d684SMustafa Ismail __le64 *wqe;
13673f49d684SMustafa Ismail u64 hdr;
13683f49d684SMustafa Ismail struct irdma_qp_uk *qp_uk;
13693f49d684SMustafa Ismail
13703f49d684SMustafa Ismail qp_uk = &qp->qp_uk;
13713f49d684SMustafa Ismail
13723f49d684SMustafa Ismail wqe = qp_uk->sq_base[1].elem;
13733f49d684SMustafa Ismail
13743f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_NOP) |
13753f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, 1) |
13763f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity);
13773f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
13783f49d684SMustafa Ismail
13793f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
13803f49d684SMustafa Ismail print_hex_dump_debug("QP: NOP W/LOCAL FENCE WQE", DUMP_PREFIX_OFFSET,
13813f49d684SMustafa Ismail 16, 8, wqe, IRDMA_QP_WQE_MIN_SIZE, false);
13823f49d684SMustafa Ismail
13833f49d684SMustafa Ismail wqe = qp_uk->sq_base[2].elem;
13843f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_GEN_RTS_AE) |
13853f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity);
13863f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
13873f49d684SMustafa Ismail
13883f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
13893f49d684SMustafa Ismail print_hex_dump_debug("QP: CONN EST WQE", DUMP_PREFIX_OFFSET, 16, 8,
13903f49d684SMustafa Ismail wqe, IRDMA_QP_WQE_MIN_SIZE, false);
13913f49d684SMustafa Ismail }
13923f49d684SMustafa Ismail
13933f49d684SMustafa Ismail /**
13943f49d684SMustafa Ismail * irdma_sc_send_lsmm - send last streaming mode message
13953f49d684SMustafa Ismail * @qp: sc qp struct
13963f49d684SMustafa Ismail * @lsmm_buf: buffer with lsmm message
13973f49d684SMustafa Ismail * @size: size of lsmm buffer
13983f49d684SMustafa Ismail * @stag: stag of lsmm buffer
13993f49d684SMustafa Ismail */
irdma_sc_send_lsmm(struct irdma_sc_qp * qp,void * lsmm_buf,u32 size,irdma_stag stag)14003f49d684SMustafa Ismail void irdma_sc_send_lsmm(struct irdma_sc_qp *qp, void *lsmm_buf, u32 size,
14013f49d684SMustafa Ismail irdma_stag stag)
14023f49d684SMustafa Ismail {
14033f49d684SMustafa Ismail __le64 *wqe;
14043f49d684SMustafa Ismail u64 hdr;
14053f49d684SMustafa Ismail struct irdma_qp_uk *qp_uk;
14063f49d684SMustafa Ismail
14073f49d684SMustafa Ismail qp_uk = &qp->qp_uk;
14083f49d684SMustafa Ismail wqe = qp_uk->sq_base->elem;
14093f49d684SMustafa Ismail
14103f49d684SMustafa Ismail set_64bit_val(wqe, 0, (uintptr_t)lsmm_buf);
14113f49d684SMustafa Ismail if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) {
14123f49d684SMustafa Ismail set_64bit_val(wqe, 8,
14133f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_LEN, size) |
14143f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_STAG, stag));
14153f49d684SMustafa Ismail } else {
14163f49d684SMustafa Ismail set_64bit_val(wqe, 8,
14173f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_LEN, size) |
14183f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_STAG, stag) |
14193f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity));
14203f49d684SMustafa Ismail }
14213f49d684SMustafa Ismail set_64bit_val(wqe, 16, 0);
14223f49d684SMustafa Ismail
14233f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_RDMA_SEND) |
14243f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_STREAMMODE, 1) |
14253f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_WAITFORRCVPDU, 1) |
14263f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity);
14273f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
14283f49d684SMustafa Ismail
14293f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
14303f49d684SMustafa Ismail
14313f49d684SMustafa Ismail print_hex_dump_debug("WQE: SEND_LSMM WQE", DUMP_PREFIX_OFFSET, 16, 8,
14323f49d684SMustafa Ismail wqe, IRDMA_QP_WQE_MIN_SIZE, false);
14333f49d684SMustafa Ismail
14343f49d684SMustafa Ismail if (qp->dev->hw_attrs.uk_attrs.feature_flags & IRDMA_FEATURE_RTS_AE)
14353f49d684SMustafa Ismail irdma_sc_gen_rts_ae(qp);
14363f49d684SMustafa Ismail }
14373f49d684SMustafa Ismail
14383f49d684SMustafa Ismail /**
14393f49d684SMustafa Ismail * irdma_sc_send_rtt - send last read0 or write0
14403f49d684SMustafa Ismail * @qp: sc qp struct
14413f49d684SMustafa Ismail * @read: Do read0 or write0
14423f49d684SMustafa Ismail */
irdma_sc_send_rtt(struct irdma_sc_qp * qp,bool read)14433f49d684SMustafa Ismail void irdma_sc_send_rtt(struct irdma_sc_qp *qp, bool read)
14443f49d684SMustafa Ismail {
14453f49d684SMustafa Ismail __le64 *wqe;
14463f49d684SMustafa Ismail u64 hdr;
14473f49d684SMustafa Ismail struct irdma_qp_uk *qp_uk;
14483f49d684SMustafa Ismail
14493f49d684SMustafa Ismail qp_uk = &qp->qp_uk;
14503f49d684SMustafa Ismail wqe = qp_uk->sq_base->elem;
14513f49d684SMustafa Ismail
14523f49d684SMustafa Ismail set_64bit_val(wqe, 0, 0);
14533f49d684SMustafa Ismail set_64bit_val(wqe, 16, 0);
14543f49d684SMustafa Ismail if (read) {
14553f49d684SMustafa Ismail if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) {
14563f49d684SMustafa Ismail set_64bit_val(wqe, 8,
14573f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_STAG, 0xabcd));
14583f49d684SMustafa Ismail } else {
14593f49d684SMustafa Ismail set_64bit_val(wqe, 8,
14603f49d684SMustafa Ismail (u64)0xabcd | FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity));
14613f49d684SMustafa Ismail }
14623f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, 0x1234) |
14633f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_RDMA_READ) |
14643f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity);
14653f49d684SMustafa Ismail
14663f49d684SMustafa Ismail } else {
14673f49d684SMustafa Ismail if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) {
14683f49d684SMustafa Ismail set_64bit_val(wqe, 8, 0);
14693f49d684SMustafa Ismail } else {
14703f49d684SMustafa Ismail set_64bit_val(wqe, 8,
14713f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity));
14723f49d684SMustafa Ismail }
14733f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_RDMA_WRITE) |
14743f49d684SMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity);
14753f49d684SMustafa Ismail }
14763f49d684SMustafa Ismail
14773f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
14783f49d684SMustafa Ismail
14793f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
14803f49d684SMustafa Ismail
14813f49d684SMustafa Ismail print_hex_dump_debug("WQE: RTR WQE", DUMP_PREFIX_OFFSET, 16, 8, wqe,
14823f49d684SMustafa Ismail IRDMA_QP_WQE_MIN_SIZE, false);
14833f49d684SMustafa Ismail
14843f49d684SMustafa Ismail if (qp->dev->hw_attrs.uk_attrs.feature_flags & IRDMA_FEATURE_RTS_AE)
14853f49d684SMustafa Ismail irdma_sc_gen_rts_ae(qp);
14863f49d684SMustafa Ismail }
14873f49d684SMustafa Ismail
14883f49d684SMustafa Ismail /**
14893f49d684SMustafa Ismail * irdma_iwarp_opcode - determine if incoming is rdma layer
14903f49d684SMustafa Ismail * @info: aeq info for the packet
14913f49d684SMustafa Ismail * @pkt: packet for error
14923f49d684SMustafa Ismail */
irdma_iwarp_opcode(struct irdma_aeqe_info * info,u8 * pkt)14933f49d684SMustafa Ismail static u32 irdma_iwarp_opcode(struct irdma_aeqe_info *info, u8 *pkt)
14943f49d684SMustafa Ismail {
14953f49d684SMustafa Ismail __be16 *mpa;
14963f49d684SMustafa Ismail u32 opcode = 0xffffffff;
14973f49d684SMustafa Ismail
14983f49d684SMustafa Ismail if (info->q2_data_written) {
14993f49d684SMustafa Ismail mpa = (__be16 *)pkt;
15003f49d684SMustafa Ismail opcode = ntohs(mpa[1]) & 0xf;
15013f49d684SMustafa Ismail }
15023f49d684SMustafa Ismail
15033f49d684SMustafa Ismail return opcode;
15043f49d684SMustafa Ismail }
15053f49d684SMustafa Ismail
15063f49d684SMustafa Ismail /**
15073f49d684SMustafa Ismail * irdma_locate_mpa - return pointer to mpa in the pkt
15083f49d684SMustafa Ismail * @pkt: packet with data
15093f49d684SMustafa Ismail */
irdma_locate_mpa(u8 * pkt)15103f49d684SMustafa Ismail static u8 *irdma_locate_mpa(u8 *pkt)
15113f49d684SMustafa Ismail {
15123f49d684SMustafa Ismail /* skip over ethernet header */
15133f49d684SMustafa Ismail pkt += IRDMA_MAC_HLEN;
15143f49d684SMustafa Ismail
15153f49d684SMustafa Ismail /* Skip over IP and TCP headers */
15163f49d684SMustafa Ismail pkt += 4 * (pkt[0] & 0x0f);
15173f49d684SMustafa Ismail pkt += 4 * ((pkt[12] >> 4) & 0x0f);
15183f49d684SMustafa Ismail
15193f49d684SMustafa Ismail return pkt;
15203f49d684SMustafa Ismail }
15213f49d684SMustafa Ismail
15223f49d684SMustafa Ismail /**
15233f49d684SMustafa Ismail * irdma_bld_termhdr_ctrl - setup terminate hdr control fields
15243f49d684SMustafa Ismail * @qp: sc qp ptr for pkt
15253f49d684SMustafa Ismail * @hdr: term hdr
15263f49d684SMustafa Ismail * @opcode: flush opcode for termhdr
15273f49d684SMustafa Ismail * @layer_etype: error layer + error type
15283f49d684SMustafa Ismail * @err: error cod ein the header
15293f49d684SMustafa Ismail */
irdma_bld_termhdr_ctrl(struct irdma_sc_qp * qp,struct irdma_terminate_hdr * hdr,enum irdma_flush_opcode opcode,u8 layer_etype,u8 err)15303f49d684SMustafa Ismail static void irdma_bld_termhdr_ctrl(struct irdma_sc_qp *qp,
15313f49d684SMustafa Ismail struct irdma_terminate_hdr *hdr,
15323f49d684SMustafa Ismail enum irdma_flush_opcode opcode,
15333f49d684SMustafa Ismail u8 layer_etype, u8 err)
15343f49d684SMustafa Ismail {
15353f49d684SMustafa Ismail qp->flush_code = opcode;
15363f49d684SMustafa Ismail hdr->layer_etype = layer_etype;
15373f49d684SMustafa Ismail hdr->error_code = err;
15383f49d684SMustafa Ismail }
15393f49d684SMustafa Ismail
15403f49d684SMustafa Ismail /**
15413f49d684SMustafa Ismail * irdma_bld_termhdr_ddp_rdma - setup ddp and rdma hdrs in terminate hdr
15423f49d684SMustafa Ismail * @pkt: ptr to mpa in offending pkt
15433f49d684SMustafa Ismail * @hdr: term hdr
15443f49d684SMustafa Ismail * @copy_len: offending pkt length to be copied to term hdr
15453f49d684SMustafa Ismail * @is_tagged: DDP tagged or untagged
15463f49d684SMustafa Ismail */
irdma_bld_termhdr_ddp_rdma(u8 * pkt,struct irdma_terminate_hdr * hdr,int * copy_len,u8 * is_tagged)15473f49d684SMustafa Ismail static void irdma_bld_termhdr_ddp_rdma(u8 *pkt, struct irdma_terminate_hdr *hdr,
15483f49d684SMustafa Ismail int *copy_len, u8 *is_tagged)
15493f49d684SMustafa Ismail {
15503f49d684SMustafa Ismail u16 ddp_seg_len;
15513f49d684SMustafa Ismail
15523f49d684SMustafa Ismail ddp_seg_len = ntohs(*(__be16 *)pkt);
15533f49d684SMustafa Ismail if (ddp_seg_len) {
15543f49d684SMustafa Ismail *copy_len = 2;
15553f49d684SMustafa Ismail hdr->hdrct = DDP_LEN_FLAG;
15563f49d684SMustafa Ismail if (pkt[2] & 0x80) {
15573f49d684SMustafa Ismail *is_tagged = 1;
15583f49d684SMustafa Ismail if (ddp_seg_len >= TERM_DDP_LEN_TAGGED) {
15593f49d684SMustafa Ismail *copy_len += TERM_DDP_LEN_TAGGED;
15603f49d684SMustafa Ismail hdr->hdrct |= DDP_HDR_FLAG;
15613f49d684SMustafa Ismail }
15623f49d684SMustafa Ismail } else {
15633f49d684SMustafa Ismail if (ddp_seg_len >= TERM_DDP_LEN_UNTAGGED) {
15643f49d684SMustafa Ismail *copy_len += TERM_DDP_LEN_UNTAGGED;
15653f49d684SMustafa Ismail hdr->hdrct |= DDP_HDR_FLAG;
15663f49d684SMustafa Ismail }
15673f49d684SMustafa Ismail if (ddp_seg_len >= (TERM_DDP_LEN_UNTAGGED + TERM_RDMA_LEN) &&
15683f49d684SMustafa Ismail ((pkt[3] & RDMA_OPCODE_M) == RDMA_READ_REQ_OPCODE)) {
15693f49d684SMustafa Ismail *copy_len += TERM_RDMA_LEN;
15703f49d684SMustafa Ismail hdr->hdrct |= RDMA_HDR_FLAG;
15713f49d684SMustafa Ismail }
15723f49d684SMustafa Ismail }
15733f49d684SMustafa Ismail }
15743f49d684SMustafa Ismail }
15753f49d684SMustafa Ismail
15763f49d684SMustafa Ismail /**
15773f49d684SMustafa Ismail * irdma_bld_terminate_hdr - build terminate message header
15783f49d684SMustafa Ismail * @qp: qp associated with received terminate AE
15793f49d684SMustafa Ismail * @info: the struct contiaing AE information
15803f49d684SMustafa Ismail */
irdma_bld_terminate_hdr(struct irdma_sc_qp * qp,struct irdma_aeqe_info * info)15813f49d684SMustafa Ismail static int irdma_bld_terminate_hdr(struct irdma_sc_qp *qp,
15823f49d684SMustafa Ismail struct irdma_aeqe_info *info)
15833f49d684SMustafa Ismail {
15843f49d684SMustafa Ismail u8 *pkt = qp->q2_buf + Q2_BAD_FRAME_OFFSET;
15853f49d684SMustafa Ismail int copy_len = 0;
15863f49d684SMustafa Ismail u8 is_tagged = 0;
15873f49d684SMustafa Ismail u32 opcode;
15883f49d684SMustafa Ismail struct irdma_terminate_hdr *termhdr;
15893f49d684SMustafa Ismail
15903f49d684SMustafa Ismail termhdr = (struct irdma_terminate_hdr *)qp->q2_buf;
15913f49d684SMustafa Ismail memset(termhdr, 0, Q2_BAD_FRAME_OFFSET);
15923f49d684SMustafa Ismail
15933f49d684SMustafa Ismail if (info->q2_data_written) {
15943f49d684SMustafa Ismail pkt = irdma_locate_mpa(pkt);
15953f49d684SMustafa Ismail irdma_bld_termhdr_ddp_rdma(pkt, termhdr, ©_len, &is_tagged);
15963f49d684SMustafa Ismail }
15973f49d684SMustafa Ismail
15983f49d684SMustafa Ismail opcode = irdma_iwarp_opcode(info, pkt);
15993f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
16003f49d684SMustafa Ismail qp->sq_flush_code = info->sq;
16013f49d684SMustafa Ismail qp->rq_flush_code = info->rq;
16023f49d684SMustafa Ismail
16033f49d684SMustafa Ismail switch (info->ae_id) {
16043f49d684SMustafa Ismail case IRDMA_AE_AMP_UNALLOCATED_STAG:
16053f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
16063f49d684SMustafa Ismail if (opcode == IRDMA_OP_TYPE_RDMA_WRITE)
16073f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR,
16083f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_TAGGED_BUF,
16093f49d684SMustafa Ismail DDP_TAGGED_INV_STAG);
16103f49d684SMustafa Ismail else
16113f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
16123f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
16133f49d684SMustafa Ismail RDMAP_INV_STAG);
16143f49d684SMustafa Ismail break;
16153f49d684SMustafa Ismail case IRDMA_AE_AMP_BOUNDS_VIOLATION:
16163f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
16173f49d684SMustafa Ismail if (info->q2_data_written)
16183f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR,
16193f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_TAGGED_BUF,
16203f49d684SMustafa Ismail DDP_TAGGED_BOUNDS);
16213f49d684SMustafa Ismail else
16223f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
16233f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
16243f49d684SMustafa Ismail RDMAP_INV_BOUNDS);
16253f49d684SMustafa Ismail break;
16263f49d684SMustafa Ismail case IRDMA_AE_AMP_BAD_PD:
16273f49d684SMustafa Ismail switch (opcode) {
16283f49d684SMustafa Ismail case IRDMA_OP_TYPE_RDMA_WRITE:
16293f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR,
16303f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_TAGGED_BUF,
16313f49d684SMustafa Ismail DDP_TAGGED_UNASSOC_STAG);
16323f49d684SMustafa Ismail break;
16333f49d684SMustafa Ismail case IRDMA_OP_TYPE_SEND_INV:
16343f49d684SMustafa Ismail case IRDMA_OP_TYPE_SEND_SOL_INV:
16353f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
16363f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
16373f49d684SMustafa Ismail RDMAP_CANT_INV_STAG);
16383f49d684SMustafa Ismail break;
16393f49d684SMustafa Ismail default:
16403f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
16413f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
16423f49d684SMustafa Ismail RDMAP_UNASSOC_STAG);
16433f49d684SMustafa Ismail }
16443f49d684SMustafa Ismail break;
16453f49d684SMustafa Ismail case IRDMA_AE_AMP_INVALID_STAG:
16463f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
16473f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
16483f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
16493f49d684SMustafa Ismail RDMAP_INV_STAG);
16503f49d684SMustafa Ismail break;
16513f49d684SMustafa Ismail case IRDMA_AE_AMP_BAD_QP:
16523f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_QP_OP_ERR,
16533f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
16543f49d684SMustafa Ismail DDP_UNTAGGED_INV_QN);
16553f49d684SMustafa Ismail break;
16563f49d684SMustafa Ismail case IRDMA_AE_AMP_BAD_STAG_KEY:
16573f49d684SMustafa Ismail case IRDMA_AE_AMP_BAD_STAG_INDEX:
16583f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
16593f49d684SMustafa Ismail switch (opcode) {
16603f49d684SMustafa Ismail case IRDMA_OP_TYPE_SEND_INV:
16613f49d684SMustafa Ismail case IRDMA_OP_TYPE_SEND_SOL_INV:
16623f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_OP_ERR,
16633f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_OP,
16643f49d684SMustafa Ismail RDMAP_CANT_INV_STAG);
16653f49d684SMustafa Ismail break;
16663f49d684SMustafa Ismail default:
16673f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
16683f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_OP,
16693f49d684SMustafa Ismail RDMAP_INV_STAG);
16703f49d684SMustafa Ismail }
16713f49d684SMustafa Ismail break;
16723f49d684SMustafa Ismail case IRDMA_AE_AMP_RIGHTS_VIOLATION:
16733f49d684SMustafa Ismail case IRDMA_AE_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS:
16743f49d684SMustafa Ismail case IRDMA_AE_PRIV_OPERATION_DENIED:
16753f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
16763f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
16773f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
16783f49d684SMustafa Ismail RDMAP_ACCESS);
16793f49d684SMustafa Ismail break;
16803f49d684SMustafa Ismail case IRDMA_AE_AMP_TO_WRAP:
16813f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
16823f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
16833f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
16843f49d684SMustafa Ismail RDMAP_TO_WRAP);
16853f49d684SMustafa Ismail break;
16863f49d684SMustafa Ismail case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR:
16873f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
16883f49d684SMustafa Ismail (LAYER_MPA << 4) | DDP_LLP, MPA_CRC);
16893f49d684SMustafa Ismail break;
16903f49d684SMustafa Ismail case IRDMA_AE_LLP_SEGMENT_TOO_SMALL:
16913f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_LEN_ERR,
16923f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_CATASTROPHIC,
16933f49d684SMustafa Ismail DDP_CATASTROPHIC_LOCAL);
16943f49d684SMustafa Ismail break;
16953f49d684SMustafa Ismail case IRDMA_AE_LCE_QP_CATASTROPHIC:
16963f49d684SMustafa Ismail case IRDMA_AE_DDP_NO_L_BIT:
16973f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_FATAL_ERR,
16983f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_CATASTROPHIC,
16993f49d684SMustafa Ismail DDP_CATASTROPHIC_LOCAL);
17003f49d684SMustafa Ismail break;
17013f49d684SMustafa Ismail case IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN:
17023f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
17033f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
17043f49d684SMustafa Ismail DDP_UNTAGGED_INV_MSN_RANGE);
17053f49d684SMustafa Ismail break;
17063f49d684SMustafa Ismail case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
17073f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
17083f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_LEN_ERR,
17093f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
17103f49d684SMustafa Ismail DDP_UNTAGGED_INV_TOO_LONG);
17113f49d684SMustafa Ismail break;
17123f49d684SMustafa Ismail case IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION:
17133f49d684SMustafa Ismail if (is_tagged)
17143f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
17153f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_TAGGED_BUF,
17163f49d684SMustafa Ismail DDP_TAGGED_INV_DDP_VER);
17173f49d684SMustafa Ismail else
17183f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
17193f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
17203f49d684SMustafa Ismail DDP_UNTAGGED_INV_DDP_VER);
17213f49d684SMustafa Ismail break;
17223f49d684SMustafa Ismail case IRDMA_AE_DDP_UBE_INVALID_MO:
17233f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
17243f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
17253f49d684SMustafa Ismail DDP_UNTAGGED_INV_MO);
17263f49d684SMustafa Ismail break;
17273f49d684SMustafa Ismail case IRDMA_AE_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
17283f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_OP_ERR,
17293f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
17303f49d684SMustafa Ismail DDP_UNTAGGED_INV_MSN_NO_BUF);
17313f49d684SMustafa Ismail break;
17323f49d684SMustafa Ismail case IRDMA_AE_DDP_UBE_INVALID_QN:
17333f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
17343f49d684SMustafa Ismail (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
17353f49d684SMustafa Ismail DDP_UNTAGGED_INV_QN);
17363f49d684SMustafa Ismail break;
17373f49d684SMustafa Ismail case IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION:
17383f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
17393f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_OP,
17403f49d684SMustafa Ismail RDMAP_INV_RDMAP_VER);
17413f49d684SMustafa Ismail break;
17423f49d684SMustafa Ismail default:
17433f49d684SMustafa Ismail irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_FATAL_ERR,
17443f49d684SMustafa Ismail (LAYER_RDMA << 4) | RDMAP_REMOTE_OP,
17453f49d684SMustafa Ismail RDMAP_UNSPECIFIED);
17463f49d684SMustafa Ismail break;
17473f49d684SMustafa Ismail }
17483f49d684SMustafa Ismail
17493f49d684SMustafa Ismail if (copy_len)
17503f49d684SMustafa Ismail memcpy(termhdr + 1, pkt, copy_len);
17513f49d684SMustafa Ismail
17523f49d684SMustafa Ismail return sizeof(struct irdma_terminate_hdr) + copy_len;
17533f49d684SMustafa Ismail }
17543f49d684SMustafa Ismail
17553f49d684SMustafa Ismail /**
17563f49d684SMustafa Ismail * irdma_terminate_send_fin() - Send fin for terminate message
17573f49d684SMustafa Ismail * @qp: qp associated with received terminate AE
17583f49d684SMustafa Ismail */
irdma_terminate_send_fin(struct irdma_sc_qp * qp)17593f49d684SMustafa Ismail void irdma_terminate_send_fin(struct irdma_sc_qp *qp)
17603f49d684SMustafa Ismail {
17613f49d684SMustafa Ismail irdma_term_modify_qp(qp, IRDMA_QP_STATE_TERMINATE,
17623f49d684SMustafa Ismail IRDMAQP_TERM_SEND_FIN_ONLY, 0);
17633f49d684SMustafa Ismail }
17643f49d684SMustafa Ismail
17653f49d684SMustafa Ismail /**
17663f49d684SMustafa Ismail * irdma_terminate_connection() - Bad AE and send terminate to remote QP
17673f49d684SMustafa Ismail * @qp: qp associated with received terminate AE
17683f49d684SMustafa Ismail * @info: the struct contiaing AE information
17693f49d684SMustafa Ismail */
irdma_terminate_connection(struct irdma_sc_qp * qp,struct irdma_aeqe_info * info)17703f49d684SMustafa Ismail void irdma_terminate_connection(struct irdma_sc_qp *qp,
17713f49d684SMustafa Ismail struct irdma_aeqe_info *info)
17723f49d684SMustafa Ismail {
17733f49d684SMustafa Ismail u8 termlen = 0;
17743f49d684SMustafa Ismail
17753f49d684SMustafa Ismail if (qp->term_flags & IRDMA_TERM_SENT)
17763f49d684SMustafa Ismail return;
17773f49d684SMustafa Ismail
17783f49d684SMustafa Ismail termlen = irdma_bld_terminate_hdr(qp, info);
17793f49d684SMustafa Ismail irdma_terminate_start_timer(qp);
17803f49d684SMustafa Ismail qp->term_flags |= IRDMA_TERM_SENT;
17813f49d684SMustafa Ismail irdma_term_modify_qp(qp, IRDMA_QP_STATE_TERMINATE,
17823f49d684SMustafa Ismail IRDMAQP_TERM_SEND_TERM_ONLY, termlen);
17833f49d684SMustafa Ismail }
17843f49d684SMustafa Ismail
17853f49d684SMustafa Ismail /**
17863f49d684SMustafa Ismail * irdma_terminate_received - handle terminate received AE
17873f49d684SMustafa Ismail * @qp: qp associated with received terminate AE
17883f49d684SMustafa Ismail * @info: the struct contiaing AE information
17893f49d684SMustafa Ismail */
irdma_terminate_received(struct irdma_sc_qp * qp,struct irdma_aeqe_info * info)17903f49d684SMustafa Ismail void irdma_terminate_received(struct irdma_sc_qp *qp,
17913f49d684SMustafa Ismail struct irdma_aeqe_info *info)
17923f49d684SMustafa Ismail {
17933f49d684SMustafa Ismail u8 *pkt = qp->q2_buf + Q2_BAD_FRAME_OFFSET;
17943f49d684SMustafa Ismail __be32 *mpa;
17953f49d684SMustafa Ismail u8 ddp_ctl;
17963f49d684SMustafa Ismail u8 rdma_ctl;
17973f49d684SMustafa Ismail u16 aeq_id = 0;
17983f49d684SMustafa Ismail struct irdma_terminate_hdr *termhdr;
17993f49d684SMustafa Ismail
18003f49d684SMustafa Ismail mpa = (__be32 *)irdma_locate_mpa(pkt);
18013f49d684SMustafa Ismail if (info->q2_data_written) {
18023f49d684SMustafa Ismail /* did not validate the frame - do it now */
18033f49d684SMustafa Ismail ddp_ctl = (ntohl(mpa[0]) >> 8) & 0xff;
18043f49d684SMustafa Ismail rdma_ctl = ntohl(mpa[0]) & 0xff;
18053f49d684SMustafa Ismail if ((ddp_ctl & 0xc0) != 0x40)
18063f49d684SMustafa Ismail aeq_id = IRDMA_AE_LCE_QP_CATASTROPHIC;
18073f49d684SMustafa Ismail else if ((ddp_ctl & 0x03) != 1)
18083f49d684SMustafa Ismail aeq_id = IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION;
18093f49d684SMustafa Ismail else if (ntohl(mpa[2]) != 2)
18103f49d684SMustafa Ismail aeq_id = IRDMA_AE_DDP_UBE_INVALID_QN;
18113f49d684SMustafa Ismail else if (ntohl(mpa[3]) != 1)
18123f49d684SMustafa Ismail aeq_id = IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN;
18133f49d684SMustafa Ismail else if (ntohl(mpa[4]) != 0)
18143f49d684SMustafa Ismail aeq_id = IRDMA_AE_DDP_UBE_INVALID_MO;
18153f49d684SMustafa Ismail else if ((rdma_ctl & 0xc0) != 0x40)
18163f49d684SMustafa Ismail aeq_id = IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION;
18173f49d684SMustafa Ismail
18183f49d684SMustafa Ismail info->ae_id = aeq_id;
18193f49d684SMustafa Ismail if (info->ae_id) {
18203f49d684SMustafa Ismail /* Bad terminate recvd - send back a terminate */
18213f49d684SMustafa Ismail irdma_terminate_connection(qp, info);
18223f49d684SMustafa Ismail return;
18233f49d684SMustafa Ismail }
18243f49d684SMustafa Ismail }
18253f49d684SMustafa Ismail
18263f49d684SMustafa Ismail qp->term_flags |= IRDMA_TERM_RCVD;
18273f49d684SMustafa Ismail qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
18283f49d684SMustafa Ismail termhdr = (struct irdma_terminate_hdr *)&mpa[5];
18293f49d684SMustafa Ismail if (termhdr->layer_etype == RDMAP_REMOTE_PROT ||
18303f49d684SMustafa Ismail termhdr->layer_etype == RDMAP_REMOTE_OP) {
18313f49d684SMustafa Ismail irdma_terminate_done(qp, 0);
18323f49d684SMustafa Ismail } else {
18333f49d684SMustafa Ismail irdma_terminate_start_timer(qp);
18343f49d684SMustafa Ismail irdma_terminate_send_fin(qp);
18353f49d684SMustafa Ismail }
18363f49d684SMustafa Ismail }
18373f49d684SMustafa Ismail
irdma_null_ws_add(struct irdma_sc_vsi * vsi,u8 user_pri)18382c4b14eaSShiraz Saleem static int irdma_null_ws_add(struct irdma_sc_vsi *vsi, u8 user_pri)
18393f49d684SMustafa Ismail {
18403f49d684SMustafa Ismail return 0;
18413f49d684SMustafa Ismail }
18423f49d684SMustafa Ismail
irdma_null_ws_remove(struct irdma_sc_vsi * vsi,u8 user_pri)18433f49d684SMustafa Ismail static void irdma_null_ws_remove(struct irdma_sc_vsi *vsi, u8 user_pri)
18443f49d684SMustafa Ismail {
18453f49d684SMustafa Ismail /* do nothing */
18463f49d684SMustafa Ismail }
18473f49d684SMustafa Ismail
irdma_null_ws_reset(struct irdma_sc_vsi * vsi)18483f49d684SMustafa Ismail static void irdma_null_ws_reset(struct irdma_sc_vsi *vsi)
18493f49d684SMustafa Ismail {
18503f49d684SMustafa Ismail /* do nothing */
18513f49d684SMustafa Ismail }
18523f49d684SMustafa Ismail
18533f49d684SMustafa Ismail /**
18543f49d684SMustafa Ismail * irdma_sc_vsi_init - Init the vsi structure
18553f49d684SMustafa Ismail * @vsi: pointer to vsi structure to initialize
18563f49d684SMustafa Ismail * @info: the info used to initialize the vsi struct
18573f49d684SMustafa Ismail */
irdma_sc_vsi_init(struct irdma_sc_vsi * vsi,struct irdma_vsi_init_info * info)18583f49d684SMustafa Ismail void irdma_sc_vsi_init(struct irdma_sc_vsi *vsi,
18593f49d684SMustafa Ismail struct irdma_vsi_init_info *info)
18603f49d684SMustafa Ismail {
18613f49d684SMustafa Ismail int i;
18623f49d684SMustafa Ismail
18633f49d684SMustafa Ismail vsi->dev = info->dev;
18643f49d684SMustafa Ismail vsi->back_vsi = info->back_vsi;
18653f49d684SMustafa Ismail vsi->register_qset = info->register_qset;
18663f49d684SMustafa Ismail vsi->unregister_qset = info->unregister_qset;
18673f49d684SMustafa Ismail vsi->mtu = info->params->mtu;
18683f49d684SMustafa Ismail vsi->exception_lan_q = info->exception_lan_q;
18693f49d684SMustafa Ismail vsi->vsi_idx = info->pf_data_vsi_num;
18703f49d684SMustafa Ismail
187183483055SMustafa Ismail irdma_set_qos_info(vsi, info->params);
18723f49d684SMustafa Ismail for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
18733f49d684SMustafa Ismail mutex_init(&vsi->qos[i].qos_mutex);
18743f49d684SMustafa Ismail INIT_LIST_HEAD(&vsi->qos[i].qplist);
18753f49d684SMustafa Ismail }
18763f49d684SMustafa Ismail if (vsi->register_qset) {
18773f49d684SMustafa Ismail vsi->dev->ws_add = irdma_ws_add;
18783f49d684SMustafa Ismail vsi->dev->ws_remove = irdma_ws_remove;
18793f49d684SMustafa Ismail vsi->dev->ws_reset = irdma_ws_reset;
18803f49d684SMustafa Ismail } else {
18813f49d684SMustafa Ismail vsi->dev->ws_add = irdma_null_ws_add;
18823f49d684SMustafa Ismail vsi->dev->ws_remove = irdma_null_ws_remove;
18833f49d684SMustafa Ismail vsi->dev->ws_reset = irdma_null_ws_reset;
18843f49d684SMustafa Ismail }
18853f49d684SMustafa Ismail }
18863f49d684SMustafa Ismail
18873f49d684SMustafa Ismail /**
18885a711e58SKrzysztof Czurylo * irdma_get_stats_idx - Return stats index
18893f49d684SMustafa Ismail * @vsi: pointer to the vsi
18903f49d684SMustafa Ismail */
irdma_get_stats_idx(struct irdma_sc_vsi * vsi)18915a711e58SKrzysztof Czurylo static u8 irdma_get_stats_idx(struct irdma_sc_vsi *vsi)
18923f49d684SMustafa Ismail {
18933f49d684SMustafa Ismail struct irdma_stats_inst_info stats_info = {};
18943f49d684SMustafa Ismail struct irdma_sc_dev *dev = vsi->dev;
18955a711e58SKrzysztof Czurylo u8 i;
18963f49d684SMustafa Ismail
18975a711e58SKrzysztof Czurylo if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
18983f49d684SMustafa Ismail if (!irdma_cqp_stats_inst_cmd(vsi, IRDMA_OP_STATS_ALLOCATE,
18993f49d684SMustafa Ismail &stats_info))
19003f49d684SMustafa Ismail return stats_info.stats_idx;
19013f49d684SMustafa Ismail }
19023f49d684SMustafa Ismail
19035a711e58SKrzysztof Czurylo for (i = 0; i < IRDMA_MAX_STATS_COUNT_GEN_1; i++) {
19045a711e58SKrzysztof Czurylo if (!dev->stats_idx_array[i]) {
19055a711e58SKrzysztof Czurylo dev->stats_idx_array[i] = true;
19065a711e58SKrzysztof Czurylo return i;
19075a711e58SKrzysztof Czurylo }
19083f49d684SMustafa Ismail }
19093f49d684SMustafa Ismail
19105a711e58SKrzysztof Czurylo return IRDMA_INVALID_STATS_IDX;
19115a711e58SKrzysztof Czurylo }
19125a711e58SKrzysztof Czurylo
19135a711e58SKrzysztof Czurylo /**
19145a711e58SKrzysztof Czurylo * irdma_hw_stats_init_gen1 - Initialize stat reg table used for gen1
19155a711e58SKrzysztof Czurylo * @vsi: vsi structure where hw_regs are set
19165a711e58SKrzysztof Czurylo *
19175a711e58SKrzysztof Czurylo * Populate the HW stats table
19185a711e58SKrzysztof Czurylo */
irdma_hw_stats_init_gen1(struct irdma_sc_vsi * vsi)19195a711e58SKrzysztof Czurylo static void irdma_hw_stats_init_gen1(struct irdma_sc_vsi *vsi)
19205a711e58SKrzysztof Czurylo {
19215a711e58SKrzysztof Czurylo struct irdma_sc_dev *dev = vsi->dev;
19225a711e58SKrzysztof Czurylo const struct irdma_hw_stat_map *map;
19235a711e58SKrzysztof Czurylo u64 *stat_reg = vsi->hw_stats_regs;
19245a711e58SKrzysztof Czurylo u64 *regs = dev->hw_stats_regs;
19255a711e58SKrzysztof Czurylo u16 i, stats_reg_set = vsi->stats_idx;
19265a711e58SKrzysztof Czurylo
19275a711e58SKrzysztof Czurylo map = dev->hw_stats_map;
19285a711e58SKrzysztof Czurylo
19295a711e58SKrzysztof Czurylo /* First 4 stat instances are reserved for port level statistics. */
19305a711e58SKrzysztof Czurylo stats_reg_set += vsi->stats_inst_alloc ? IRDMA_FIRST_NON_PF_STAT : 0;
19315a711e58SKrzysztof Czurylo
19325a711e58SKrzysztof Czurylo for (i = 0; i < dev->hw_attrs.max_stat_idx; i++) {
19335a711e58SKrzysztof Czurylo if (map[i].bitmask <= IRDMA_MAX_STATS_32)
19345a711e58SKrzysztof Czurylo stat_reg[i] = regs[i] + stats_reg_set * sizeof(u32);
19355a711e58SKrzysztof Czurylo else
19365a711e58SKrzysztof Czurylo stat_reg[i] = regs[i] + stats_reg_set * sizeof(u64);
19375a711e58SKrzysztof Czurylo }
19383f49d684SMustafa Ismail }
19393f49d684SMustafa Ismail
19403f49d684SMustafa Ismail /**
19413f49d684SMustafa Ismail * irdma_vsi_stats_init - Initialize the vsi statistics
19423f49d684SMustafa Ismail * @vsi: pointer to the vsi structure
19433f49d684SMustafa Ismail * @info: The info structure used for initialization
19443f49d684SMustafa Ismail */
irdma_vsi_stats_init(struct irdma_sc_vsi * vsi,struct irdma_vsi_stats_info * info)19452c4b14eaSShiraz Saleem int irdma_vsi_stats_init(struct irdma_sc_vsi *vsi,
19463f49d684SMustafa Ismail struct irdma_vsi_stats_info *info)
19473f49d684SMustafa Ismail {
19483f49d684SMustafa Ismail struct irdma_dma_mem *stats_buff_mem;
19493f49d684SMustafa Ismail
19503f49d684SMustafa Ismail vsi->pestat = info->pestat;
19513f49d684SMustafa Ismail vsi->pestat->hw = vsi->dev->hw;
19523f49d684SMustafa Ismail vsi->pestat->vsi = vsi;
19533f49d684SMustafa Ismail stats_buff_mem = &vsi->pestat->gather_info.stats_buff_mem;
19543f49d684SMustafa Ismail stats_buff_mem->size = ALIGN(IRDMA_GATHER_STATS_BUF_SIZE * 2, 1);
19553f49d684SMustafa Ismail stats_buff_mem->va = dma_alloc_coherent(vsi->pestat->hw->device,
19563f49d684SMustafa Ismail stats_buff_mem->size,
19573f49d684SMustafa Ismail &stats_buff_mem->pa,
19583f49d684SMustafa Ismail GFP_KERNEL);
19593f49d684SMustafa Ismail if (!stats_buff_mem->va)
19602c4b14eaSShiraz Saleem return -ENOMEM;
19613f49d684SMustafa Ismail
19623f49d684SMustafa Ismail vsi->pestat->gather_info.gather_stats_va = stats_buff_mem->va;
19633f49d684SMustafa Ismail vsi->pestat->gather_info.last_gather_stats_va =
19643f49d684SMustafa Ismail (void *)((uintptr_t)stats_buff_mem->va +
19653f49d684SMustafa Ismail IRDMA_GATHER_STATS_BUF_SIZE);
19663f49d684SMustafa Ismail
19673f49d684SMustafa Ismail irdma_hw_stats_start_timer(vsi);
19683f49d684SMustafa Ismail
19695a711e58SKrzysztof Czurylo /* when stat allocation is not required default to fcn_id. */
19705a711e58SKrzysztof Czurylo vsi->stats_idx = info->fcn_id;
19715a711e58SKrzysztof Czurylo if (info->alloc_stats_inst) {
19725a711e58SKrzysztof Czurylo u8 stats_idx = irdma_get_stats_idx(vsi);
19735a711e58SKrzysztof Czurylo
19745a711e58SKrzysztof Czurylo if (stats_idx != IRDMA_INVALID_STATS_IDX) {
19755a711e58SKrzysztof Czurylo vsi->stats_inst_alloc = true;
19765a711e58SKrzysztof Czurylo vsi->stats_idx = stats_idx;
19773f49d684SMustafa Ismail vsi->pestat->gather_info.use_stats_inst = true;
19785a711e58SKrzysztof Czurylo vsi->pestat->gather_info.stats_inst_index = stats_idx;
19795a711e58SKrzysztof Czurylo }
19803f49d684SMustafa Ismail }
19813f49d684SMustafa Ismail
19825a711e58SKrzysztof Czurylo if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
19835a711e58SKrzysztof Czurylo irdma_hw_stats_init_gen1(vsi);
19845a711e58SKrzysztof Czurylo
19853f49d684SMustafa Ismail return 0;
19863f49d684SMustafa Ismail }
19873f49d684SMustafa Ismail
19883f49d684SMustafa Ismail /**
19893f49d684SMustafa Ismail * irdma_vsi_stats_free - Free the vsi stats
19903f49d684SMustafa Ismail * @vsi: pointer to the vsi structure
19913f49d684SMustafa Ismail */
irdma_vsi_stats_free(struct irdma_sc_vsi * vsi)19923f49d684SMustafa Ismail void irdma_vsi_stats_free(struct irdma_sc_vsi *vsi)
19933f49d684SMustafa Ismail {
19943f49d684SMustafa Ismail struct irdma_stats_inst_info stats_info = {};
19953f49d684SMustafa Ismail struct irdma_sc_dev *dev = vsi->dev;
19965a711e58SKrzysztof Czurylo u8 stats_idx = vsi->stats_idx;
19973f49d684SMustafa Ismail
19985a711e58SKrzysztof Czurylo if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
19995a711e58SKrzysztof Czurylo if (vsi->stats_inst_alloc) {
20005a711e58SKrzysztof Czurylo stats_info.stats_idx = vsi->stats_idx;
20013f49d684SMustafa Ismail irdma_cqp_stats_inst_cmd(vsi, IRDMA_OP_STATS_FREE,
20023f49d684SMustafa Ismail &stats_info);
20033f49d684SMustafa Ismail }
20043f49d684SMustafa Ismail } else {
20055a711e58SKrzysztof Czurylo if (vsi->stats_inst_alloc &&
20065a711e58SKrzysztof Czurylo stats_idx < vsi->dev->hw_attrs.max_stat_inst)
20075a711e58SKrzysztof Czurylo vsi->dev->stats_idx_array[stats_idx] = false;
20083f49d684SMustafa Ismail }
20093f49d684SMustafa Ismail
20103f49d684SMustafa Ismail if (!vsi->pestat)
20113f49d684SMustafa Ismail return;
20123f49d684SMustafa Ismail irdma_hw_stats_stop_timer(vsi);
20133f49d684SMustafa Ismail dma_free_coherent(vsi->pestat->hw->device,
20143f49d684SMustafa Ismail vsi->pestat->gather_info.stats_buff_mem.size,
20153f49d684SMustafa Ismail vsi->pestat->gather_info.stats_buff_mem.va,
20163f49d684SMustafa Ismail vsi->pestat->gather_info.stats_buff_mem.pa);
20173f49d684SMustafa Ismail vsi->pestat->gather_info.stats_buff_mem.va = NULL;
20183f49d684SMustafa Ismail }
20193f49d684SMustafa Ismail
20203f49d684SMustafa Ismail /**
20213f49d684SMustafa Ismail * irdma_get_encoded_wqe_size - given wq size, returns hardware encoded size
20223f49d684SMustafa Ismail * @wqsize: size of the wq (sq, rq) to encoded_size
20233f49d684SMustafa Ismail * @queue_type: queue type selected for the calculation algorithm
20243f49d684SMustafa Ismail */
irdma_get_encoded_wqe_size(u32 wqsize,enum irdma_queue_type queue_type)20253f49d684SMustafa Ismail u8 irdma_get_encoded_wqe_size(u32 wqsize, enum irdma_queue_type queue_type)
20263f49d684SMustafa Ismail {
20273f49d684SMustafa Ismail u8 encoded_size = 0;
20283f49d684SMustafa Ismail
20293f49d684SMustafa Ismail /* cqp sq's hw coded value starts from 1 for size of 4
20303f49d684SMustafa Ismail * while it starts from 0 for qp' wq's.
20313f49d684SMustafa Ismail */
20323f49d684SMustafa Ismail if (queue_type == IRDMA_QUEUE_TYPE_CQP)
20333f49d684SMustafa Ismail encoded_size = 1;
20343f49d684SMustafa Ismail wqsize >>= 2;
20353f49d684SMustafa Ismail while (wqsize >>= 1)
20363f49d684SMustafa Ismail encoded_size++;
20373f49d684SMustafa Ismail
20383f49d684SMustafa Ismail return encoded_size;
20393f49d684SMustafa Ismail }
20403f49d684SMustafa Ismail
20413f49d684SMustafa Ismail /**
20423f49d684SMustafa Ismail * irdma_sc_gather_stats - collect the statistics
20433f49d684SMustafa Ismail * @cqp: struct for cqp hw
20443f49d684SMustafa Ismail * @info: gather stats info structure
20453f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
20463f49d684SMustafa Ismail */
irdma_sc_gather_stats(struct irdma_sc_cqp * cqp,struct irdma_stats_gather_info * info,u64 scratch)20472c4b14eaSShiraz Saleem static int irdma_sc_gather_stats(struct irdma_sc_cqp *cqp,
20482c4b14eaSShiraz Saleem struct irdma_stats_gather_info *info,
20492c4b14eaSShiraz Saleem u64 scratch)
20503f49d684SMustafa Ismail {
20513f49d684SMustafa Ismail __le64 *wqe;
20523f49d684SMustafa Ismail u64 temp;
20533f49d684SMustafa Ismail
20543f49d684SMustafa Ismail if (info->stats_buff_mem.size < IRDMA_GATHER_STATS_BUF_SIZE)
20552c4b14eaSShiraz Saleem return -ENOMEM;
20563f49d684SMustafa Ismail
20573f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
20583f49d684SMustafa Ismail if (!wqe)
20592c4b14eaSShiraz Saleem return -ENOMEM;
20603f49d684SMustafa Ismail
20613f49d684SMustafa Ismail set_64bit_val(wqe, 40,
20623f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_HMC_FCN_INDEX, info->hmc_fcn_index));
20633f49d684SMustafa Ismail set_64bit_val(wqe, 32, info->stats_buff_mem.pa);
20643f49d684SMustafa Ismail
20653f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPSQ_STATS_WQEVALID, cqp->polarity) |
20663f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_USE_INST, info->use_stats_inst) |
20673f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_INST_INDEX,
20683f49d684SMustafa Ismail info->stats_inst_index) |
20693f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_USE_HMC_FCN_INDEX,
20703f49d684SMustafa Ismail info->use_hmc_fcn_index) |
20713f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_OP, IRDMA_CQP_OP_GATHER_STATS);
20723f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
20733f49d684SMustafa Ismail
20743f49d684SMustafa Ismail set_64bit_val(wqe, 24, temp);
20753f49d684SMustafa Ismail
20763f49d684SMustafa Ismail print_hex_dump_debug("STATS: GATHER_STATS WQE", DUMP_PREFIX_OFFSET,
20773f49d684SMustafa Ismail 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
20783f49d684SMustafa Ismail
20793f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
20803f49d684SMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev),
20813f49d684SMustafa Ismail "STATS: CQP SQ head 0x%x tail 0x%x size 0x%x\n",
20823f49d684SMustafa Ismail cqp->sq_ring.head, cqp->sq_ring.tail, cqp->sq_ring.size);
20833f49d684SMustafa Ismail
20843f49d684SMustafa Ismail return 0;
20853f49d684SMustafa Ismail }
20863f49d684SMustafa Ismail
20873f49d684SMustafa Ismail /**
20883f49d684SMustafa Ismail * irdma_sc_manage_stats_inst - allocate or free stats instance
20893f49d684SMustafa Ismail * @cqp: struct for cqp hw
20903f49d684SMustafa Ismail * @info: stats info structure
20913f49d684SMustafa Ismail * @alloc: alloc vs. delete flag
20923f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
20933f49d684SMustafa Ismail */
irdma_sc_manage_stats_inst(struct irdma_sc_cqp * cqp,struct irdma_stats_inst_info * info,bool alloc,u64 scratch)20942c4b14eaSShiraz Saleem static int irdma_sc_manage_stats_inst(struct irdma_sc_cqp *cqp,
20952c4b14eaSShiraz Saleem struct irdma_stats_inst_info *info,
20962c4b14eaSShiraz Saleem bool alloc, u64 scratch)
20973f49d684SMustafa Ismail {
20983f49d684SMustafa Ismail __le64 *wqe;
20993f49d684SMustafa Ismail u64 temp;
21003f49d684SMustafa Ismail
21013f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
21023f49d684SMustafa Ismail if (!wqe)
21032c4b14eaSShiraz Saleem return -ENOMEM;
21043f49d684SMustafa Ismail
21053f49d684SMustafa Ismail set_64bit_val(wqe, 40,
21063f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_HMC_FCN_INDEX, info->hmc_fn_id));
21073f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPSQ_STATS_WQEVALID, cqp->polarity) |
21083f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_ALLOC_INST, alloc) |
21093f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_USE_HMC_FCN_INDEX,
21103f49d684SMustafa Ismail info->use_hmc_fcn_index) |
21113f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_INST_INDEX, info->stats_idx) |
21123f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_STATS_OP, IRDMA_CQP_OP_MANAGE_STATS);
21133f49d684SMustafa Ismail
21143f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
21153f49d684SMustafa Ismail
21163f49d684SMustafa Ismail set_64bit_val(wqe, 24, temp);
21173f49d684SMustafa Ismail
21183f49d684SMustafa Ismail print_hex_dump_debug("WQE: MANAGE_STATS WQE", DUMP_PREFIX_OFFSET, 16,
21193f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
21203f49d684SMustafa Ismail
21213f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
21223f49d684SMustafa Ismail return 0;
21233f49d684SMustafa Ismail }
21243f49d684SMustafa Ismail
21253f49d684SMustafa Ismail /**
21263f49d684SMustafa Ismail * irdma_sc_set_up_map - set the up map table
21273f49d684SMustafa Ismail * @cqp: struct for cqp hw
21283f49d684SMustafa Ismail * @info: User priority map info
21293f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
21303f49d684SMustafa Ismail */
irdma_sc_set_up_map(struct irdma_sc_cqp * cqp,struct irdma_up_info * info,u64 scratch)21312c4b14eaSShiraz Saleem static int irdma_sc_set_up_map(struct irdma_sc_cqp *cqp,
21322c4b14eaSShiraz Saleem struct irdma_up_info *info, u64 scratch)
21333f49d684SMustafa Ismail {
21343f49d684SMustafa Ismail __le64 *wqe;
21353f49d684SMustafa Ismail u64 temp = 0;
21363f49d684SMustafa Ismail int i;
21373f49d684SMustafa Ismail
21383f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
21393f49d684SMustafa Ismail if (!wqe)
21402c4b14eaSShiraz Saleem return -ENOMEM;
21413f49d684SMustafa Ismail
21423f49d684SMustafa Ismail for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++)
21437fde2dbeSColin Ian King temp |= (u64)info->map[i] << (i * 8);
21443f49d684SMustafa Ismail
21453f49d684SMustafa Ismail set_64bit_val(wqe, 0, temp);
21463f49d684SMustafa Ismail set_64bit_val(wqe, 40,
21473f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UP_CNPOVERRIDE, info->cnp_up_override) |
21483f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UP_HMCFCNIDX, info->hmc_fcn_idx));
21493f49d684SMustafa Ismail
21503f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPSQ_UP_WQEVALID, cqp->polarity) |
21513f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UP_USEVLAN, info->use_vlan) |
21523f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UP_USEOVERRIDE,
21533f49d684SMustafa Ismail info->use_cnp_up_override) |
21543f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UP_OP, IRDMA_CQP_OP_UP_MAP);
21553f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
21563f49d684SMustafa Ismail
21573f49d684SMustafa Ismail set_64bit_val(wqe, 24, temp);
21583f49d684SMustafa Ismail
21593f49d684SMustafa Ismail print_hex_dump_debug("WQE: UPMAP WQE", DUMP_PREFIX_OFFSET, 16, 8, wqe,
21603f49d684SMustafa Ismail IRDMA_CQP_WQE_SIZE * 8, false);
21613f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
21623f49d684SMustafa Ismail
21633f49d684SMustafa Ismail return 0;
21643f49d684SMustafa Ismail }
21653f49d684SMustafa Ismail
21663f49d684SMustafa Ismail /**
21673f49d684SMustafa Ismail * irdma_sc_manage_ws_node - create/modify/destroy WS node
21683f49d684SMustafa Ismail * @cqp: struct for cqp hw
21693f49d684SMustafa Ismail * @info: node info structure
21703f49d684SMustafa Ismail * @node_op: 0 for add 1 for modify, 2 for delete
21713f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
21723f49d684SMustafa Ismail */
irdma_sc_manage_ws_node(struct irdma_sc_cqp * cqp,struct irdma_ws_node_info * info,enum irdma_ws_node_op node_op,u64 scratch)21732c4b14eaSShiraz Saleem static int irdma_sc_manage_ws_node(struct irdma_sc_cqp *cqp,
21743f49d684SMustafa Ismail struct irdma_ws_node_info *info,
21753f49d684SMustafa Ismail enum irdma_ws_node_op node_op, u64 scratch)
21763f49d684SMustafa Ismail {
21773f49d684SMustafa Ismail __le64 *wqe;
21783f49d684SMustafa Ismail u64 temp = 0;
21793f49d684SMustafa Ismail
21803f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
21813f49d684SMustafa Ismail if (!wqe)
21822c4b14eaSShiraz Saleem return -ENOMEM;
21833f49d684SMustafa Ismail
21843f49d684SMustafa Ismail set_64bit_val(wqe, 32,
21853f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_VSI, info->vsi) |
21863f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_WEIGHT, info->weight));
21873f49d684SMustafa Ismail
21883f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPSQ_WS_WQEVALID, cqp->polarity) |
21893f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_NODEOP, node_op) |
21903f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_ENABLENODE, info->enable) |
21913f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_NODETYPE, info->type_leaf) |
21923f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_PRIOTYPE, info->prio_type) |
21933f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_TC, info->tc) |
21943f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_OP, IRDMA_CQP_OP_WORK_SCHED_NODE) |
21953f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_PARENTID, info->parent_id) |
21963f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WS_NODEID, info->id);
21973f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
21983f49d684SMustafa Ismail
21993f49d684SMustafa Ismail set_64bit_val(wqe, 24, temp);
22003f49d684SMustafa Ismail
22013f49d684SMustafa Ismail print_hex_dump_debug("WQE: MANAGE_WS WQE", DUMP_PREFIX_OFFSET, 16, 8,
22023f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
22033f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
22043f49d684SMustafa Ismail
22053f49d684SMustafa Ismail return 0;
22063f49d684SMustafa Ismail }
22073f49d684SMustafa Ismail
22083f49d684SMustafa Ismail /**
22093f49d684SMustafa Ismail * irdma_sc_qp_flush_wqes - flush qp's wqe
22103f49d684SMustafa Ismail * @qp: sc qp
22113f49d684SMustafa Ismail * @info: dlush information
22123f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
22133f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
22143f49d684SMustafa Ismail */
irdma_sc_qp_flush_wqes(struct irdma_sc_qp * qp,struct irdma_qp_flush_info * info,u64 scratch,bool post_sq)22152c4b14eaSShiraz Saleem int irdma_sc_qp_flush_wqes(struct irdma_sc_qp *qp,
22162c4b14eaSShiraz Saleem struct irdma_qp_flush_info *info, u64 scratch,
22172c4b14eaSShiraz Saleem bool post_sq)
22183f49d684SMustafa Ismail {
22193f49d684SMustafa Ismail u64 temp = 0;
22203f49d684SMustafa Ismail __le64 *wqe;
22213f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
22223f49d684SMustafa Ismail u64 hdr;
22233f49d684SMustafa Ismail bool flush_sq = false, flush_rq = false;
22243f49d684SMustafa Ismail
22253f49d684SMustafa Ismail if (info->rq && !qp->flush_rq)
22263f49d684SMustafa Ismail flush_rq = true;
22273f49d684SMustafa Ismail if (info->sq && !qp->flush_sq)
22283f49d684SMustafa Ismail flush_sq = true;
22293f49d684SMustafa Ismail qp->flush_sq |= flush_sq;
22303f49d684SMustafa Ismail qp->flush_rq |= flush_rq;
22313f49d684SMustafa Ismail
22323f49d684SMustafa Ismail if (!flush_sq && !flush_rq) {
22333f49d684SMustafa Ismail ibdev_dbg(to_ibdev(qp->dev),
22343f49d684SMustafa Ismail "CQP: Additional flush request ignored for qp %x\n",
22353f49d684SMustafa Ismail qp->qp_uk.qp_id);
22362c4b14eaSShiraz Saleem return -EALREADY;
22373f49d684SMustafa Ismail }
22383f49d684SMustafa Ismail
22393f49d684SMustafa Ismail cqp = qp->pd->dev->cqp;
22403f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
22413f49d684SMustafa Ismail if (!wqe)
22422c4b14eaSShiraz Saleem return -ENOMEM;
22433f49d684SMustafa Ismail
22443f49d684SMustafa Ismail if (info->userflushcode) {
22453f49d684SMustafa Ismail if (flush_rq)
22463f49d684SMustafa Ismail temp |= FIELD_PREP(IRDMA_CQPSQ_FWQE_RQMNERR,
22473f49d684SMustafa Ismail info->rq_minor_code) |
22483f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_FWQE_RQMJERR,
22493f49d684SMustafa Ismail info->rq_major_code);
22503f49d684SMustafa Ismail if (flush_sq)
22513f49d684SMustafa Ismail temp |= FIELD_PREP(IRDMA_CQPSQ_FWQE_SQMNERR,
22523f49d684SMustafa Ismail info->sq_minor_code) |
22533f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_FWQE_SQMJERR,
22543f49d684SMustafa Ismail info->sq_major_code);
22553f49d684SMustafa Ismail }
22563f49d684SMustafa Ismail set_64bit_val(wqe, 16, temp);
22573f49d684SMustafa Ismail
22583f49d684SMustafa Ismail temp = (info->generate_ae) ?
22593f49d684SMustafa Ismail info->ae_code | FIELD_PREP(IRDMA_CQPSQ_FWQE_AESOURCE,
22603f49d684SMustafa Ismail info->ae_src) : 0;
22613f49d684SMustafa Ismail set_64bit_val(wqe, 8, temp);
22623f49d684SMustafa Ismail
22633f49d684SMustafa Ismail hdr = qp->qp_uk.qp_id |
22643f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_FLUSH_WQES) |
22653f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_FWQE_GENERATE_AE, info->generate_ae) |
22663f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_FWQE_USERFLCODE, info->userflushcode) |
22673f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_FWQE_FLUSHSQ, flush_sq) |
22683f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_FWQE_FLUSHRQ, flush_rq) |
22693f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
22703f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
22713f49d684SMustafa Ismail
22723f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
22733f49d684SMustafa Ismail
22743f49d684SMustafa Ismail print_hex_dump_debug("WQE: QP_FLUSH WQE", DUMP_PREFIX_OFFSET, 16, 8,
22753f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
22763f49d684SMustafa Ismail if (post_sq)
22773f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
22783f49d684SMustafa Ismail
22793f49d684SMustafa Ismail return 0;
22803f49d684SMustafa Ismail }
22813f49d684SMustafa Ismail
22823f49d684SMustafa Ismail /**
22833f49d684SMustafa Ismail * irdma_sc_gen_ae - generate AE, uses flush WQE CQP OP
22843f49d684SMustafa Ismail * @qp: sc qp
22853f49d684SMustafa Ismail * @info: gen ae information
22863f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
22873f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
22883f49d684SMustafa Ismail */
irdma_sc_gen_ae(struct irdma_sc_qp * qp,struct irdma_gen_ae_info * info,u64 scratch,bool post_sq)22892c4b14eaSShiraz Saleem static int irdma_sc_gen_ae(struct irdma_sc_qp *qp,
22902c4b14eaSShiraz Saleem struct irdma_gen_ae_info *info, u64 scratch,
22912c4b14eaSShiraz Saleem bool post_sq)
22923f49d684SMustafa Ismail {
22933f49d684SMustafa Ismail u64 temp;
22943f49d684SMustafa Ismail __le64 *wqe;
22953f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
22963f49d684SMustafa Ismail u64 hdr;
22973f49d684SMustafa Ismail
22983f49d684SMustafa Ismail cqp = qp->pd->dev->cqp;
22993f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
23003f49d684SMustafa Ismail if (!wqe)
23012c4b14eaSShiraz Saleem return -ENOMEM;
23023f49d684SMustafa Ismail
23033f49d684SMustafa Ismail temp = info->ae_code | FIELD_PREP(IRDMA_CQPSQ_FWQE_AESOURCE,
23043f49d684SMustafa Ismail info->ae_src);
23053f49d684SMustafa Ismail set_64bit_val(wqe, 8, temp);
23063f49d684SMustafa Ismail
23073f49d684SMustafa Ismail hdr = qp->qp_uk.qp_id | FIELD_PREP(IRDMA_CQPSQ_OPCODE,
23083f49d684SMustafa Ismail IRDMA_CQP_OP_GEN_AE) |
23093f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_FWQE_GENERATE_AE, 1) |
23103f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
23113f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
23123f49d684SMustafa Ismail
23133f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
23143f49d684SMustafa Ismail
23153f49d684SMustafa Ismail print_hex_dump_debug("WQE: GEN_AE WQE", DUMP_PREFIX_OFFSET, 16, 8,
23163f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
23173f49d684SMustafa Ismail if (post_sq)
23183f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
23193f49d684SMustafa Ismail
23203f49d684SMustafa Ismail return 0;
23213f49d684SMustafa Ismail }
23223f49d684SMustafa Ismail
23233f49d684SMustafa Ismail /*** irdma_sc_qp_upload_context - upload qp's context
23243f49d684SMustafa Ismail * @dev: sc device struct
23253f49d684SMustafa Ismail * @info: upload context info ptr for return
23263f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
23273f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
23283f49d684SMustafa Ismail */
irdma_sc_qp_upload_context(struct irdma_sc_dev * dev,struct irdma_upload_context_info * info,u64 scratch,bool post_sq)23292c4b14eaSShiraz Saleem static int irdma_sc_qp_upload_context(struct irdma_sc_dev *dev,
23302c4b14eaSShiraz Saleem struct irdma_upload_context_info *info,
23312c4b14eaSShiraz Saleem u64 scratch, bool post_sq)
23323f49d684SMustafa Ismail {
23333f49d684SMustafa Ismail __le64 *wqe;
23343f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
23353f49d684SMustafa Ismail u64 hdr;
23363f49d684SMustafa Ismail
23373f49d684SMustafa Ismail cqp = dev->cqp;
23383f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
23393f49d684SMustafa Ismail if (!wqe)
23402c4b14eaSShiraz Saleem return -ENOMEM;
23413f49d684SMustafa Ismail
23423f49d684SMustafa Ismail set_64bit_val(wqe, 16, info->buf_pa);
23433f49d684SMustafa Ismail
23443f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_UCTX_QPID, info->qp_id) |
23453f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_UPLOAD_CONTEXT) |
23463f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UCTX_QPTYPE, info->qp_type) |
23473f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UCTX_RAWFORMAT, info->raw_format) |
23483f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UCTX_FREEZEQP, info->freeze_qp) |
23493f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
23503f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
23513f49d684SMustafa Ismail
23523f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
23533f49d684SMustafa Ismail
23543f49d684SMustafa Ismail print_hex_dump_debug("WQE: QP_UPLOAD_CTX WQE", DUMP_PREFIX_OFFSET, 16,
23553f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
23563f49d684SMustafa Ismail if (post_sq)
23573f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
23583f49d684SMustafa Ismail
23593f49d684SMustafa Ismail return 0;
23603f49d684SMustafa Ismail }
23613f49d684SMustafa Ismail
23623f49d684SMustafa Ismail /**
23633f49d684SMustafa Ismail * irdma_sc_manage_push_page - Handle push page
23643f49d684SMustafa Ismail * @cqp: struct for cqp hw
23653f49d684SMustafa Ismail * @info: push page info
23663f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
23673f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
23683f49d684SMustafa Ismail */
irdma_sc_manage_push_page(struct irdma_sc_cqp * cqp,struct irdma_cqp_manage_push_page_info * info,u64 scratch,bool post_sq)23692c4b14eaSShiraz Saleem static int irdma_sc_manage_push_page(struct irdma_sc_cqp *cqp,
23703f49d684SMustafa Ismail struct irdma_cqp_manage_push_page_info *info,
23713f49d684SMustafa Ismail u64 scratch, bool post_sq)
23723f49d684SMustafa Ismail {
23733f49d684SMustafa Ismail __le64 *wqe;
23743f49d684SMustafa Ismail u64 hdr;
23753f49d684SMustafa Ismail
23763f49d684SMustafa Ismail if (info->free_page &&
23773f49d684SMustafa Ismail info->push_idx >= cqp->dev->hw_attrs.max_hw_device_pages)
23782c4b14eaSShiraz Saleem return -EINVAL;
23793f49d684SMustafa Ismail
23803f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
23813f49d684SMustafa Ismail if (!wqe)
23822c4b14eaSShiraz Saleem return -ENOMEM;
23833f49d684SMustafa Ismail
23843f49d684SMustafa Ismail set_64bit_val(wqe, 16, info->qs_handle);
23853f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_MPP_PPIDX, info->push_idx) |
23863f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_MPP_PPTYPE, info->push_page_type) |
23873f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MANAGE_PUSH_PAGES) |
23883f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity) |
23893f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_MPP_FREE_PAGE, info->free_page);
23903f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
23913f49d684SMustafa Ismail
23923f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
23933f49d684SMustafa Ismail
23943f49d684SMustafa Ismail print_hex_dump_debug("WQE: MANAGE_PUSH_PAGES WQE", DUMP_PREFIX_OFFSET,
23953f49d684SMustafa Ismail 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
23963f49d684SMustafa Ismail if (post_sq)
23973f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
23983f49d684SMustafa Ismail
23993f49d684SMustafa Ismail return 0;
24003f49d684SMustafa Ismail }
24013f49d684SMustafa Ismail
24023f49d684SMustafa Ismail /**
24033f49d684SMustafa Ismail * irdma_sc_suspend_qp - suspend qp for param change
24043f49d684SMustafa Ismail * @cqp: struct for cqp hw
24053f49d684SMustafa Ismail * @qp: sc qp struct
24063f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
24073f49d684SMustafa Ismail */
irdma_sc_suspend_qp(struct irdma_sc_cqp * cqp,struct irdma_sc_qp * qp,u64 scratch)24082c4b14eaSShiraz Saleem static int irdma_sc_suspend_qp(struct irdma_sc_cqp *cqp, struct irdma_sc_qp *qp,
24093f49d684SMustafa Ismail u64 scratch)
24103f49d684SMustafa Ismail {
24113f49d684SMustafa Ismail u64 hdr;
24123f49d684SMustafa Ismail __le64 *wqe;
24133f49d684SMustafa Ismail
24143f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
24153f49d684SMustafa Ismail if (!wqe)
24162c4b14eaSShiraz Saleem return -ENOMEM;
24173f49d684SMustafa Ismail
24183f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_SUSPENDQP_QPID, qp->qp_uk.qp_id) |
24193f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_SUSPEND_QP) |
24203f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
24213f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
24223f49d684SMustafa Ismail
24233f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
24243f49d684SMustafa Ismail
24253f49d684SMustafa Ismail print_hex_dump_debug("WQE: SUSPEND_QP WQE", DUMP_PREFIX_OFFSET, 16, 8,
24263f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
24273f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
24283f49d684SMustafa Ismail
24293f49d684SMustafa Ismail return 0;
24303f49d684SMustafa Ismail }
24313f49d684SMustafa Ismail
24323f49d684SMustafa Ismail /**
24333f49d684SMustafa Ismail * irdma_sc_resume_qp - resume qp after suspend
24343f49d684SMustafa Ismail * @cqp: struct for cqp hw
24353f49d684SMustafa Ismail * @qp: sc qp struct
24363f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
24373f49d684SMustafa Ismail */
irdma_sc_resume_qp(struct irdma_sc_cqp * cqp,struct irdma_sc_qp * qp,u64 scratch)24382c4b14eaSShiraz Saleem static int irdma_sc_resume_qp(struct irdma_sc_cqp *cqp, struct irdma_sc_qp *qp,
24393f49d684SMustafa Ismail u64 scratch)
24403f49d684SMustafa Ismail {
24413f49d684SMustafa Ismail u64 hdr;
24423f49d684SMustafa Ismail __le64 *wqe;
24433f49d684SMustafa Ismail
24443f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
24453f49d684SMustafa Ismail if (!wqe)
24462c4b14eaSShiraz Saleem return -ENOMEM;
24473f49d684SMustafa Ismail
24483f49d684SMustafa Ismail set_64bit_val(wqe, 16,
24493f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_RESUMEQP_QSHANDLE, qp->qs_handle));
24503f49d684SMustafa Ismail
24513f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_RESUMEQP_QPID, qp->qp_uk.qp_id) |
24523f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_RESUME_QP) |
24533f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
24543f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
24553f49d684SMustafa Ismail
24563f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
24573f49d684SMustafa Ismail
24583f49d684SMustafa Ismail print_hex_dump_debug("WQE: RESUME_QP WQE", DUMP_PREFIX_OFFSET, 16, 8,
24593f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
24603f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
24613f49d684SMustafa Ismail
24623f49d684SMustafa Ismail return 0;
24633f49d684SMustafa Ismail }
24643f49d684SMustafa Ismail
24653f49d684SMustafa Ismail /**
24663f49d684SMustafa Ismail * irdma_sc_cq_ack - acknowledge completion q
24673f49d684SMustafa Ismail * @cq: cq struct
24683f49d684SMustafa Ismail */
irdma_sc_cq_ack(struct irdma_sc_cq * cq)24693f49d684SMustafa Ismail static inline void irdma_sc_cq_ack(struct irdma_sc_cq *cq)
24703f49d684SMustafa Ismail {
24713f49d684SMustafa Ismail writel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);
24723f49d684SMustafa Ismail }
24733f49d684SMustafa Ismail
24743f49d684SMustafa Ismail /**
24753f49d684SMustafa Ismail * irdma_sc_cq_init - initialize completion q
24763f49d684SMustafa Ismail * @cq: cq struct
24773f49d684SMustafa Ismail * @info: cq initialization info
24783f49d684SMustafa Ismail */
irdma_sc_cq_init(struct irdma_sc_cq * cq,struct irdma_cq_init_info * info)24792c4b14eaSShiraz Saleem int irdma_sc_cq_init(struct irdma_sc_cq *cq, struct irdma_cq_init_info *info)
24803f49d684SMustafa Ismail {
24813f49d684SMustafa Ismail u32 pble_obj_cnt;
24823f49d684SMustafa Ismail
24833f49d684SMustafa Ismail pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
24843f49d684SMustafa Ismail if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt)
24852c4b14eaSShiraz Saleem return -EINVAL;
24863f49d684SMustafa Ismail
24873f49d684SMustafa Ismail cq->cq_pa = info->cq_base_pa;
24883f49d684SMustafa Ismail cq->dev = info->dev;
24893f49d684SMustafa Ismail cq->ceq_id = info->ceq_id;
24903f49d684SMustafa Ismail info->cq_uk_init_info.cqe_alloc_db = cq->dev->cq_arm_db;
24913f49d684SMustafa Ismail info->cq_uk_init_info.cq_ack_db = cq->dev->cq_ack_db;
2492dede33daSZhu Yanjun irdma_uk_cq_init(&cq->cq_uk, &info->cq_uk_init_info);
24933f49d684SMustafa Ismail
24943f49d684SMustafa Ismail cq->virtual_map = info->virtual_map;
24953f49d684SMustafa Ismail cq->pbl_chunk_size = info->pbl_chunk_size;
24963f49d684SMustafa Ismail cq->ceqe_mask = info->ceqe_mask;
24973f49d684SMustafa Ismail cq->cq_type = (info->type) ? info->type : IRDMA_CQ_TYPE_IWARP;
24983f49d684SMustafa Ismail cq->shadow_area_pa = info->shadow_area_pa;
24993f49d684SMustafa Ismail cq->shadow_read_threshold = info->shadow_read_threshold;
25003f49d684SMustafa Ismail cq->ceq_id_valid = info->ceq_id_valid;
25013f49d684SMustafa Ismail cq->tph_en = info->tph_en;
25023f49d684SMustafa Ismail cq->tph_val = info->tph_val;
25033f49d684SMustafa Ismail cq->first_pm_pbl_idx = info->first_pm_pbl_idx;
25043f49d684SMustafa Ismail cq->vsi = info->vsi;
25053f49d684SMustafa Ismail
25063f49d684SMustafa Ismail return 0;
25073f49d684SMustafa Ismail }
25083f49d684SMustafa Ismail
25093f49d684SMustafa Ismail /**
25103f49d684SMustafa Ismail * irdma_sc_cq_create - create completion q
25113f49d684SMustafa Ismail * @cq: cq struct
25123f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
25133f49d684SMustafa Ismail * @check_overflow: flag for overflow check
25143f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
25153f49d684SMustafa Ismail */
irdma_sc_cq_create(struct irdma_sc_cq * cq,u64 scratch,bool check_overflow,bool post_sq)25162c4b14eaSShiraz Saleem static int irdma_sc_cq_create(struct irdma_sc_cq *cq, u64 scratch,
25172c4b14eaSShiraz Saleem bool check_overflow, bool post_sq)
25183f49d684SMustafa Ismail {
25193f49d684SMustafa Ismail __le64 *wqe;
25203f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
25213f49d684SMustafa Ismail u64 hdr;
25223f49d684SMustafa Ismail struct irdma_sc_ceq *ceq;
25232c4b14eaSShiraz Saleem int ret_code = 0;
25243f49d684SMustafa Ismail
25253f49d684SMustafa Ismail cqp = cq->dev->cqp;
25266f6dbb81SDan Carpenter if (cq->cq_uk.cq_id >= cqp->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].max_cnt)
25272c4b14eaSShiraz Saleem return -EINVAL;
25283f49d684SMustafa Ismail
25296f6dbb81SDan Carpenter if (cq->ceq_id >= cq->dev->hmc_fpm_misc.max_ceqs)
25302c4b14eaSShiraz Saleem return -EINVAL;
25313f49d684SMustafa Ismail
25323f49d684SMustafa Ismail ceq = cq->dev->ceq[cq->ceq_id];
25333f49d684SMustafa Ismail if (ceq && ceq->reg_cq)
25343f49d684SMustafa Ismail ret_code = irdma_sc_add_cq_ctx(ceq, cq);
25353f49d684SMustafa Ismail
25363f49d684SMustafa Ismail if (ret_code)
25373f49d684SMustafa Ismail return ret_code;
25383f49d684SMustafa Ismail
25393f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
25403f49d684SMustafa Ismail if (!wqe) {
25413f49d684SMustafa Ismail if (ceq && ceq->reg_cq)
25423f49d684SMustafa Ismail irdma_sc_remove_cq_ctx(ceq, cq);
25432c4b14eaSShiraz Saleem return -ENOMEM;
25443f49d684SMustafa Ismail }
25453f49d684SMustafa Ismail
25463f49d684SMustafa Ismail set_64bit_val(wqe, 0, cq->cq_uk.cq_size);
25473f49d684SMustafa Ismail set_64bit_val(wqe, 8, (uintptr_t)cq >> 1);
25483f49d684SMustafa Ismail set_64bit_val(wqe, 16,
25493f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD, cq->shadow_read_threshold));
25503f49d684SMustafa Ismail set_64bit_val(wqe, 32, (cq->virtual_map ? 0 : cq->cq_pa));
25513f49d684SMustafa Ismail set_64bit_val(wqe, 40, cq->shadow_area_pa);
25523f49d684SMustafa Ismail set_64bit_val(wqe, 48,
25533f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_FIRSTPMPBLIDX, (cq->virtual_map ? cq->first_pm_pbl_idx : 0)));
25543f49d684SMustafa Ismail set_64bit_val(wqe, 56,
25553f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHVAL, cq->tph_val) |
25563f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_VSIIDX, cq->vsi->vsi_idx));
25573f49d684SMustafa Ismail
25583f49d684SMustafa Ismail hdr = FLD_LS_64(cq->dev, cq->cq_uk.cq_id, IRDMA_CQPSQ_CQ_CQID) |
25593f49d684SMustafa Ismail FLD_LS_64(cq->dev, (cq->ceq_id_valid ? cq->ceq_id : 0),
25603f49d684SMustafa Ismail IRDMA_CQPSQ_CQ_CEQID) |
25613f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_CQ) |
25623f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_LPBLSIZE, cq->pbl_chunk_size) |
25633f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_CHKOVERFLOW, check_overflow) |
25643f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_VIRTMAP, cq->virtual_map) |
25653f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, cq->ceqe_mask) |
25663f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_CEQIDVALID, cq->ceq_id_valid) |
25673f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHEN, cq->tph_en) |
25683f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT,
25693f49d684SMustafa Ismail cq->cq_uk.avoid_mem_cflct) |
25703f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
25713f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
25723f49d684SMustafa Ismail
25733f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
25743f49d684SMustafa Ismail
25753f49d684SMustafa Ismail print_hex_dump_debug("WQE: CQ_CREATE WQE", DUMP_PREFIX_OFFSET, 16, 8,
25763f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
25773f49d684SMustafa Ismail if (post_sq)
25783f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
25793f49d684SMustafa Ismail
25803f49d684SMustafa Ismail return 0;
25813f49d684SMustafa Ismail }
25823f49d684SMustafa Ismail
25833f49d684SMustafa Ismail /**
25843f49d684SMustafa Ismail * irdma_sc_cq_destroy - destroy completion q
25853f49d684SMustafa Ismail * @cq: cq struct
25863f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
25873f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
25883f49d684SMustafa Ismail */
irdma_sc_cq_destroy(struct irdma_sc_cq * cq,u64 scratch,bool post_sq)25892c4b14eaSShiraz Saleem int irdma_sc_cq_destroy(struct irdma_sc_cq *cq, u64 scratch, bool post_sq)
25903f49d684SMustafa Ismail {
25913f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
25923f49d684SMustafa Ismail __le64 *wqe;
25933f49d684SMustafa Ismail u64 hdr;
25943f49d684SMustafa Ismail struct irdma_sc_ceq *ceq;
25953f49d684SMustafa Ismail
25963f49d684SMustafa Ismail cqp = cq->dev->cqp;
25973f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
25983f49d684SMustafa Ismail if (!wqe)
25992c4b14eaSShiraz Saleem return -ENOMEM;
26003f49d684SMustafa Ismail
26013f49d684SMustafa Ismail ceq = cq->dev->ceq[cq->ceq_id];
26023f49d684SMustafa Ismail if (ceq && ceq->reg_cq)
26033f49d684SMustafa Ismail irdma_sc_remove_cq_ctx(ceq, cq);
26043f49d684SMustafa Ismail
26053f49d684SMustafa Ismail set_64bit_val(wqe, 0, cq->cq_uk.cq_size);
26063f49d684SMustafa Ismail set_64bit_val(wqe, 8, (uintptr_t)cq >> 1);
26073f49d684SMustafa Ismail set_64bit_val(wqe, 40, cq->shadow_area_pa);
26083f49d684SMustafa Ismail set_64bit_val(wqe, 48,
26093f49d684SMustafa Ismail (cq->virtual_map ? cq->first_pm_pbl_idx : 0));
26103f49d684SMustafa Ismail
26113f49d684SMustafa Ismail hdr = cq->cq_uk.cq_id |
26123f49d684SMustafa Ismail FLD_LS_64(cq->dev, (cq->ceq_id_valid ? cq->ceq_id : 0),
26133f49d684SMustafa Ismail IRDMA_CQPSQ_CQ_CEQID) |
26143f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_CQ) |
26153f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_LPBLSIZE, cq->pbl_chunk_size) |
26163f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_VIRTMAP, cq->virtual_map) |
26173f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, cq->ceqe_mask) |
26183f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_CEQIDVALID, cq->ceq_id_valid) |
26193f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHEN, cq->tph_en) |
26203f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT, cq->cq_uk.avoid_mem_cflct) |
26213f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
26223f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
26233f49d684SMustafa Ismail
26243f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
26253f49d684SMustafa Ismail
26263f49d684SMustafa Ismail print_hex_dump_debug("WQE: CQ_DESTROY WQE", DUMP_PREFIX_OFFSET, 16, 8,
26273f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
26283f49d684SMustafa Ismail if (post_sq)
26293f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
26303f49d684SMustafa Ismail
26313f49d684SMustafa Ismail return 0;
26323f49d684SMustafa Ismail }
26333f49d684SMustafa Ismail
26343f49d684SMustafa Ismail /**
26353f49d684SMustafa Ismail * irdma_sc_cq_resize - set resized cq buffer info
26363f49d684SMustafa Ismail * @cq: resized cq
26373f49d684SMustafa Ismail * @info: resized cq buffer info
26383f49d684SMustafa Ismail */
irdma_sc_cq_resize(struct irdma_sc_cq * cq,struct irdma_modify_cq_info * info)26393f49d684SMustafa Ismail void irdma_sc_cq_resize(struct irdma_sc_cq *cq, struct irdma_modify_cq_info *info)
26403f49d684SMustafa Ismail {
26413f49d684SMustafa Ismail cq->virtual_map = info->virtual_map;
26423f49d684SMustafa Ismail cq->cq_pa = info->cq_pa;
26433f49d684SMustafa Ismail cq->first_pm_pbl_idx = info->first_pm_pbl_idx;
26443f49d684SMustafa Ismail cq->pbl_chunk_size = info->pbl_chunk_size;
26453f49d684SMustafa Ismail irdma_uk_cq_resize(&cq->cq_uk, info->cq_base, info->cq_size);
26463f49d684SMustafa Ismail }
26473f49d684SMustafa Ismail
26483f49d684SMustafa Ismail /**
26493f49d684SMustafa Ismail * irdma_sc_cq_modify - modify a Completion Queue
26503f49d684SMustafa Ismail * @cq: cq struct
26513f49d684SMustafa Ismail * @info: modification info struct
26523f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
26533f49d684SMustafa Ismail * @post_sq: flag to post to sq
26543f49d684SMustafa Ismail */
irdma_sc_cq_modify(struct irdma_sc_cq * cq,struct irdma_modify_cq_info * info,u64 scratch,bool post_sq)26552c4b14eaSShiraz Saleem static int irdma_sc_cq_modify(struct irdma_sc_cq *cq,
26562c4b14eaSShiraz Saleem struct irdma_modify_cq_info *info, u64 scratch,
26572c4b14eaSShiraz Saleem bool post_sq)
26583f49d684SMustafa Ismail {
26593f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
26603f49d684SMustafa Ismail __le64 *wqe;
26613f49d684SMustafa Ismail u64 hdr;
26623f49d684SMustafa Ismail u32 pble_obj_cnt;
26633f49d684SMustafa Ismail
26643f49d684SMustafa Ismail pble_obj_cnt = cq->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
26653f49d684SMustafa Ismail if (info->cq_resize && info->virtual_map &&
26663f49d684SMustafa Ismail info->first_pm_pbl_idx >= pble_obj_cnt)
26672c4b14eaSShiraz Saleem return -EINVAL;
26683f49d684SMustafa Ismail
26693f49d684SMustafa Ismail cqp = cq->dev->cqp;
26703f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
26713f49d684SMustafa Ismail if (!wqe)
26722c4b14eaSShiraz Saleem return -ENOMEM;
26733f49d684SMustafa Ismail
26743f49d684SMustafa Ismail set_64bit_val(wqe, 0, info->cq_size);
26753f49d684SMustafa Ismail set_64bit_val(wqe, 8, (uintptr_t)cq >> 1);
26763f49d684SMustafa Ismail set_64bit_val(wqe, 16,
26773f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD, info->shadow_read_threshold));
26783f49d684SMustafa Ismail set_64bit_val(wqe, 32, info->cq_pa);
26793f49d684SMustafa Ismail set_64bit_val(wqe, 40, cq->shadow_area_pa);
26803f49d684SMustafa Ismail set_64bit_val(wqe, 48, info->first_pm_pbl_idx);
26813f49d684SMustafa Ismail set_64bit_val(wqe, 56,
26823f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHVAL, cq->tph_val) |
26833f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_VSIIDX, cq->vsi->vsi_idx));
26843f49d684SMustafa Ismail
26853f49d684SMustafa Ismail hdr = cq->cq_uk.cq_id |
26863f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MODIFY_CQ) |
26873f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_CQRESIZE, info->cq_resize) |
26883f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_LPBLSIZE, info->pbl_chunk_size) |
26893f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_CHKOVERFLOW, info->check_overflow) |
26903f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_VIRTMAP, info->virtual_map) |
26913f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, cq->ceqe_mask) |
26923f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHEN, cq->tph_en) |
26933f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT,
26943f49d684SMustafa Ismail cq->cq_uk.avoid_mem_cflct) |
26953f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
26963f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
26973f49d684SMustafa Ismail
26983f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
26993f49d684SMustafa Ismail
27003f49d684SMustafa Ismail print_hex_dump_debug("WQE: CQ_MODIFY WQE", DUMP_PREFIX_OFFSET, 16, 8,
27013f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
27023f49d684SMustafa Ismail if (post_sq)
27033f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
27043f49d684SMustafa Ismail
27053f49d684SMustafa Ismail return 0;
27063f49d684SMustafa Ismail }
27073f49d684SMustafa Ismail
27083f49d684SMustafa Ismail /**
27093f49d684SMustafa Ismail * irdma_check_cqp_progress - check cqp processing progress
27103f49d684SMustafa Ismail * @timeout: timeout info struct
27113f49d684SMustafa Ismail * @dev: sc device struct
27123f49d684SMustafa Ismail */
irdma_check_cqp_progress(struct irdma_cqp_timeout * timeout,struct irdma_sc_dev * dev)27133f49d684SMustafa Ismail void irdma_check_cqp_progress(struct irdma_cqp_timeout *timeout, struct irdma_sc_dev *dev)
27143f49d684SMustafa Ismail {
2715f2c30378SShiraz Saleem u64 completed_ops = atomic64_read(&dev->cqp->completed_ops);
2716f2c30378SShiraz Saleem
2717f2c30378SShiraz Saleem if (timeout->compl_cqp_cmds != completed_ops) {
2718f2c30378SShiraz Saleem timeout->compl_cqp_cmds = completed_ops;
27193f49d684SMustafa Ismail timeout->count = 0;
2720f2c30378SShiraz Saleem } else if (timeout->compl_cqp_cmds != dev->cqp->requested_ops) {
27213f49d684SMustafa Ismail timeout->count++;
27223f49d684SMustafa Ismail }
27233f49d684SMustafa Ismail }
27243f49d684SMustafa Ismail
27253f49d684SMustafa Ismail /**
27263f49d684SMustafa Ismail * irdma_get_cqp_reg_info - get head and tail for cqp using registers
27273f49d684SMustafa Ismail * @cqp: struct for cqp hw
27283f49d684SMustafa Ismail * @val: cqp tail register value
27293f49d684SMustafa Ismail * @tail: wqtail register value
27303f49d684SMustafa Ismail * @error: cqp processing err
27313f49d684SMustafa Ismail */
irdma_get_cqp_reg_info(struct irdma_sc_cqp * cqp,u32 * val,u32 * tail,u32 * error)27323f49d684SMustafa Ismail static inline void irdma_get_cqp_reg_info(struct irdma_sc_cqp *cqp, u32 *val,
27333f49d684SMustafa Ismail u32 *tail, u32 *error)
27343f49d684SMustafa Ismail {
27353f49d684SMustafa Ismail *val = readl(cqp->dev->hw_regs[IRDMA_CQPTAIL]);
27363f49d684SMustafa Ismail *tail = FIELD_GET(IRDMA_CQPTAIL_WQTAIL, *val);
27373f49d684SMustafa Ismail *error = FIELD_GET(IRDMA_CQPTAIL_CQP_OP_ERR, *val);
27383f49d684SMustafa Ismail }
27393f49d684SMustafa Ismail
27403f49d684SMustafa Ismail /**
27413f49d684SMustafa Ismail * irdma_cqp_poll_registers - poll cqp registers
27423f49d684SMustafa Ismail * @cqp: struct for cqp hw
27433f49d684SMustafa Ismail * @tail: wqtail register value
27443f49d684SMustafa Ismail * @count: how many times to try for completion
27453f49d684SMustafa Ismail */
irdma_cqp_poll_registers(struct irdma_sc_cqp * cqp,u32 tail,u32 count)27462c4b14eaSShiraz Saleem static int irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp, u32 tail,
27472c4b14eaSShiraz Saleem u32 count)
27483f49d684SMustafa Ismail {
27493f49d684SMustafa Ismail u32 i = 0;
27503f49d684SMustafa Ismail u32 newtail, error, val;
27513f49d684SMustafa Ismail
27523f49d684SMustafa Ismail while (i++ < count) {
27533f49d684SMustafa Ismail irdma_get_cqp_reg_info(cqp, &val, &newtail, &error);
27543f49d684SMustafa Ismail if (error) {
27553f49d684SMustafa Ismail error = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]);
27563f49d684SMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev),
27573f49d684SMustafa Ismail "CQP: CQPERRCODES error_code[x%08X]\n",
27583f49d684SMustafa Ismail error);
27592c4b14eaSShiraz Saleem return -EIO;
27603f49d684SMustafa Ismail }
27613f49d684SMustafa Ismail if (newtail != tail) {
27623f49d684SMustafa Ismail /* SUCCESS */
27633f49d684SMustafa Ismail IRDMA_RING_MOVE_TAIL(cqp->sq_ring);
2764f2c30378SShiraz Saleem atomic64_inc(&cqp->completed_ops);
27653f49d684SMustafa Ismail return 0;
27663f49d684SMustafa Ismail }
27673f49d684SMustafa Ismail udelay(cqp->dev->hw_attrs.max_sleep_count);
27683f49d684SMustafa Ismail }
27693f49d684SMustafa Ismail
27702c4b14eaSShiraz Saleem return -ETIMEDOUT;
27713f49d684SMustafa Ismail }
27723f49d684SMustafa Ismail
27733f49d684SMustafa Ismail /**
27743f49d684SMustafa Ismail * irdma_sc_decode_fpm_commit - decode a 64 bit value into count and base
27753f49d684SMustafa Ismail * @dev: sc device struct
27763f49d684SMustafa Ismail * @buf: pointer to commit buffer
27773f49d684SMustafa Ismail * @buf_idx: buffer index
27783f49d684SMustafa Ismail * @obj_info: object info pointer
27793f49d684SMustafa Ismail * @rsrc_idx: indexs of memory resource
27803f49d684SMustafa Ismail */
irdma_sc_decode_fpm_commit(struct irdma_sc_dev * dev,__le64 * buf,u32 buf_idx,struct irdma_hmc_obj_info * obj_info,u32 rsrc_idx)27813f49d684SMustafa Ismail static u64 irdma_sc_decode_fpm_commit(struct irdma_sc_dev *dev, __le64 *buf,
27823f49d684SMustafa Ismail u32 buf_idx, struct irdma_hmc_obj_info *obj_info,
27833f49d684SMustafa Ismail u32 rsrc_idx)
27843f49d684SMustafa Ismail {
27853f49d684SMustafa Ismail u64 temp;
27863f49d684SMustafa Ismail
27873f49d684SMustafa Ismail get_64bit_val(buf, buf_idx, &temp);
27883f49d684SMustafa Ismail
27893f49d684SMustafa Ismail switch (rsrc_idx) {
27903f49d684SMustafa Ismail case IRDMA_HMC_IW_QP:
27913f49d684SMustafa Ismail obj_info[rsrc_idx].cnt = (u32)FIELD_GET(IRDMA_COMMIT_FPM_QPCNT, temp);
27923f49d684SMustafa Ismail break;
27933f49d684SMustafa Ismail case IRDMA_HMC_IW_CQ:
27943f49d684SMustafa Ismail obj_info[rsrc_idx].cnt = (u32)FLD_RS_64(dev, temp, IRDMA_COMMIT_FPM_CQCNT);
27953f49d684SMustafa Ismail break;
27963f49d684SMustafa Ismail case IRDMA_HMC_IW_APBVT_ENTRY:
27973f49d684SMustafa Ismail obj_info[rsrc_idx].cnt = 1;
27983f49d684SMustafa Ismail break;
27993f49d684SMustafa Ismail default:
28003f49d684SMustafa Ismail obj_info[rsrc_idx].cnt = (u32)temp;
28013f49d684SMustafa Ismail break;
28023f49d684SMustafa Ismail }
28033f49d684SMustafa Ismail
28043f49d684SMustafa Ismail obj_info[rsrc_idx].base = (temp >> IRDMA_COMMIT_FPM_BASE_S) * 512;
28053f49d684SMustafa Ismail
28063f49d684SMustafa Ismail return temp;
28073f49d684SMustafa Ismail }
28083f49d684SMustafa Ismail
28093f49d684SMustafa Ismail /**
28103f49d684SMustafa Ismail * irdma_sc_parse_fpm_commit_buf - parse fpm commit buffer
28113f49d684SMustafa Ismail * @dev: pointer to dev struct
28123f49d684SMustafa Ismail * @buf: ptr to fpm commit buffer
28133f49d684SMustafa Ismail * @info: ptr to irdma_hmc_obj_info struct
28143f49d684SMustafa Ismail * @sd: number of SDs for HMC objects
28153f49d684SMustafa Ismail *
28163f49d684SMustafa Ismail * parses fpm commit info and copy base value
28173f49d684SMustafa Ismail * of hmc objects in hmc_info
28183f49d684SMustafa Ismail */
2819c9538831SZhu Yanjun static void
irdma_sc_parse_fpm_commit_buf(struct irdma_sc_dev * dev,__le64 * buf,struct irdma_hmc_obj_info * info,u32 * sd)28203f49d684SMustafa Ismail irdma_sc_parse_fpm_commit_buf(struct irdma_sc_dev *dev, __le64 *buf,
28213f49d684SMustafa Ismail struct irdma_hmc_obj_info *info, u32 *sd)
28223f49d684SMustafa Ismail {
28233f49d684SMustafa Ismail u64 size;
28243f49d684SMustafa Ismail u32 i;
28253f49d684SMustafa Ismail u64 max_base = 0;
28263f49d684SMustafa Ismail u32 last_hmc_obj = 0;
28273f49d684SMustafa Ismail
28283f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 0, info,
28293f49d684SMustafa Ismail IRDMA_HMC_IW_QP);
28303f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 8, info,
28313f49d684SMustafa Ismail IRDMA_HMC_IW_CQ);
28323f49d684SMustafa Ismail /* skiping RSRVD */
28333f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 24, info,
28343f49d684SMustafa Ismail IRDMA_HMC_IW_HTE);
28353f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 32, info,
28363f49d684SMustafa Ismail IRDMA_HMC_IW_ARP);
28373f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 40, info,
28383f49d684SMustafa Ismail IRDMA_HMC_IW_APBVT_ENTRY);
28393f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 48, info,
28403f49d684SMustafa Ismail IRDMA_HMC_IW_MR);
28413f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 56, info,
28423f49d684SMustafa Ismail IRDMA_HMC_IW_XF);
28433f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 64, info,
28443f49d684SMustafa Ismail IRDMA_HMC_IW_XFFL);
28453f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 72, info,
28463f49d684SMustafa Ismail IRDMA_HMC_IW_Q1);
28473f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 80, info,
28483f49d684SMustafa Ismail IRDMA_HMC_IW_Q1FL);
28493f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 88, info,
28503f49d684SMustafa Ismail IRDMA_HMC_IW_TIMER);
28513f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 112, info,
28523f49d684SMustafa Ismail IRDMA_HMC_IW_PBLE);
28533f49d684SMustafa Ismail /* skipping RSVD. */
28543f49d684SMustafa Ismail if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1) {
28553f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 96, info,
28563f49d684SMustafa Ismail IRDMA_HMC_IW_FSIMC);
28573f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 104, info,
28583f49d684SMustafa Ismail IRDMA_HMC_IW_FSIAV);
28593f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 128, info,
28603f49d684SMustafa Ismail IRDMA_HMC_IW_RRF);
28613f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 136, info,
28623f49d684SMustafa Ismail IRDMA_HMC_IW_RRFFL);
28633f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 144, info,
28643f49d684SMustafa Ismail IRDMA_HMC_IW_HDR);
28653f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 152, info,
28663f49d684SMustafa Ismail IRDMA_HMC_IW_MD);
28673f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 160, info,
28683f49d684SMustafa Ismail IRDMA_HMC_IW_OOISC);
28693f49d684SMustafa Ismail irdma_sc_decode_fpm_commit(dev, buf, 168, info,
28703f49d684SMustafa Ismail IRDMA_HMC_IW_OOISCFFL);
28713f49d684SMustafa Ismail }
28723f49d684SMustafa Ismail
28733f49d684SMustafa Ismail /* searching for the last object in HMC to find the size of the HMC area. */
28743f49d684SMustafa Ismail for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) {
28753f49d684SMustafa Ismail if (info[i].base > max_base) {
28763f49d684SMustafa Ismail max_base = info[i].base;
28773f49d684SMustafa Ismail last_hmc_obj = i;
28783f49d684SMustafa Ismail }
28793f49d684SMustafa Ismail }
28803f49d684SMustafa Ismail
28813f49d684SMustafa Ismail size = info[last_hmc_obj].cnt * info[last_hmc_obj].size +
28823f49d684SMustafa Ismail info[last_hmc_obj].base;
28833f49d684SMustafa Ismail
28843f49d684SMustafa Ismail if (size & 0x1FFFFF)
28853f49d684SMustafa Ismail *sd = (u32)((size >> 21) + 1); /* add 1 for remainder */
28863f49d684SMustafa Ismail else
28873f49d684SMustafa Ismail *sd = (u32)(size >> 21);
28883f49d684SMustafa Ismail
28893f49d684SMustafa Ismail }
28903f49d684SMustafa Ismail
28913f49d684SMustafa Ismail /**
28923f49d684SMustafa Ismail * irdma_sc_decode_fpm_query() - Decode a 64 bit value into max count and size
28933f49d684SMustafa Ismail * @buf: ptr to fpm query buffer
28943f49d684SMustafa Ismail * @buf_idx: index into buf
28953f49d684SMustafa Ismail * @obj_info: ptr to irdma_hmc_obj_info struct
28963f49d684SMustafa Ismail * @rsrc_idx: resource index into info
28973f49d684SMustafa Ismail *
28983f49d684SMustafa Ismail * Decode a 64 bit value from fpm query buffer into max count and size
28993f49d684SMustafa Ismail */
irdma_sc_decode_fpm_query(__le64 * buf,u32 buf_idx,struct irdma_hmc_obj_info * obj_info,u32 rsrc_idx)29003f49d684SMustafa Ismail static u64 irdma_sc_decode_fpm_query(__le64 *buf, u32 buf_idx,
29013f49d684SMustafa Ismail struct irdma_hmc_obj_info *obj_info,
29023f49d684SMustafa Ismail u32 rsrc_idx)
29033f49d684SMustafa Ismail {
29043f49d684SMustafa Ismail u64 temp;
29053f49d684SMustafa Ismail u32 size;
29063f49d684SMustafa Ismail
29073f49d684SMustafa Ismail get_64bit_val(buf, buf_idx, &temp);
29083f49d684SMustafa Ismail obj_info[rsrc_idx].max_cnt = (u32)temp;
29093f49d684SMustafa Ismail size = (u32)(temp >> 32);
29103f49d684SMustafa Ismail obj_info[rsrc_idx].size = BIT_ULL(size);
29113f49d684SMustafa Ismail
29123f49d684SMustafa Ismail return temp;
29133f49d684SMustafa Ismail }
29143f49d684SMustafa Ismail
29153f49d684SMustafa Ismail /**
29163f49d684SMustafa Ismail * irdma_sc_parse_fpm_query_buf() - parses fpm query buffer
29173f49d684SMustafa Ismail * @dev: ptr to shared code device
29183f49d684SMustafa Ismail * @buf: ptr to fpm query buffer
29193f49d684SMustafa Ismail * @hmc_info: ptr to irdma_hmc_obj_info struct
29203f49d684SMustafa Ismail * @hmc_fpm_misc: ptr to fpm data
29213f49d684SMustafa Ismail *
29223f49d684SMustafa Ismail * parses fpm query buffer and copy max_cnt and
29233f49d684SMustafa Ismail * size value of hmc objects in hmc_info
29243f49d684SMustafa Ismail */
irdma_sc_parse_fpm_query_buf(struct irdma_sc_dev * dev,__le64 * buf,struct irdma_hmc_info * hmc_info,struct irdma_hmc_fpm_misc * hmc_fpm_misc)29252c4b14eaSShiraz Saleem static int irdma_sc_parse_fpm_query_buf(struct irdma_sc_dev *dev, __le64 *buf,
29263f49d684SMustafa Ismail struct irdma_hmc_info *hmc_info,
29273f49d684SMustafa Ismail struct irdma_hmc_fpm_misc *hmc_fpm_misc)
29283f49d684SMustafa Ismail {
29293f49d684SMustafa Ismail struct irdma_hmc_obj_info *obj_info;
29303f49d684SMustafa Ismail u64 temp;
29313f49d684SMustafa Ismail u32 size;
29323f49d684SMustafa Ismail u16 max_pe_sds;
29333f49d684SMustafa Ismail
29343f49d684SMustafa Ismail obj_info = hmc_info->hmc_obj;
29353f49d684SMustafa Ismail
29363f49d684SMustafa Ismail get_64bit_val(buf, 0, &temp);
29373f49d684SMustafa Ismail hmc_info->first_sd_index = (u16)FIELD_GET(IRDMA_QUERY_FPM_FIRST_PE_SD_INDEX, temp);
29383f49d684SMustafa Ismail max_pe_sds = (u16)FIELD_GET(IRDMA_QUERY_FPM_MAX_PE_SDS, temp);
29393f49d684SMustafa Ismail
29403f49d684SMustafa Ismail hmc_fpm_misc->max_sds = max_pe_sds;
29413f49d684SMustafa Ismail hmc_info->sd_table.sd_cnt = max_pe_sds + hmc_info->first_sd_index;
29423f49d684SMustafa Ismail get_64bit_val(buf, 8, &temp);
29433f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_QP].max_cnt = (u32)FIELD_GET(IRDMA_QUERY_FPM_MAX_QPS, temp);
29443f49d684SMustafa Ismail size = (u32)(temp >> 32);
29453f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_QP].size = BIT_ULL(size);
29463f49d684SMustafa Ismail
29473f49d684SMustafa Ismail get_64bit_val(buf, 16, &temp);
29483f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_CQ].max_cnt = (u32)FIELD_GET(IRDMA_QUERY_FPM_MAX_CQS, temp);
29493f49d684SMustafa Ismail size = (u32)(temp >> 32);
29503f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_CQ].size = BIT_ULL(size);
29513f49d684SMustafa Ismail
29523f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 32, obj_info, IRDMA_HMC_IW_HTE);
29533f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 40, obj_info, IRDMA_HMC_IW_ARP);
29543f49d684SMustafa Ismail
29553f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_APBVT_ENTRY].size = 8192;
29563f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_APBVT_ENTRY].max_cnt = 1;
29573f49d684SMustafa Ismail
29583f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 48, obj_info, IRDMA_HMC_IW_MR);
29593f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 56, obj_info, IRDMA_HMC_IW_XF);
29603f49d684SMustafa Ismail
29613f49d684SMustafa Ismail get_64bit_val(buf, 64, &temp);
29623f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_XFFL].max_cnt = (u32)temp;
29633f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_XFFL].size = 4;
29643f49d684SMustafa Ismail hmc_fpm_misc->xf_block_size = FIELD_GET(IRDMA_QUERY_FPM_XFBLOCKSIZE, temp);
29653f49d684SMustafa Ismail if (!hmc_fpm_misc->xf_block_size)
29662c4b14eaSShiraz Saleem return -EINVAL;
29673f49d684SMustafa Ismail
29683f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 72, obj_info, IRDMA_HMC_IW_Q1);
29693f49d684SMustafa Ismail get_64bit_val(buf, 80, &temp);
29703f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_Q1FL].max_cnt = (u32)temp;
29713f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_Q1FL].size = 4;
29723f49d684SMustafa Ismail
29733f49d684SMustafa Ismail hmc_fpm_misc->q1_block_size = FIELD_GET(IRDMA_QUERY_FPM_Q1BLOCKSIZE, temp);
29743f49d684SMustafa Ismail if (!hmc_fpm_misc->q1_block_size)
29752c4b14eaSShiraz Saleem return -EINVAL;
29763f49d684SMustafa Ismail
29773f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 88, obj_info, IRDMA_HMC_IW_TIMER);
29783f49d684SMustafa Ismail
29793f49d684SMustafa Ismail get_64bit_val(buf, 112, &temp);
29803f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_PBLE].max_cnt = (u32)temp;
29813f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_PBLE].size = 8;
29823f49d684SMustafa Ismail
29833f49d684SMustafa Ismail get_64bit_val(buf, 120, &temp);
29843f49d684SMustafa Ismail hmc_fpm_misc->max_ceqs = FIELD_GET(IRDMA_QUERY_FPM_MAX_CEQS, temp);
29853f49d684SMustafa Ismail hmc_fpm_misc->ht_multiplier = FIELD_GET(IRDMA_QUERY_FPM_HTMULTIPLIER, temp);
29863f49d684SMustafa Ismail hmc_fpm_misc->timer_bucket = FIELD_GET(IRDMA_QUERY_FPM_TIMERBUCKET, temp);
29873f49d684SMustafa Ismail if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
29883f49d684SMustafa Ismail return 0;
29893f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 96, obj_info, IRDMA_HMC_IW_FSIMC);
29903f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 104, obj_info, IRDMA_HMC_IW_FSIAV);
29913f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 128, obj_info, IRDMA_HMC_IW_RRF);
29923f49d684SMustafa Ismail
29933f49d684SMustafa Ismail get_64bit_val(buf, 136, &temp);
29943f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_RRFFL].max_cnt = (u32)temp;
29953f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_RRFFL].size = 4;
29963f49d684SMustafa Ismail hmc_fpm_misc->rrf_block_size = FIELD_GET(IRDMA_QUERY_FPM_RRFBLOCKSIZE, temp);
29973f49d684SMustafa Ismail if (!hmc_fpm_misc->rrf_block_size &&
29983f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_RRFFL].max_cnt)
29992c4b14eaSShiraz Saleem return -EINVAL;
30003f49d684SMustafa Ismail
30013f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 144, obj_info, IRDMA_HMC_IW_HDR);
30023f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 152, obj_info, IRDMA_HMC_IW_MD);
30033f49d684SMustafa Ismail irdma_sc_decode_fpm_query(buf, 160, obj_info, IRDMA_HMC_IW_OOISC);
30043f49d684SMustafa Ismail
30053f49d684SMustafa Ismail get_64bit_val(buf, 168, &temp);
30063f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt = (u32)temp;
30073f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_OOISCFFL].size = 4;
30083f49d684SMustafa Ismail hmc_fpm_misc->ooiscf_block_size = FIELD_GET(IRDMA_QUERY_FPM_OOISCFBLOCKSIZE, temp);
30093f49d684SMustafa Ismail if (!hmc_fpm_misc->ooiscf_block_size &&
30103f49d684SMustafa Ismail obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt)
30112c4b14eaSShiraz Saleem return -EINVAL;
30123f49d684SMustafa Ismail
30133f49d684SMustafa Ismail return 0;
30143f49d684SMustafa Ismail }
30153f49d684SMustafa Ismail
30163f49d684SMustafa Ismail /**
30173f49d684SMustafa Ismail * irdma_sc_find_reg_cq - find cq ctx index
30183f49d684SMustafa Ismail * @ceq: ceq sc structure
30193f49d684SMustafa Ismail * @cq: cq sc structure
30203f49d684SMustafa Ismail */
irdma_sc_find_reg_cq(struct irdma_sc_ceq * ceq,struct irdma_sc_cq * cq)30213f49d684SMustafa Ismail static u32 irdma_sc_find_reg_cq(struct irdma_sc_ceq *ceq,
30223f49d684SMustafa Ismail struct irdma_sc_cq *cq)
30233f49d684SMustafa Ismail {
30243f49d684SMustafa Ismail u32 i;
30253f49d684SMustafa Ismail
30263f49d684SMustafa Ismail for (i = 0; i < ceq->reg_cq_size; i++) {
30273f49d684SMustafa Ismail if (cq == ceq->reg_cq[i])
30283f49d684SMustafa Ismail return i;
30293f49d684SMustafa Ismail }
30303f49d684SMustafa Ismail
30313f49d684SMustafa Ismail return IRDMA_INVALID_CQ_IDX;
30323f49d684SMustafa Ismail }
30333f49d684SMustafa Ismail
30343f49d684SMustafa Ismail /**
30353f49d684SMustafa Ismail * irdma_sc_add_cq_ctx - add cq ctx tracking for ceq
30363f49d684SMustafa Ismail * @ceq: ceq sc structure
30373f49d684SMustafa Ismail * @cq: cq sc structure
30383f49d684SMustafa Ismail */
irdma_sc_add_cq_ctx(struct irdma_sc_ceq * ceq,struct irdma_sc_cq * cq)30392c4b14eaSShiraz Saleem int irdma_sc_add_cq_ctx(struct irdma_sc_ceq *ceq, struct irdma_sc_cq *cq)
30403f49d684SMustafa Ismail {
30413f49d684SMustafa Ismail unsigned long flags;
30423f49d684SMustafa Ismail
30433f49d684SMustafa Ismail spin_lock_irqsave(&ceq->req_cq_lock, flags);
30443f49d684SMustafa Ismail
30453f49d684SMustafa Ismail if (ceq->reg_cq_size == ceq->elem_cnt) {
30463f49d684SMustafa Ismail spin_unlock_irqrestore(&ceq->req_cq_lock, flags);
30472c4b14eaSShiraz Saleem return -ENOMEM;
30483f49d684SMustafa Ismail }
30493f49d684SMustafa Ismail
30503f49d684SMustafa Ismail ceq->reg_cq[ceq->reg_cq_size++] = cq;
30513f49d684SMustafa Ismail
30523f49d684SMustafa Ismail spin_unlock_irqrestore(&ceq->req_cq_lock, flags);
30533f49d684SMustafa Ismail
30543f49d684SMustafa Ismail return 0;
30553f49d684SMustafa Ismail }
30563f49d684SMustafa Ismail
30573f49d684SMustafa Ismail /**
30583f49d684SMustafa Ismail * irdma_sc_remove_cq_ctx - remove cq ctx tracking for ceq
30593f49d684SMustafa Ismail * @ceq: ceq sc structure
30603f49d684SMustafa Ismail * @cq: cq sc structure
30613f49d684SMustafa Ismail */
irdma_sc_remove_cq_ctx(struct irdma_sc_ceq * ceq,struct irdma_sc_cq * cq)30623f49d684SMustafa Ismail void irdma_sc_remove_cq_ctx(struct irdma_sc_ceq *ceq, struct irdma_sc_cq *cq)
30633f49d684SMustafa Ismail {
30643f49d684SMustafa Ismail unsigned long flags;
30653f49d684SMustafa Ismail u32 cq_ctx_idx;
30663f49d684SMustafa Ismail
30673f49d684SMustafa Ismail spin_lock_irqsave(&ceq->req_cq_lock, flags);
30683f49d684SMustafa Ismail cq_ctx_idx = irdma_sc_find_reg_cq(ceq, cq);
30693f49d684SMustafa Ismail if (cq_ctx_idx == IRDMA_INVALID_CQ_IDX)
30703f49d684SMustafa Ismail goto exit;
30713f49d684SMustafa Ismail
30723f49d684SMustafa Ismail ceq->reg_cq_size--;
30733f49d684SMustafa Ismail if (cq_ctx_idx != ceq->reg_cq_size)
30743f49d684SMustafa Ismail ceq->reg_cq[cq_ctx_idx] = ceq->reg_cq[ceq->reg_cq_size];
30753f49d684SMustafa Ismail ceq->reg_cq[ceq->reg_cq_size] = NULL;
30763f49d684SMustafa Ismail
30773f49d684SMustafa Ismail exit:
30783f49d684SMustafa Ismail spin_unlock_irqrestore(&ceq->req_cq_lock, flags);
30793f49d684SMustafa Ismail }
30803f49d684SMustafa Ismail
30813f49d684SMustafa Ismail /**
30823f49d684SMustafa Ismail * irdma_sc_cqp_init - Initialize buffers for a control Queue Pair
30833f49d684SMustafa Ismail * @cqp: IWARP control queue pair pointer
30843f49d684SMustafa Ismail * @info: IWARP control queue pair init info pointer
30853f49d684SMustafa Ismail *
30863f49d684SMustafa Ismail * Initializes the object and context buffers for a control Queue Pair.
30873f49d684SMustafa Ismail */
irdma_sc_cqp_init(struct irdma_sc_cqp * cqp,struct irdma_cqp_init_info * info)30882c4b14eaSShiraz Saleem int irdma_sc_cqp_init(struct irdma_sc_cqp *cqp,
30893f49d684SMustafa Ismail struct irdma_cqp_init_info *info)
30903f49d684SMustafa Ismail {
30913f49d684SMustafa Ismail u8 hw_sq_size;
30923f49d684SMustafa Ismail
30933f49d684SMustafa Ismail if (info->sq_size > IRDMA_CQP_SW_SQSIZE_2048 ||
30943f49d684SMustafa Ismail info->sq_size < IRDMA_CQP_SW_SQSIZE_4 ||
30953f49d684SMustafa Ismail ((info->sq_size & (info->sq_size - 1))))
30962c4b14eaSShiraz Saleem return -EINVAL;
30973f49d684SMustafa Ismail
30983f49d684SMustafa Ismail hw_sq_size = irdma_get_encoded_wqe_size(info->sq_size,
30993f49d684SMustafa Ismail IRDMA_QUEUE_TYPE_CQP);
31003f49d684SMustafa Ismail cqp->size = sizeof(*cqp);
31013f49d684SMustafa Ismail cqp->sq_size = info->sq_size;
31023f49d684SMustafa Ismail cqp->hw_sq_size = hw_sq_size;
31033f49d684SMustafa Ismail cqp->sq_base = info->sq;
31043f49d684SMustafa Ismail cqp->host_ctx = info->host_ctx;
31053f49d684SMustafa Ismail cqp->sq_pa = info->sq_pa;
31063f49d684SMustafa Ismail cqp->host_ctx_pa = info->host_ctx_pa;
31073f49d684SMustafa Ismail cqp->dev = info->dev;
31083f49d684SMustafa Ismail cqp->struct_ver = info->struct_ver;
31093f49d684SMustafa Ismail cqp->hw_maj_ver = info->hw_maj_ver;
31103f49d684SMustafa Ismail cqp->hw_min_ver = info->hw_min_ver;
31113f49d684SMustafa Ismail cqp->scratch_array = info->scratch_array;
31123f49d684SMustafa Ismail cqp->polarity = 0;
31133f49d684SMustafa Ismail cqp->en_datacenter_tcp = info->en_datacenter_tcp;
31143f49d684SMustafa Ismail cqp->ena_vf_count = info->ena_vf_count;
31153f49d684SMustafa Ismail cqp->hmc_profile = info->hmc_profile;
31163f49d684SMustafa Ismail cqp->ceqs_per_vf = info->ceqs_per_vf;
31173f49d684SMustafa Ismail cqp->disable_packed = info->disable_packed;
31183f49d684SMustafa Ismail cqp->rocev2_rto_policy = info->rocev2_rto_policy;
31193f49d684SMustafa Ismail cqp->protocol_used = info->protocol_used;
31203f49d684SMustafa Ismail memcpy(&cqp->dcqcn_params, &info->dcqcn_params, sizeof(cqp->dcqcn_params));
31213f49d684SMustafa Ismail info->dev->cqp = cqp;
31223f49d684SMustafa Ismail
31233f49d684SMustafa Ismail IRDMA_RING_INIT(cqp->sq_ring, cqp->sq_size);
3124f2c30378SShiraz Saleem cqp->requested_ops = 0;
3125f2c30378SShiraz Saleem atomic64_set(&cqp->completed_ops, 0);
31263f49d684SMustafa Ismail /* for the cqp commands backlog. */
31273f49d684SMustafa Ismail INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head);
31283f49d684SMustafa Ismail
31293f49d684SMustafa Ismail writel(0, cqp->dev->hw_regs[IRDMA_CQPTAIL]);
31303f49d684SMustafa Ismail writel(0, cqp->dev->hw_regs[IRDMA_CQPDB]);
31313f49d684SMustafa Ismail writel(0, cqp->dev->hw_regs[IRDMA_CCQPSTATUS]);
31323f49d684SMustafa Ismail
31333f49d684SMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev),
31343f49d684SMustafa Ismail "WQE: sq_size[%04d] hw_sq_size[%04d] sq_base[%p] sq_pa[%pK] cqp[%p] polarity[x%04x]\n",
31353f49d684SMustafa Ismail cqp->sq_size, cqp->hw_sq_size, cqp->sq_base,
31363f49d684SMustafa Ismail (u64 *)(uintptr_t)cqp->sq_pa, cqp, cqp->polarity);
31373f49d684SMustafa Ismail return 0;
31383f49d684SMustafa Ismail }
31393f49d684SMustafa Ismail
31403f49d684SMustafa Ismail /**
31413f49d684SMustafa Ismail * irdma_sc_cqp_create - create cqp during bringup
31423f49d684SMustafa Ismail * @cqp: struct for cqp hw
31433f49d684SMustafa Ismail * @maj_err: If error, major err number
31443f49d684SMustafa Ismail * @min_err: If error, minor err number
31453f49d684SMustafa Ismail */
irdma_sc_cqp_create(struct irdma_sc_cqp * cqp,u16 * maj_err,u16 * min_err)31462c4b14eaSShiraz Saleem int irdma_sc_cqp_create(struct irdma_sc_cqp *cqp, u16 *maj_err, u16 *min_err)
31473f49d684SMustafa Ismail {
31483f49d684SMustafa Ismail u64 temp;
31493f49d684SMustafa Ismail u8 hw_rev;
31503f49d684SMustafa Ismail u32 cnt = 0, p1, p2, val = 0, err_code;
31512c4b14eaSShiraz Saleem int ret_code;
31523f49d684SMustafa Ismail
31533f49d684SMustafa Ismail hw_rev = cqp->dev->hw_attrs.uk_attrs.hw_rev;
31543f49d684SMustafa Ismail cqp->sdbuf.size = ALIGN(IRDMA_UPDATE_SD_BUFF_SIZE * cqp->sq_size,
31553f49d684SMustafa Ismail IRDMA_SD_BUF_ALIGNMENT);
31563f49d684SMustafa Ismail cqp->sdbuf.va = dma_alloc_coherent(cqp->dev->hw->device,
31573f49d684SMustafa Ismail cqp->sdbuf.size, &cqp->sdbuf.pa,
31583f49d684SMustafa Ismail GFP_KERNEL);
31593f49d684SMustafa Ismail if (!cqp->sdbuf.va)
31602c4b14eaSShiraz Saleem return -ENOMEM;
31613f49d684SMustafa Ismail
31623f49d684SMustafa Ismail spin_lock_init(&cqp->dev->cqp_lock);
31633f49d684SMustafa Ismail
31643f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPHC_SQSIZE, cqp->hw_sq_size) |
31653f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_SVER, cqp->struct_ver) |
31663f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_DISABLE_PFPDUS, cqp->disable_packed) |
31673f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_CEQPERVF, cqp->ceqs_per_vf);
31683f49d684SMustafa Ismail if (hw_rev >= IRDMA_GEN_2) {
31693f49d684SMustafa Ismail temp |= FIELD_PREP(IRDMA_CQPHC_ROCEV2_RTO_POLICY,
31703f49d684SMustafa Ismail cqp->rocev2_rto_policy) |
31713f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_PROTOCOL_USED,
31723f49d684SMustafa Ismail cqp->protocol_used);
31733f49d684SMustafa Ismail }
31743f49d684SMustafa Ismail
31753f49d684SMustafa Ismail set_64bit_val(cqp->host_ctx, 0, temp);
31763f49d684SMustafa Ismail set_64bit_val(cqp->host_ctx, 8, cqp->sq_pa);
31773f49d684SMustafa Ismail
31783f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPHC_ENABLED_VFS, cqp->ena_vf_count) |
31793f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_HMC_PROFILE, cqp->hmc_profile);
31803f49d684SMustafa Ismail set_64bit_val(cqp->host_ctx, 16, temp);
31813f49d684SMustafa Ismail set_64bit_val(cqp->host_ctx, 24, (uintptr_t)cqp);
31823f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPHC_HW_MAJVER, cqp->hw_maj_ver) |
31833f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_HW_MINVER, cqp->hw_min_ver);
31843f49d684SMustafa Ismail if (hw_rev >= IRDMA_GEN_2) {
31853f49d684SMustafa Ismail temp |= FIELD_PREP(IRDMA_CQPHC_MIN_RATE, cqp->dcqcn_params.min_rate) |
31863f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_MIN_DEC_FACTOR, cqp->dcqcn_params.min_dec_factor);
31873f49d684SMustafa Ismail }
31883f49d684SMustafa Ismail set_64bit_val(cqp->host_ctx, 32, temp);
31893f49d684SMustafa Ismail set_64bit_val(cqp->host_ctx, 40, 0);
31903f49d684SMustafa Ismail temp = 0;
31913f49d684SMustafa Ismail if (hw_rev >= IRDMA_GEN_2) {
31923f49d684SMustafa Ismail temp |= FIELD_PREP(IRDMA_CQPHC_DCQCN_T, cqp->dcqcn_params.dcqcn_t) |
31933f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_RAI_FACTOR, cqp->dcqcn_params.rai_factor) |
31943f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_HAI_FACTOR, cqp->dcqcn_params.hai_factor);
31953f49d684SMustafa Ismail }
31963f49d684SMustafa Ismail set_64bit_val(cqp->host_ctx, 48, temp);
31973f49d684SMustafa Ismail temp = 0;
31983f49d684SMustafa Ismail if (hw_rev >= IRDMA_GEN_2) {
31993f49d684SMustafa Ismail temp |= FIELD_PREP(IRDMA_CQPHC_DCQCN_B, cqp->dcqcn_params.dcqcn_b) |
32003f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_DCQCN_F, cqp->dcqcn_params.dcqcn_f) |
32013f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_CC_CFG_VALID, cqp->dcqcn_params.cc_cfg_valid) |
32023f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPHC_RREDUCE_MPERIOD, cqp->dcqcn_params.rreduce_mperiod);
32033f49d684SMustafa Ismail }
32043f49d684SMustafa Ismail set_64bit_val(cqp->host_ctx, 56, temp);
32053f49d684SMustafa Ismail print_hex_dump_debug("WQE: CQP_HOST_CTX WQE", DUMP_PREFIX_OFFSET, 16,
32063f49d684SMustafa Ismail 8, cqp->host_ctx, IRDMA_CQP_CTX_SIZE * 8, false);
32073f49d684SMustafa Ismail p1 = cqp->host_ctx_pa >> 32;
32083f49d684SMustafa Ismail p2 = (u32)cqp->host_ctx_pa;
32093f49d684SMustafa Ismail
32103f49d684SMustafa Ismail writel(p1, cqp->dev->hw_regs[IRDMA_CCQPHIGH]);
32113f49d684SMustafa Ismail writel(p2, cqp->dev->hw_regs[IRDMA_CCQPLOW]);
32123f49d684SMustafa Ismail
32133f49d684SMustafa Ismail do {
32143f49d684SMustafa Ismail if (cnt++ > cqp->dev->hw_attrs.max_done_count) {
32152c4b14eaSShiraz Saleem ret_code = -ETIMEDOUT;
32163f49d684SMustafa Ismail goto err;
32173f49d684SMustafa Ismail }
32183f49d684SMustafa Ismail udelay(cqp->dev->hw_attrs.max_sleep_count);
32193f49d684SMustafa Ismail val = readl(cqp->dev->hw_regs[IRDMA_CCQPSTATUS]);
32203f49d684SMustafa Ismail } while (!val);
32213f49d684SMustafa Ismail
32223f49d684SMustafa Ismail if (FLD_RS_32(cqp->dev, val, IRDMA_CCQPSTATUS_CCQP_ERR)) {
32232c4b14eaSShiraz Saleem ret_code = -EOPNOTSUPP;
32243f49d684SMustafa Ismail goto err;
32253f49d684SMustafa Ismail }
32263f49d684SMustafa Ismail
32273f49d684SMustafa Ismail cqp->process_cqp_sds = irdma_update_sds_noccq;
32283f49d684SMustafa Ismail return 0;
32293f49d684SMustafa Ismail
32303f49d684SMustafa Ismail err:
32313f49d684SMustafa Ismail dma_free_coherent(cqp->dev->hw->device, cqp->sdbuf.size,
32323f49d684SMustafa Ismail cqp->sdbuf.va, cqp->sdbuf.pa);
32333f49d684SMustafa Ismail cqp->sdbuf.va = NULL;
32343f49d684SMustafa Ismail err_code = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]);
32353f49d684SMustafa Ismail *min_err = FIELD_GET(IRDMA_CQPERRCODES_CQP_MINOR_CODE, err_code);
32363f49d684SMustafa Ismail *maj_err = FIELD_GET(IRDMA_CQPERRCODES_CQP_MAJOR_CODE, err_code);
32373f49d684SMustafa Ismail return ret_code;
32383f49d684SMustafa Ismail }
32393f49d684SMustafa Ismail
32403f49d684SMustafa Ismail /**
32413f49d684SMustafa Ismail * irdma_sc_cqp_post_sq - post of cqp's sq
32423f49d684SMustafa Ismail * @cqp: struct for cqp hw
32433f49d684SMustafa Ismail */
irdma_sc_cqp_post_sq(struct irdma_sc_cqp * cqp)32443f49d684SMustafa Ismail void irdma_sc_cqp_post_sq(struct irdma_sc_cqp *cqp)
32453f49d684SMustafa Ismail {
32463f49d684SMustafa Ismail writel(IRDMA_RING_CURRENT_HEAD(cqp->sq_ring), cqp->dev->cqp_db);
32473f49d684SMustafa Ismail
32483f49d684SMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev),
32493f49d684SMustafa Ismail "WQE: CQP SQ head 0x%x tail 0x%x size 0x%x\n",
32503f49d684SMustafa Ismail cqp->sq_ring.head, cqp->sq_ring.tail, cqp->sq_ring.size);
32513f49d684SMustafa Ismail }
32523f49d684SMustafa Ismail
32533f49d684SMustafa Ismail /**
32543f49d684SMustafa Ismail * irdma_sc_cqp_get_next_send_wqe_idx - get next wqe on cqp sq
32553f49d684SMustafa Ismail * and pass back index
32563f49d684SMustafa Ismail * @cqp: CQP HW structure
32573f49d684SMustafa Ismail * @scratch: private data for CQP WQE
32583f49d684SMustafa Ismail * @wqe_idx: WQE index of CQP SQ
32593f49d684SMustafa Ismail */
irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp * cqp,u64 scratch,u32 * wqe_idx)32603f49d684SMustafa Ismail __le64 *irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratch,
32613f49d684SMustafa Ismail u32 *wqe_idx)
32623f49d684SMustafa Ismail {
32633f49d684SMustafa Ismail __le64 *wqe = NULL;
32642c4b14eaSShiraz Saleem int ret_code;
32653f49d684SMustafa Ismail
32663f49d684SMustafa Ismail if (IRDMA_RING_FULL_ERR(cqp->sq_ring)) {
32673f49d684SMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev),
32683f49d684SMustafa Ismail "WQE: CQP SQ is full, head 0x%x tail 0x%x size 0x%x\n",
32693f49d684SMustafa Ismail cqp->sq_ring.head, cqp->sq_ring.tail,
32703f49d684SMustafa Ismail cqp->sq_ring.size);
32713f49d684SMustafa Ismail return NULL;
32723f49d684SMustafa Ismail }
32733f49d684SMustafa Ismail IRDMA_ATOMIC_RING_MOVE_HEAD(cqp->sq_ring, *wqe_idx, ret_code);
32743f49d684SMustafa Ismail if (ret_code)
32753f49d684SMustafa Ismail return NULL;
32763f49d684SMustafa Ismail
3277f2c30378SShiraz Saleem cqp->requested_ops++;
32783f49d684SMustafa Ismail if (!*wqe_idx)
32793f49d684SMustafa Ismail cqp->polarity = !cqp->polarity;
32803f49d684SMustafa Ismail wqe = cqp->sq_base[*wqe_idx].elem;
32813f49d684SMustafa Ismail cqp->scratch_array[*wqe_idx] = scratch;
32823f49d684SMustafa Ismail IRDMA_CQP_INIT_WQE(wqe);
32833f49d684SMustafa Ismail
32843f49d684SMustafa Ismail return wqe;
32853f49d684SMustafa Ismail }
32863f49d684SMustafa Ismail
32873f49d684SMustafa Ismail /**
32883f49d684SMustafa Ismail * irdma_sc_cqp_destroy - destroy cqp during close
32893f49d684SMustafa Ismail * @cqp: struct for cqp hw
32903f49d684SMustafa Ismail */
irdma_sc_cqp_destroy(struct irdma_sc_cqp * cqp)32912c4b14eaSShiraz Saleem int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp)
32923f49d684SMustafa Ismail {
3293cd16b32cSColin Ian King u32 cnt = 0, val;
32942c4b14eaSShiraz Saleem int ret_code = 0;
32953f49d684SMustafa Ismail
32963f49d684SMustafa Ismail writel(0, cqp->dev->hw_regs[IRDMA_CCQPHIGH]);
32973f49d684SMustafa Ismail writel(0, cqp->dev->hw_regs[IRDMA_CCQPLOW]);
32983f49d684SMustafa Ismail do {
32993f49d684SMustafa Ismail if (cnt++ > cqp->dev->hw_attrs.max_done_count) {
33002c4b14eaSShiraz Saleem ret_code = -ETIMEDOUT;
33013f49d684SMustafa Ismail break;
33023f49d684SMustafa Ismail }
33033f49d684SMustafa Ismail udelay(cqp->dev->hw_attrs.max_sleep_count);
33043f49d684SMustafa Ismail val = readl(cqp->dev->hw_regs[IRDMA_CCQPSTATUS]);
33053f49d684SMustafa Ismail } while (FLD_RS_32(cqp->dev, val, IRDMA_CCQPSTATUS_CCQP_DONE));
33063f49d684SMustafa Ismail
33073f49d684SMustafa Ismail dma_free_coherent(cqp->dev->hw->device, cqp->sdbuf.size,
33083f49d684SMustafa Ismail cqp->sdbuf.va, cqp->sdbuf.pa);
33093f49d684SMustafa Ismail cqp->sdbuf.va = NULL;
33103f49d684SMustafa Ismail return ret_code;
33113f49d684SMustafa Ismail }
33123f49d684SMustafa Ismail
33133f49d684SMustafa Ismail /**
33143f49d684SMustafa Ismail * irdma_sc_ccq_arm - enable intr for control cq
33153f49d684SMustafa Ismail * @ccq: ccq sc struct
33163f49d684SMustafa Ismail */
irdma_sc_ccq_arm(struct irdma_sc_cq * ccq)33173f49d684SMustafa Ismail void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq)
33183f49d684SMustafa Ismail {
33193f49d684SMustafa Ismail u64 temp_val;
33203f49d684SMustafa Ismail u16 sw_cq_sel;
33213f49d684SMustafa Ismail u8 arm_next_se;
33223f49d684SMustafa Ismail u8 arm_seq_num;
33233f49d684SMustafa Ismail
33243f49d684SMustafa Ismail get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val);
33253f49d684SMustafa Ismail sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val);
33263f49d684SMustafa Ismail arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val);
33273f49d684SMustafa Ismail arm_seq_num = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_SEQ_NUM, temp_val);
33283f49d684SMustafa Ismail arm_seq_num++;
33293f49d684SMustafa Ismail temp_val = FIELD_PREP(IRDMA_CQ_DBSA_ARM_SEQ_NUM, arm_seq_num) |
33303f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_SW_CQ_SELECT, sw_cq_sel) |
33313f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) |
33323f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1);
33333f49d684SMustafa Ismail set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val);
33343f49d684SMustafa Ismail
33353f49d684SMustafa Ismail dma_wmb(); /* make sure shadow area is updated before arming */
33363f49d684SMustafa Ismail
33373f49d684SMustafa Ismail writel(ccq->cq_uk.cq_id, ccq->dev->cq_arm_db);
33383f49d684SMustafa Ismail }
33393f49d684SMustafa Ismail
33403f49d684SMustafa Ismail /**
33413f49d684SMustafa Ismail * irdma_sc_ccq_get_cqe_info - get ccq's cq entry
33423f49d684SMustafa Ismail * @ccq: ccq sc struct
33433f49d684SMustafa Ismail * @info: completion q entry to return
33443f49d684SMustafa Ismail */
irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq * ccq,struct irdma_ccq_cqe_info * info)33452c4b14eaSShiraz Saleem int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,
33463f49d684SMustafa Ismail struct irdma_ccq_cqe_info *info)
33473f49d684SMustafa Ismail {
33483f49d684SMustafa Ismail u64 qp_ctx, temp, temp1;
33493f49d684SMustafa Ismail __le64 *cqe;
33503f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
33513f49d684SMustafa Ismail u32 wqe_idx;
33523f49d684SMustafa Ismail u32 error;
33533f49d684SMustafa Ismail u8 polarity;
33542c4b14eaSShiraz Saleem int ret_code = 0;
33553f49d684SMustafa Ismail
33563f49d684SMustafa Ismail if (ccq->cq_uk.avoid_mem_cflct)
33573f49d684SMustafa Ismail cqe = IRDMA_GET_CURRENT_EXTENDED_CQ_ELEM(&ccq->cq_uk);
33583f49d684SMustafa Ismail else
33593f49d684SMustafa Ismail cqe = IRDMA_GET_CURRENT_CQ_ELEM(&ccq->cq_uk);
33603f49d684SMustafa Ismail
33613f49d684SMustafa Ismail get_64bit_val(cqe, 24, &temp);
33623f49d684SMustafa Ismail polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, temp);
33633f49d684SMustafa Ismail if (polarity != ccq->cq_uk.polarity)
33642c4b14eaSShiraz Saleem return -ENOENT;
33653f49d684SMustafa Ismail
33664984eb51SShiraz Saleem /* Ensure CEQE contents are read after valid bit is checked */
33674984eb51SShiraz Saleem dma_rmb();
33684984eb51SShiraz Saleem
33693f49d684SMustafa Ismail get_64bit_val(cqe, 8, &qp_ctx);
33703f49d684SMustafa Ismail cqp = (struct irdma_sc_cqp *)(unsigned long)qp_ctx;
33713f49d684SMustafa Ismail info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, temp);
33723f49d684SMustafa Ismail info->maj_err_code = IRDMA_CQPSQ_MAJ_NO_ERROR;
33733f49d684SMustafa Ismail info->min_err_code = (u16)FIELD_GET(IRDMA_CQ_MINERR, temp);
33743f49d684SMustafa Ismail if (info->error) {
33753f49d684SMustafa Ismail info->maj_err_code = (u16)FIELD_GET(IRDMA_CQ_MAJERR, temp);
33763f49d684SMustafa Ismail error = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]);
33773f49d684SMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev),
33783f49d684SMustafa Ismail "CQP: CQPERRCODES error_code[x%08X]\n", error);
33793f49d684SMustafa Ismail }
33803f49d684SMustafa Ismail
33813f49d684SMustafa Ismail wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, temp);
33823f49d684SMustafa Ismail info->scratch = cqp->scratch_array[wqe_idx];
33833f49d684SMustafa Ismail
33843f49d684SMustafa Ismail get_64bit_val(cqe, 16, &temp1);
33853f49d684SMustafa Ismail info->op_ret_val = (u32)FIELD_GET(IRDMA_CCQ_OPRETVAL, temp1);
33863f49d684SMustafa Ismail get_64bit_val(cqp->sq_base[wqe_idx].elem, 24, &temp1);
33873f49d684SMustafa Ismail info->op_code = (u8)FIELD_GET(IRDMA_CQPSQ_OPCODE, temp1);
33883f49d684SMustafa Ismail info->cqp = cqp;
33893f49d684SMustafa Ismail
33903f49d684SMustafa Ismail /* move the head for cq */
33913f49d684SMustafa Ismail IRDMA_RING_MOVE_HEAD(ccq->cq_uk.cq_ring, ret_code);
33923f49d684SMustafa Ismail if (!IRDMA_RING_CURRENT_HEAD(ccq->cq_uk.cq_ring))
33933f49d684SMustafa Ismail ccq->cq_uk.polarity ^= 1;
33943f49d684SMustafa Ismail
33953f49d684SMustafa Ismail /* update cq tail in cq shadow memory also */
33963f49d684SMustafa Ismail IRDMA_RING_MOVE_TAIL(ccq->cq_uk.cq_ring);
33973f49d684SMustafa Ismail set_64bit_val(ccq->cq_uk.shadow_area, 0,
33983f49d684SMustafa Ismail IRDMA_RING_CURRENT_HEAD(ccq->cq_uk.cq_ring));
33993f49d684SMustafa Ismail
34003f49d684SMustafa Ismail dma_wmb(); /* make sure shadow area is updated before moving tail */
34013f49d684SMustafa Ismail
34023f49d684SMustafa Ismail IRDMA_RING_MOVE_TAIL(cqp->sq_ring);
3403f2c30378SShiraz Saleem atomic64_inc(&cqp->completed_ops);
34043f49d684SMustafa Ismail
34053f49d684SMustafa Ismail return ret_code;
34063f49d684SMustafa Ismail }
34073f49d684SMustafa Ismail
34083f49d684SMustafa Ismail /**
34093f49d684SMustafa Ismail * irdma_sc_poll_for_cqp_op_done - Waits for last write to complete in CQP SQ
34103f49d684SMustafa Ismail * @cqp: struct for cqp hw
34113f49d684SMustafa Ismail * @op_code: cqp opcode for completion
34123f49d684SMustafa Ismail * @compl_info: completion q entry to return
34133f49d684SMustafa Ismail */
irdma_sc_poll_for_cqp_op_done(struct irdma_sc_cqp * cqp,u8 op_code,struct irdma_ccq_cqe_info * compl_info)34142c4b14eaSShiraz Saleem int irdma_sc_poll_for_cqp_op_done(struct irdma_sc_cqp *cqp, u8 op_code,
34153f49d684SMustafa Ismail struct irdma_ccq_cqe_info *compl_info)
34163f49d684SMustafa Ismail {
34173f49d684SMustafa Ismail struct irdma_ccq_cqe_info info = {};
34183f49d684SMustafa Ismail struct irdma_sc_cq *ccq;
34192c4b14eaSShiraz Saleem int ret_code = 0;
34203f49d684SMustafa Ismail u32 cnt = 0;
34213f49d684SMustafa Ismail
34223f49d684SMustafa Ismail ccq = cqp->dev->ccq;
34233f49d684SMustafa Ismail while (1) {
34243f49d684SMustafa Ismail if (cnt++ > 100 * cqp->dev->hw_attrs.max_done_count)
34252c4b14eaSShiraz Saleem return -ETIMEDOUT;
34263f49d684SMustafa Ismail
34273f49d684SMustafa Ismail if (irdma_sc_ccq_get_cqe_info(ccq, &info)) {
34283f49d684SMustafa Ismail udelay(cqp->dev->hw_attrs.max_sleep_count);
34293f49d684SMustafa Ismail continue;
34303f49d684SMustafa Ismail }
34313f49d684SMustafa Ismail if (info.error && info.op_code != IRDMA_CQP_OP_QUERY_STAG) {
34322c4b14eaSShiraz Saleem ret_code = -EIO;
34333f49d684SMustafa Ismail break;
34343f49d684SMustafa Ismail }
34353f49d684SMustafa Ismail /* make sure op code matches*/
34363f49d684SMustafa Ismail if (op_code == info.op_code)
34373f49d684SMustafa Ismail break;
34383f49d684SMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev),
34393f49d684SMustafa Ismail "WQE: opcode mismatch for my op code 0x%x, returned opcode %x\n",
34403f49d684SMustafa Ismail op_code, info.op_code);
34413f49d684SMustafa Ismail }
34423f49d684SMustafa Ismail
34433f49d684SMustafa Ismail if (compl_info)
34443f49d684SMustafa Ismail memcpy(compl_info, &info, sizeof(*compl_info));
34453f49d684SMustafa Ismail
34463f49d684SMustafa Ismail return ret_code;
34473f49d684SMustafa Ismail }
34483f49d684SMustafa Ismail
34493f49d684SMustafa Ismail /**
34503f49d684SMustafa Ismail * irdma_sc_manage_hmc_pm_func_table - manage of function table
34513f49d684SMustafa Ismail * @cqp: struct for cqp hw
34523f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
34533f49d684SMustafa Ismail * @info: info for the manage function table operation
34543f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
34553f49d684SMustafa Ismail */
irdma_sc_manage_hmc_pm_func_table(struct irdma_sc_cqp * cqp,struct irdma_hmc_fcn_info * info,u64 scratch,bool post_sq)34562c4b14eaSShiraz Saleem static int irdma_sc_manage_hmc_pm_func_table(struct irdma_sc_cqp *cqp,
34573f49d684SMustafa Ismail struct irdma_hmc_fcn_info *info,
34583f49d684SMustafa Ismail u64 scratch, bool post_sq)
34593f49d684SMustafa Ismail {
34603f49d684SMustafa Ismail __le64 *wqe;
34613f49d684SMustafa Ismail u64 hdr;
34623f49d684SMustafa Ismail
34633f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
34643f49d684SMustafa Ismail if (!wqe)
34652c4b14eaSShiraz Saleem return -ENOMEM;
34663f49d684SMustafa Ismail
34673f49d684SMustafa Ismail set_64bit_val(wqe, 0, 0);
34683f49d684SMustafa Ismail set_64bit_val(wqe, 8, 0);
34693f49d684SMustafa Ismail set_64bit_val(wqe, 16, 0);
34703f49d684SMustafa Ismail set_64bit_val(wqe, 32, 0);
34713f49d684SMustafa Ismail set_64bit_val(wqe, 40, 0);
34723f49d684SMustafa Ismail set_64bit_val(wqe, 48, 0);
34733f49d684SMustafa Ismail set_64bit_val(wqe, 56, 0);
34743f49d684SMustafa Ismail
34753f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_MHMC_VFIDX, info->vf_id) |
34763f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE,
34773f49d684SMustafa Ismail IRDMA_CQP_OP_MANAGE_HMC_PM_FUNC_TABLE) |
34783f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_MHMC_FREEPMFN, info->free_fcn) |
34793f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
34803f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
34813f49d684SMustafa Ismail
34823f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
34833f49d684SMustafa Ismail
34843f49d684SMustafa Ismail print_hex_dump_debug("WQE: MANAGE_HMC_PM_FUNC_TABLE WQE",
34853f49d684SMustafa Ismail DUMP_PREFIX_OFFSET, 16, 8, wqe,
34863f49d684SMustafa Ismail IRDMA_CQP_WQE_SIZE * 8, false);
34873f49d684SMustafa Ismail if (post_sq)
34883f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
34893f49d684SMustafa Ismail
34903f49d684SMustafa Ismail return 0;
34913f49d684SMustafa Ismail }
34923f49d684SMustafa Ismail
34933f49d684SMustafa Ismail /**
34943f49d684SMustafa Ismail * irdma_sc_commit_fpm_val_done - wait for cqp eqe completion
34953f49d684SMustafa Ismail * for fpm commit
34963f49d684SMustafa Ismail * @cqp: struct for cqp hw
34973f49d684SMustafa Ismail */
irdma_sc_commit_fpm_val_done(struct irdma_sc_cqp * cqp)34982c4b14eaSShiraz Saleem static int irdma_sc_commit_fpm_val_done(struct irdma_sc_cqp *cqp)
34993f49d684SMustafa Ismail {
35003f49d684SMustafa Ismail return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_COMMIT_FPM_VAL,
35013f49d684SMustafa Ismail NULL);
35023f49d684SMustafa Ismail }
35033f49d684SMustafa Ismail
35043f49d684SMustafa Ismail /**
35053f49d684SMustafa Ismail * irdma_sc_commit_fpm_val - cqp wqe for commit fpm values
35063f49d684SMustafa Ismail * @cqp: struct for cqp hw
35073f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
35083f49d684SMustafa Ismail * @hmc_fn_id: hmc function id
35093f49d684SMustafa Ismail * @commit_fpm_mem: Memory for fpm values
35103f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
35113f49d684SMustafa Ismail * @wait_type: poll ccq or cqp registers for cqp completion
35123f49d684SMustafa Ismail */
irdma_sc_commit_fpm_val(struct irdma_sc_cqp * cqp,u64 scratch,u8 hmc_fn_id,struct irdma_dma_mem * commit_fpm_mem,bool post_sq,u8 wait_type)35132c4b14eaSShiraz Saleem static int irdma_sc_commit_fpm_val(struct irdma_sc_cqp *cqp, u64 scratch,
35142c4b14eaSShiraz Saleem u8 hmc_fn_id,
35152c4b14eaSShiraz Saleem struct irdma_dma_mem *commit_fpm_mem,
35162c4b14eaSShiraz Saleem bool post_sq, u8 wait_type)
35173f49d684SMustafa Ismail {
35183f49d684SMustafa Ismail __le64 *wqe;
35193f49d684SMustafa Ismail u64 hdr;
35203f49d684SMustafa Ismail u32 tail, val, error;
35212c4b14eaSShiraz Saleem int ret_code = 0;
35223f49d684SMustafa Ismail
35233f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
35243f49d684SMustafa Ismail if (!wqe)
35252c4b14eaSShiraz Saleem return -ENOMEM;
35263f49d684SMustafa Ismail
35273f49d684SMustafa Ismail set_64bit_val(wqe, 16, hmc_fn_id);
35283f49d684SMustafa Ismail set_64bit_val(wqe, 32, commit_fpm_mem->pa);
35293f49d684SMustafa Ismail
35303f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_BUFSIZE, IRDMA_COMMIT_FPM_BUF_SIZE) |
35313f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_COMMIT_FPM_VAL) |
35323f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
35333f49d684SMustafa Ismail
35343f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
35353f49d684SMustafa Ismail
35363f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
35373f49d684SMustafa Ismail
35383f49d684SMustafa Ismail print_hex_dump_debug("WQE: COMMIT_FPM_VAL WQE", DUMP_PREFIX_OFFSET,
35393f49d684SMustafa Ismail 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
35403f49d684SMustafa Ismail irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
35413f49d684SMustafa Ismail
35423f49d684SMustafa Ismail if (post_sq) {
35433f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
35443f49d684SMustafa Ismail if (wait_type == IRDMA_CQP_WAIT_POLL_REGS)
35453f49d684SMustafa Ismail ret_code = irdma_cqp_poll_registers(cqp, tail,
35463f49d684SMustafa Ismail cqp->dev->hw_attrs.max_done_count);
35473f49d684SMustafa Ismail else if (wait_type == IRDMA_CQP_WAIT_POLL_CQ)
35483f49d684SMustafa Ismail ret_code = irdma_sc_commit_fpm_val_done(cqp);
35493f49d684SMustafa Ismail }
35503f49d684SMustafa Ismail
35513f49d684SMustafa Ismail return ret_code;
35523f49d684SMustafa Ismail }
35533f49d684SMustafa Ismail
35543f49d684SMustafa Ismail /**
35553f49d684SMustafa Ismail * irdma_sc_query_fpm_val_done - poll for cqp wqe completion for
35563f49d684SMustafa Ismail * query fpm
35573f49d684SMustafa Ismail * @cqp: struct for cqp hw
35583f49d684SMustafa Ismail */
irdma_sc_query_fpm_val_done(struct irdma_sc_cqp * cqp)35592c4b14eaSShiraz Saleem static int irdma_sc_query_fpm_val_done(struct irdma_sc_cqp *cqp)
35603f49d684SMustafa Ismail {
35613f49d684SMustafa Ismail return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_QUERY_FPM_VAL,
35623f49d684SMustafa Ismail NULL);
35633f49d684SMustafa Ismail }
35643f49d684SMustafa Ismail
35653f49d684SMustafa Ismail /**
35663f49d684SMustafa Ismail * irdma_sc_query_fpm_val - cqp wqe query fpm values
35673f49d684SMustafa Ismail * @cqp: struct for cqp hw
35683f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
35693f49d684SMustafa Ismail * @hmc_fn_id: hmc function id
35703f49d684SMustafa Ismail * @query_fpm_mem: memory for return fpm values
35713f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
35723f49d684SMustafa Ismail * @wait_type: poll ccq or cqp registers for cqp completion
35733f49d684SMustafa Ismail */
irdma_sc_query_fpm_val(struct irdma_sc_cqp * cqp,u64 scratch,u8 hmc_fn_id,struct irdma_dma_mem * query_fpm_mem,bool post_sq,u8 wait_type)35742c4b14eaSShiraz Saleem static int irdma_sc_query_fpm_val(struct irdma_sc_cqp *cqp, u64 scratch,
35752c4b14eaSShiraz Saleem u8 hmc_fn_id,
35762c4b14eaSShiraz Saleem struct irdma_dma_mem *query_fpm_mem,
35772c4b14eaSShiraz Saleem bool post_sq, u8 wait_type)
35783f49d684SMustafa Ismail {
35793f49d684SMustafa Ismail __le64 *wqe;
35803f49d684SMustafa Ismail u64 hdr;
35813f49d684SMustafa Ismail u32 tail, val, error;
35822c4b14eaSShiraz Saleem int ret_code = 0;
35833f49d684SMustafa Ismail
35843f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
35853f49d684SMustafa Ismail if (!wqe)
35862c4b14eaSShiraz Saleem return -ENOMEM;
35873f49d684SMustafa Ismail
35883f49d684SMustafa Ismail set_64bit_val(wqe, 16, hmc_fn_id);
35893f49d684SMustafa Ismail set_64bit_val(wqe, 32, query_fpm_mem->pa);
35903f49d684SMustafa Ismail
35913f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_QUERY_FPM_VAL) |
35923f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
35933f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
35943f49d684SMustafa Ismail
35953f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
35963f49d684SMustafa Ismail
35973f49d684SMustafa Ismail print_hex_dump_debug("WQE: QUERY_FPM WQE", DUMP_PREFIX_OFFSET, 16, 8,
35983f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
35993f49d684SMustafa Ismail irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
36003f49d684SMustafa Ismail
36013f49d684SMustafa Ismail if (post_sq) {
36023f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
36033f49d684SMustafa Ismail if (wait_type == IRDMA_CQP_WAIT_POLL_REGS)
36043f49d684SMustafa Ismail ret_code = irdma_cqp_poll_registers(cqp, tail,
36053f49d684SMustafa Ismail cqp->dev->hw_attrs.max_done_count);
36063f49d684SMustafa Ismail else if (wait_type == IRDMA_CQP_WAIT_POLL_CQ)
36073f49d684SMustafa Ismail ret_code = irdma_sc_query_fpm_val_done(cqp);
36083f49d684SMustafa Ismail }
36093f49d684SMustafa Ismail
36103f49d684SMustafa Ismail return ret_code;
36113f49d684SMustafa Ismail }
36123f49d684SMustafa Ismail
36133f49d684SMustafa Ismail /**
36143f49d684SMustafa Ismail * irdma_sc_ceq_init - initialize ceq
36153f49d684SMustafa Ismail * @ceq: ceq sc structure
36163f49d684SMustafa Ismail * @info: ceq initialization info
36173f49d684SMustafa Ismail */
irdma_sc_ceq_init(struct irdma_sc_ceq * ceq,struct irdma_ceq_init_info * info)36182c4b14eaSShiraz Saleem int irdma_sc_ceq_init(struct irdma_sc_ceq *ceq,
36193f49d684SMustafa Ismail struct irdma_ceq_init_info *info)
36203f49d684SMustafa Ismail {
36213f49d684SMustafa Ismail u32 pble_obj_cnt;
36223f49d684SMustafa Ismail
36233f49d684SMustafa Ismail if (info->elem_cnt < info->dev->hw_attrs.min_hw_ceq_size ||
36243f49d684SMustafa Ismail info->elem_cnt > info->dev->hw_attrs.max_hw_ceq_size)
36252c4b14eaSShiraz Saleem return -EINVAL;
36263f49d684SMustafa Ismail
36276f6dbb81SDan Carpenter if (info->ceq_id >= info->dev->hmc_fpm_misc.max_ceqs)
36282c4b14eaSShiraz Saleem return -EINVAL;
36293f49d684SMustafa Ismail pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
36303f49d684SMustafa Ismail
36313f49d684SMustafa Ismail if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt)
36322c4b14eaSShiraz Saleem return -EINVAL;
36333f49d684SMustafa Ismail
36343f49d684SMustafa Ismail ceq->size = sizeof(*ceq);
36353f49d684SMustafa Ismail ceq->ceqe_base = (struct irdma_ceqe *)info->ceqe_base;
36363f49d684SMustafa Ismail ceq->ceq_id = info->ceq_id;
36373f49d684SMustafa Ismail ceq->dev = info->dev;
36383f49d684SMustafa Ismail ceq->elem_cnt = info->elem_cnt;
36393f49d684SMustafa Ismail ceq->ceq_elem_pa = info->ceqe_pa;
36403f49d684SMustafa Ismail ceq->virtual_map = info->virtual_map;
36413f49d684SMustafa Ismail ceq->itr_no_expire = info->itr_no_expire;
36423f49d684SMustafa Ismail ceq->reg_cq = info->reg_cq;
36433f49d684SMustafa Ismail ceq->reg_cq_size = 0;
36443f49d684SMustafa Ismail spin_lock_init(&ceq->req_cq_lock);
36453f49d684SMustafa Ismail ceq->pbl_chunk_size = (ceq->virtual_map ? info->pbl_chunk_size : 0);
36463f49d684SMustafa Ismail ceq->first_pm_pbl_idx = (ceq->virtual_map ? info->first_pm_pbl_idx : 0);
36473f49d684SMustafa Ismail ceq->pbl_list = (ceq->virtual_map ? info->pbl_list : NULL);
36483f49d684SMustafa Ismail ceq->tph_en = info->tph_en;
36493f49d684SMustafa Ismail ceq->tph_val = info->tph_val;
36503f49d684SMustafa Ismail ceq->vsi = info->vsi;
36513f49d684SMustafa Ismail ceq->polarity = 1;
36523f49d684SMustafa Ismail IRDMA_RING_INIT(ceq->ceq_ring, ceq->elem_cnt);
36533f49d684SMustafa Ismail ceq->dev->ceq[info->ceq_id] = ceq;
36543f49d684SMustafa Ismail
36553f49d684SMustafa Ismail return 0;
36563f49d684SMustafa Ismail }
36573f49d684SMustafa Ismail
36583f49d684SMustafa Ismail /**
36593f49d684SMustafa Ismail * irdma_sc_ceq_create - create ceq wqe
36603f49d684SMustafa Ismail * @ceq: ceq sc structure
36613f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
36623f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
36633f49d684SMustafa Ismail */
36643f49d684SMustafa Ismail
irdma_sc_ceq_create(struct irdma_sc_ceq * ceq,u64 scratch,bool post_sq)36652c4b14eaSShiraz Saleem static int irdma_sc_ceq_create(struct irdma_sc_ceq *ceq, u64 scratch,
36663f49d684SMustafa Ismail bool post_sq)
36673f49d684SMustafa Ismail {
36683f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
36693f49d684SMustafa Ismail __le64 *wqe;
36703f49d684SMustafa Ismail u64 hdr;
36713f49d684SMustafa Ismail
36723f49d684SMustafa Ismail cqp = ceq->dev->cqp;
36733f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
36743f49d684SMustafa Ismail if (!wqe)
36752c4b14eaSShiraz Saleem return -ENOMEM;
36763f49d684SMustafa Ismail set_64bit_val(wqe, 16, ceq->elem_cnt);
36773f49d684SMustafa Ismail set_64bit_val(wqe, 32,
36783f49d684SMustafa Ismail (ceq->virtual_map ? 0 : ceq->ceq_elem_pa));
36793f49d684SMustafa Ismail set_64bit_val(wqe, 48,
36803f49d684SMustafa Ismail (ceq->virtual_map ? ceq->first_pm_pbl_idx : 0));
36813f49d684SMustafa Ismail set_64bit_val(wqe, 56,
36823f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHVAL, ceq->tph_val) |
36833f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_VSIIDX, ceq->vsi->vsi_idx));
36843f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_CEQ_CEQID, ceq->ceq_id) |
36853f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_CEQ) |
36863f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CEQ_LPBLSIZE, ceq->pbl_chunk_size) |
36873f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CEQ_VMAP, ceq->virtual_map) |
36883f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CEQ_ITRNOEXPIRE, ceq->itr_no_expire) |
36893f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHEN, ceq->tph_en) |
36903f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
36913f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
36923f49d684SMustafa Ismail
36933f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
36943f49d684SMustafa Ismail
36953f49d684SMustafa Ismail print_hex_dump_debug("WQE: CEQ_CREATE WQE", DUMP_PREFIX_OFFSET, 16, 8,
36963f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
36973f49d684SMustafa Ismail if (post_sq)
36983f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
36993f49d684SMustafa Ismail
37003f49d684SMustafa Ismail return 0;
37013f49d684SMustafa Ismail }
37023f49d684SMustafa Ismail
37033f49d684SMustafa Ismail /**
37043f49d684SMustafa Ismail * irdma_sc_cceq_create_done - poll for control ceq wqe to complete
37053f49d684SMustafa Ismail * @ceq: ceq sc structure
37063f49d684SMustafa Ismail */
irdma_sc_cceq_create_done(struct irdma_sc_ceq * ceq)37072c4b14eaSShiraz Saleem static int irdma_sc_cceq_create_done(struct irdma_sc_ceq *ceq)
37083f49d684SMustafa Ismail {
37093f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
37103f49d684SMustafa Ismail
37113f49d684SMustafa Ismail cqp = ceq->dev->cqp;
37123f49d684SMustafa Ismail return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_CREATE_CEQ,
37133f49d684SMustafa Ismail NULL);
37143f49d684SMustafa Ismail }
37153f49d684SMustafa Ismail
37163f49d684SMustafa Ismail /**
37173f49d684SMustafa Ismail * irdma_sc_cceq_destroy_done - poll for destroy cceq to complete
37183f49d684SMustafa Ismail * @ceq: ceq sc structure
37193f49d684SMustafa Ismail */
irdma_sc_cceq_destroy_done(struct irdma_sc_ceq * ceq)37202c4b14eaSShiraz Saleem int irdma_sc_cceq_destroy_done(struct irdma_sc_ceq *ceq)
37213f49d684SMustafa Ismail {
37223f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
37233f49d684SMustafa Ismail
37243f49d684SMustafa Ismail if (ceq->reg_cq)
37253f49d684SMustafa Ismail irdma_sc_remove_cq_ctx(ceq, ceq->dev->ccq);
37263f49d684SMustafa Ismail
37273f49d684SMustafa Ismail cqp = ceq->dev->cqp;
37283f49d684SMustafa Ismail cqp->process_cqp_sds = irdma_update_sds_noccq;
37293f49d684SMustafa Ismail
37303f49d684SMustafa Ismail return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_DESTROY_CEQ,
37313f49d684SMustafa Ismail NULL);
37323f49d684SMustafa Ismail }
37333f49d684SMustafa Ismail
37343f49d684SMustafa Ismail /**
37353f49d684SMustafa Ismail * irdma_sc_cceq_create - create cceq
37363f49d684SMustafa Ismail * @ceq: ceq sc structure
37373f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
37383f49d684SMustafa Ismail */
irdma_sc_cceq_create(struct irdma_sc_ceq * ceq,u64 scratch)37392c4b14eaSShiraz Saleem int irdma_sc_cceq_create(struct irdma_sc_ceq *ceq, u64 scratch)
37403f49d684SMustafa Ismail {
37412c4b14eaSShiraz Saleem int ret_code;
37423f49d684SMustafa Ismail struct irdma_sc_dev *dev = ceq->dev;
37433f49d684SMustafa Ismail
37443f49d684SMustafa Ismail dev->ccq->vsi = ceq->vsi;
37453f49d684SMustafa Ismail if (ceq->reg_cq) {
37463f49d684SMustafa Ismail ret_code = irdma_sc_add_cq_ctx(ceq, ceq->dev->ccq);
37473f49d684SMustafa Ismail if (ret_code)
37483f49d684SMustafa Ismail return ret_code;
37493f49d684SMustafa Ismail }
37503f49d684SMustafa Ismail
37513f49d684SMustafa Ismail ret_code = irdma_sc_ceq_create(ceq, scratch, true);
37523f49d684SMustafa Ismail if (!ret_code)
37533f49d684SMustafa Ismail return irdma_sc_cceq_create_done(ceq);
37543f49d684SMustafa Ismail
37553f49d684SMustafa Ismail return ret_code;
37563f49d684SMustafa Ismail }
37573f49d684SMustafa Ismail
37583f49d684SMustafa Ismail /**
37593f49d684SMustafa Ismail * irdma_sc_ceq_destroy - destroy ceq
37603f49d684SMustafa Ismail * @ceq: ceq sc structure
37613f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
37623f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
37633f49d684SMustafa Ismail */
irdma_sc_ceq_destroy(struct irdma_sc_ceq * ceq,u64 scratch,bool post_sq)37642c4b14eaSShiraz Saleem int irdma_sc_ceq_destroy(struct irdma_sc_ceq *ceq, u64 scratch, bool post_sq)
37653f49d684SMustafa Ismail {
37663f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
37673f49d684SMustafa Ismail __le64 *wqe;
37683f49d684SMustafa Ismail u64 hdr;
37693f49d684SMustafa Ismail
37703f49d684SMustafa Ismail cqp = ceq->dev->cqp;
37713f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
37723f49d684SMustafa Ismail if (!wqe)
37732c4b14eaSShiraz Saleem return -ENOMEM;
37743f49d684SMustafa Ismail
37753f49d684SMustafa Ismail set_64bit_val(wqe, 16, ceq->elem_cnt);
37763f49d684SMustafa Ismail set_64bit_val(wqe, 48, ceq->first_pm_pbl_idx);
37773f49d684SMustafa Ismail hdr = ceq->ceq_id |
37783f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_CEQ) |
37793f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CEQ_LPBLSIZE, ceq->pbl_chunk_size) |
37803f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CEQ_VMAP, ceq->virtual_map) |
37813f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHEN, ceq->tph_en) |
37823f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
37833f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
37843f49d684SMustafa Ismail
37853f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
37863f49d684SMustafa Ismail
37873f49d684SMustafa Ismail print_hex_dump_debug("WQE: CEQ_DESTROY WQE", DUMP_PREFIX_OFFSET, 16,
37883f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
37893f49d684SMustafa Ismail if (post_sq)
37903f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
37913f49d684SMustafa Ismail
37923f49d684SMustafa Ismail return 0;
37933f49d684SMustafa Ismail }
37943f49d684SMustafa Ismail
37953f49d684SMustafa Ismail /**
37963f49d684SMustafa Ismail * irdma_sc_process_ceq - process ceq
37973f49d684SMustafa Ismail * @dev: sc device struct
37983f49d684SMustafa Ismail * @ceq: ceq sc structure
37993f49d684SMustafa Ismail *
38003f49d684SMustafa Ismail * It is expected caller serializes this function with cleanup_ceqes()
38013f49d684SMustafa Ismail * because these functions manipulate the same ceq
38023f49d684SMustafa Ismail */
irdma_sc_process_ceq(struct irdma_sc_dev * dev,struct irdma_sc_ceq * ceq)38033f49d684SMustafa Ismail void *irdma_sc_process_ceq(struct irdma_sc_dev *dev, struct irdma_sc_ceq *ceq)
38043f49d684SMustafa Ismail {
38053f49d684SMustafa Ismail u64 temp;
38063f49d684SMustafa Ismail __le64 *ceqe;
38073f49d684SMustafa Ismail struct irdma_sc_cq *cq = NULL;
38083f49d684SMustafa Ismail struct irdma_sc_cq *temp_cq;
38093f49d684SMustafa Ismail u8 polarity;
38103f49d684SMustafa Ismail u32 cq_idx;
38113f49d684SMustafa Ismail unsigned long flags;
38123f49d684SMustafa Ismail
38133f49d684SMustafa Ismail do {
38143f49d684SMustafa Ismail cq_idx = 0;
38153f49d684SMustafa Ismail ceqe = IRDMA_GET_CURRENT_CEQ_ELEM(ceq);
38163f49d684SMustafa Ismail get_64bit_val(ceqe, 0, &temp);
38173f49d684SMustafa Ismail polarity = (u8)FIELD_GET(IRDMA_CEQE_VALID, temp);
38183f49d684SMustafa Ismail if (polarity != ceq->polarity)
38193f49d684SMustafa Ismail return NULL;
38203f49d684SMustafa Ismail
38213f49d684SMustafa Ismail temp_cq = (struct irdma_sc_cq *)(unsigned long)(temp << 1);
38223f49d684SMustafa Ismail if (!temp_cq) {
38233f49d684SMustafa Ismail cq_idx = IRDMA_INVALID_CQ_IDX;
38243f49d684SMustafa Ismail IRDMA_RING_MOVE_TAIL(ceq->ceq_ring);
38253f49d684SMustafa Ismail
38263f49d684SMustafa Ismail if (!IRDMA_RING_CURRENT_TAIL(ceq->ceq_ring))
38273f49d684SMustafa Ismail ceq->polarity ^= 1;
38283f49d684SMustafa Ismail continue;
38293f49d684SMustafa Ismail }
38303f49d684SMustafa Ismail
38313f49d684SMustafa Ismail cq = temp_cq;
38323f49d684SMustafa Ismail if (ceq->reg_cq) {
38333f49d684SMustafa Ismail spin_lock_irqsave(&ceq->req_cq_lock, flags);
38343f49d684SMustafa Ismail cq_idx = irdma_sc_find_reg_cq(ceq, cq);
38353f49d684SMustafa Ismail spin_unlock_irqrestore(&ceq->req_cq_lock, flags);
38363f49d684SMustafa Ismail }
38373f49d684SMustafa Ismail
38383f49d684SMustafa Ismail IRDMA_RING_MOVE_TAIL(ceq->ceq_ring);
38393f49d684SMustafa Ismail if (!IRDMA_RING_CURRENT_TAIL(ceq->ceq_ring))
38403f49d684SMustafa Ismail ceq->polarity ^= 1;
38413f49d684SMustafa Ismail } while (cq_idx == IRDMA_INVALID_CQ_IDX);
38423f49d684SMustafa Ismail
38433f49d684SMustafa Ismail if (cq)
38443f49d684SMustafa Ismail irdma_sc_cq_ack(cq);
38453f49d684SMustafa Ismail return cq;
38463f49d684SMustafa Ismail }
38473f49d684SMustafa Ismail
38483f49d684SMustafa Ismail /**
38493f49d684SMustafa Ismail * irdma_sc_cleanup_ceqes - clear the valid ceqes ctx matching the cq
38503f49d684SMustafa Ismail * @cq: cq for which the ceqes need to be cleaned up
38513f49d684SMustafa Ismail * @ceq: ceq ptr
38523f49d684SMustafa Ismail *
38533f49d684SMustafa Ismail * The function is called after the cq is destroyed to cleanup
38543f49d684SMustafa Ismail * its pending ceqe entries. It is expected caller serializes this
38553f49d684SMustafa Ismail * function with process_ceq() in interrupt context.
38563f49d684SMustafa Ismail */
irdma_sc_cleanup_ceqes(struct irdma_sc_cq * cq,struct irdma_sc_ceq * ceq)38573f49d684SMustafa Ismail void irdma_sc_cleanup_ceqes(struct irdma_sc_cq *cq, struct irdma_sc_ceq *ceq)
38583f49d684SMustafa Ismail {
38593f49d684SMustafa Ismail struct irdma_sc_cq *next_cq;
38603f49d684SMustafa Ismail u8 ceq_polarity = ceq->polarity;
38613f49d684SMustafa Ismail __le64 *ceqe;
38623f49d684SMustafa Ismail u8 polarity;
38633f49d684SMustafa Ismail u64 temp;
38643f49d684SMustafa Ismail int next;
38653f49d684SMustafa Ismail u32 i;
38663f49d684SMustafa Ismail
38673f49d684SMustafa Ismail next = IRDMA_RING_GET_NEXT_TAIL(ceq->ceq_ring, 0);
38683f49d684SMustafa Ismail
38693f49d684SMustafa Ismail for (i = 1; i <= IRDMA_RING_SIZE(*ceq); i++) {
38703f49d684SMustafa Ismail ceqe = IRDMA_GET_CEQ_ELEM_AT_POS(ceq, next);
38713f49d684SMustafa Ismail
38723f49d684SMustafa Ismail get_64bit_val(ceqe, 0, &temp);
38733f49d684SMustafa Ismail polarity = (u8)FIELD_GET(IRDMA_CEQE_VALID, temp);
38743f49d684SMustafa Ismail if (polarity != ceq_polarity)
38753f49d684SMustafa Ismail return;
38763f49d684SMustafa Ismail
38773f49d684SMustafa Ismail next_cq = (struct irdma_sc_cq *)(unsigned long)(temp << 1);
38783f49d684SMustafa Ismail if (cq == next_cq)
38793f49d684SMustafa Ismail set_64bit_val(ceqe, 0, temp & IRDMA_CEQE_VALID);
38803f49d684SMustafa Ismail
38813f49d684SMustafa Ismail next = IRDMA_RING_GET_NEXT_TAIL(ceq->ceq_ring, i);
38823f49d684SMustafa Ismail if (!next)
38833f49d684SMustafa Ismail ceq_polarity ^= 1;
38843f49d684SMustafa Ismail }
38853f49d684SMustafa Ismail }
38863f49d684SMustafa Ismail
38873f49d684SMustafa Ismail /**
38883f49d684SMustafa Ismail * irdma_sc_aeq_init - initialize aeq
38893f49d684SMustafa Ismail * @aeq: aeq structure ptr
38903f49d684SMustafa Ismail * @info: aeq initialization info
38913f49d684SMustafa Ismail */
irdma_sc_aeq_init(struct irdma_sc_aeq * aeq,struct irdma_aeq_init_info * info)38922c4b14eaSShiraz Saleem int irdma_sc_aeq_init(struct irdma_sc_aeq *aeq,
38933f49d684SMustafa Ismail struct irdma_aeq_init_info *info)
38943f49d684SMustafa Ismail {
38953f49d684SMustafa Ismail u32 pble_obj_cnt;
38963f49d684SMustafa Ismail
38973f49d684SMustafa Ismail if (info->elem_cnt < info->dev->hw_attrs.min_hw_aeq_size ||
38983f49d684SMustafa Ismail info->elem_cnt > info->dev->hw_attrs.max_hw_aeq_size)
38992c4b14eaSShiraz Saleem return -EINVAL;
39003f49d684SMustafa Ismail
39013f49d684SMustafa Ismail pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
39023f49d684SMustafa Ismail
39033f49d684SMustafa Ismail if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt)
39042c4b14eaSShiraz Saleem return -EINVAL;
39053f49d684SMustafa Ismail
39063f49d684SMustafa Ismail aeq->size = sizeof(*aeq);
39073f49d684SMustafa Ismail aeq->polarity = 1;
39083f49d684SMustafa Ismail aeq->aeqe_base = (struct irdma_sc_aeqe *)info->aeqe_base;
39093f49d684SMustafa Ismail aeq->dev = info->dev;
39103f49d684SMustafa Ismail aeq->elem_cnt = info->elem_cnt;
39113f49d684SMustafa Ismail aeq->aeq_elem_pa = info->aeq_elem_pa;
39123f49d684SMustafa Ismail IRDMA_RING_INIT(aeq->aeq_ring, aeq->elem_cnt);
39133f49d684SMustafa Ismail aeq->virtual_map = info->virtual_map;
39143f49d684SMustafa Ismail aeq->pbl_list = (aeq->virtual_map ? info->pbl_list : NULL);
39153f49d684SMustafa Ismail aeq->pbl_chunk_size = (aeq->virtual_map ? info->pbl_chunk_size : 0);
39163f49d684SMustafa Ismail aeq->first_pm_pbl_idx = (aeq->virtual_map ? info->first_pm_pbl_idx : 0);
39173f49d684SMustafa Ismail aeq->msix_idx = info->msix_idx;
39183f49d684SMustafa Ismail info->dev->aeq = aeq;
39193f49d684SMustafa Ismail
39203f49d684SMustafa Ismail return 0;
39213f49d684SMustafa Ismail }
39223f49d684SMustafa Ismail
39233f49d684SMustafa Ismail /**
39243f49d684SMustafa Ismail * irdma_sc_aeq_create - create aeq
39253f49d684SMustafa Ismail * @aeq: aeq structure ptr
39263f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
39273f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
39283f49d684SMustafa Ismail */
irdma_sc_aeq_create(struct irdma_sc_aeq * aeq,u64 scratch,bool post_sq)39292c4b14eaSShiraz Saleem static int irdma_sc_aeq_create(struct irdma_sc_aeq *aeq, u64 scratch,
39302c4b14eaSShiraz Saleem bool post_sq)
39313f49d684SMustafa Ismail {
39323f49d684SMustafa Ismail __le64 *wqe;
39333f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
39343f49d684SMustafa Ismail u64 hdr;
39353f49d684SMustafa Ismail
39363f49d684SMustafa Ismail cqp = aeq->dev->cqp;
39373f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
39383f49d684SMustafa Ismail if (!wqe)
39392c4b14eaSShiraz Saleem return -ENOMEM;
39403f49d684SMustafa Ismail set_64bit_val(wqe, 16, aeq->elem_cnt);
39413f49d684SMustafa Ismail set_64bit_val(wqe, 32,
39423f49d684SMustafa Ismail (aeq->virtual_map ? 0 : aeq->aeq_elem_pa));
39433f49d684SMustafa Ismail set_64bit_val(wqe, 48,
39443f49d684SMustafa Ismail (aeq->virtual_map ? aeq->first_pm_pbl_idx : 0));
39453f49d684SMustafa Ismail
39463f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_AEQ) |
39473f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_AEQ_LPBLSIZE, aeq->pbl_chunk_size) |
39483f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_AEQ_VMAP, aeq->virtual_map) |
39493f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
39503f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
39513f49d684SMustafa Ismail
39523f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
39533f49d684SMustafa Ismail
39543f49d684SMustafa Ismail print_hex_dump_debug("WQE: AEQ_CREATE WQE", DUMP_PREFIX_OFFSET, 16, 8,
39553f49d684SMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false);
39563f49d684SMustafa Ismail if (post_sq)
39573f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
39583f49d684SMustafa Ismail
39593f49d684SMustafa Ismail return 0;
39603f49d684SMustafa Ismail }
39613f49d684SMustafa Ismail
39623f49d684SMustafa Ismail /**
39633f49d684SMustafa Ismail * irdma_sc_aeq_destroy - destroy aeq during close
39643f49d684SMustafa Ismail * @aeq: aeq structure ptr
39653f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
39663f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
39673f49d684SMustafa Ismail */
irdma_sc_aeq_destroy(struct irdma_sc_aeq * aeq,u64 scratch,bool post_sq)39682c4b14eaSShiraz Saleem static int irdma_sc_aeq_destroy(struct irdma_sc_aeq *aeq, u64 scratch,
39692c4b14eaSShiraz Saleem bool post_sq)
39703f49d684SMustafa Ismail {
39713f49d684SMustafa Ismail __le64 *wqe;
39723f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
39733f49d684SMustafa Ismail struct irdma_sc_dev *dev;
39743f49d684SMustafa Ismail u64 hdr;
39753f49d684SMustafa Ismail
39763f49d684SMustafa Ismail dev = aeq->dev;
39773f49d684SMustafa Ismail writel(0, dev->hw_regs[IRDMA_PFINT_AEQCTL]);
39783f49d684SMustafa Ismail
39793f49d684SMustafa Ismail cqp = dev->cqp;
39803f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
39813f49d684SMustafa Ismail if (!wqe)
39822c4b14eaSShiraz Saleem return -ENOMEM;
39833f49d684SMustafa Ismail set_64bit_val(wqe, 16, aeq->elem_cnt);
39843f49d684SMustafa Ismail set_64bit_val(wqe, 48, aeq->first_pm_pbl_idx);
39853f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_AEQ) |
39863f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_AEQ_LPBLSIZE, aeq->pbl_chunk_size) |
39873f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_AEQ_VMAP, aeq->virtual_map) |
39883f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
39893f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
39903f49d684SMustafa Ismail
39913f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
39923f49d684SMustafa Ismail
39933f49d684SMustafa Ismail print_hex_dump_debug("WQE: AEQ_DESTROY WQE", DUMP_PREFIX_OFFSET, 16,
39943f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
39953f49d684SMustafa Ismail if (post_sq)
39963f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
39973f49d684SMustafa Ismail return 0;
39983f49d684SMustafa Ismail }
39993f49d684SMustafa Ismail
40003f49d684SMustafa Ismail /**
40013f49d684SMustafa Ismail * irdma_sc_get_next_aeqe - get next aeq entry
40023f49d684SMustafa Ismail * @aeq: aeq structure ptr
40033f49d684SMustafa Ismail * @info: aeqe info to be returned
40043f49d684SMustafa Ismail */
irdma_sc_get_next_aeqe(struct irdma_sc_aeq * aeq,struct irdma_aeqe_info * info)40052c4b14eaSShiraz Saleem int irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq,
40063f49d684SMustafa Ismail struct irdma_aeqe_info *info)
40073f49d684SMustafa Ismail {
40083f49d684SMustafa Ismail u64 temp, compl_ctx;
40093f49d684SMustafa Ismail __le64 *aeqe;
40103f49d684SMustafa Ismail u8 ae_src;
40113f49d684SMustafa Ismail u8 polarity;
40123f49d684SMustafa Ismail
40133f49d684SMustafa Ismail aeqe = IRDMA_GET_CURRENT_AEQ_ELEM(aeq);
40143f49d684SMustafa Ismail get_64bit_val(aeqe, 8, &temp);
40153f49d684SMustafa Ismail polarity = (u8)FIELD_GET(IRDMA_AEQE_VALID, temp);
40163f49d684SMustafa Ismail
40173f49d684SMustafa Ismail if (aeq->polarity != polarity)
40182c4b14eaSShiraz Saleem return -ENOENT;
40193f49d684SMustafa Ismail
40204984eb51SShiraz Saleem /* Ensure AEQE contents are read after valid bit is checked */
40214984eb51SShiraz Saleem dma_rmb();
40224984eb51SShiraz Saleem
40234984eb51SShiraz Saleem get_64bit_val(aeqe, 0, &compl_ctx);
40244984eb51SShiraz Saleem
40253f49d684SMustafa Ismail print_hex_dump_debug("WQE: AEQ_ENTRY WQE", DUMP_PREFIX_OFFSET, 16, 8,
40263f49d684SMustafa Ismail aeqe, 16, false);
40273f49d684SMustafa Ismail
40283f49d684SMustafa Ismail ae_src = (u8)FIELD_GET(IRDMA_AEQE_AESRC, temp);
40298cfc99daSSindhu Devale info->wqe_idx = (u16)FIELD_GET(IRDMA_AEQE_WQDESCIDX, temp);
40303f49d684SMustafa Ismail info->qp_cq_id = (u32)FIELD_GET(IRDMA_AEQE_QPCQID_LOW, temp) |
40313f49d684SMustafa Ismail ((u32)FIELD_GET(IRDMA_AEQE_QPCQID_HI, temp) << 18);
40323f49d684SMustafa Ismail info->ae_id = (u16)FIELD_GET(IRDMA_AEQE_AECODE, temp);
40333f49d684SMustafa Ismail info->tcp_state = (u8)FIELD_GET(IRDMA_AEQE_TCPSTATE, temp);
40343f49d684SMustafa Ismail info->iwarp_state = (u8)FIELD_GET(IRDMA_AEQE_IWSTATE, temp);
40353f49d684SMustafa Ismail info->q2_data_written = (u8)FIELD_GET(IRDMA_AEQE_Q2DATA, temp);
40363f49d684SMustafa Ismail info->aeqe_overflow = (bool)FIELD_GET(IRDMA_AEQE_OVERFLOW, temp);
40373f49d684SMustafa Ismail
40383f49d684SMustafa Ismail info->ae_src = ae_src;
40393f49d684SMustafa Ismail switch (info->ae_id) {
40403f49d684SMustafa Ismail case IRDMA_AE_PRIV_OPERATION_DENIED:
40413f49d684SMustafa Ismail case IRDMA_AE_AMP_INVALIDATE_TYPE1_MW:
40423f49d684SMustafa Ismail case IRDMA_AE_AMP_MWBIND_ZERO_BASED_TYPE1_MW:
40433f49d684SMustafa Ismail case IRDMA_AE_AMP_FASTREG_INVALID_PBL_HPS_CFG:
40443f49d684SMustafa Ismail case IRDMA_AE_AMP_FASTREG_PBLE_MISMATCH:
40453f49d684SMustafa Ismail case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG:
40463f49d684SMustafa Ismail case IRDMA_AE_UDA_XMIT_BAD_PD:
40473f49d684SMustafa Ismail case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT:
40483f49d684SMustafa Ismail case IRDMA_AE_BAD_CLOSE:
40493f49d684SMustafa Ismail case IRDMA_AE_RDMA_READ_WHILE_ORD_ZERO:
40503f49d684SMustafa Ismail case IRDMA_AE_STAG_ZERO_INVALID:
40513f49d684SMustafa Ismail case IRDMA_AE_IB_RREQ_AND_Q1_FULL:
40523f49d684SMustafa Ismail case IRDMA_AE_IB_INVALID_REQUEST:
40533f49d684SMustafa Ismail case IRDMA_AE_WQE_UNEXPECTED_OPCODE:
40543f49d684SMustafa Ismail case IRDMA_AE_IB_REMOTE_ACCESS_ERROR:
40553f49d684SMustafa Ismail case IRDMA_AE_IB_REMOTE_OP_ERROR:
40563f49d684SMustafa Ismail case IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION:
40573f49d684SMustafa Ismail case IRDMA_AE_DDP_UBE_INVALID_MO:
40583f49d684SMustafa Ismail case IRDMA_AE_DDP_UBE_INVALID_QN:
40593f49d684SMustafa Ismail case IRDMA_AE_DDP_NO_L_BIT:
40603f49d684SMustafa Ismail case IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION:
40613f49d684SMustafa Ismail case IRDMA_AE_RDMAP_ROE_UNEXPECTED_OPCODE:
40623f49d684SMustafa Ismail case IRDMA_AE_ROE_INVALID_RDMA_READ_REQUEST:
40633f49d684SMustafa Ismail case IRDMA_AE_ROE_INVALID_RDMA_WRITE_OR_READ_RESP:
40643f49d684SMustafa Ismail case IRDMA_AE_ROCE_RSP_LENGTH_ERROR:
40653f49d684SMustafa Ismail case IRDMA_AE_INVALID_ARP_ENTRY:
40663f49d684SMustafa Ismail case IRDMA_AE_INVALID_TCP_OPTION_RCVD:
40673f49d684SMustafa Ismail case IRDMA_AE_STALE_ARP_ENTRY:
40683f49d684SMustafa Ismail case IRDMA_AE_INVALID_AH_ENTRY:
40693f49d684SMustafa Ismail case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR:
40703f49d684SMustafa Ismail case IRDMA_AE_LLP_SEGMENT_TOO_SMALL:
40713f49d684SMustafa Ismail case IRDMA_AE_LLP_TOO_MANY_RETRIES:
40723f49d684SMustafa Ismail case IRDMA_AE_LLP_DOUBT_REACHABILITY:
40733f49d684SMustafa Ismail case IRDMA_AE_LLP_CONNECTION_ESTABLISHED:
40743f49d684SMustafa Ismail case IRDMA_AE_RESET_SENT:
40753f49d684SMustafa Ismail case IRDMA_AE_TERMINATE_SENT:
40763f49d684SMustafa Ismail case IRDMA_AE_RESET_NOT_SENT:
40773f49d684SMustafa Ismail case IRDMA_AE_LCE_QP_CATASTROPHIC:
40783f49d684SMustafa Ismail case IRDMA_AE_QP_SUSPEND_COMPLETE:
40793f49d684SMustafa Ismail case IRDMA_AE_UDA_L4LEN_INVALID:
40803f49d684SMustafa Ismail info->qp = true;
40813f49d684SMustafa Ismail info->compl_ctx = compl_ctx;
40823f49d684SMustafa Ismail break;
40833f49d684SMustafa Ismail case IRDMA_AE_LCE_CQ_CATASTROPHIC:
40843f49d684SMustafa Ismail info->cq = true;
40853f49d684SMustafa Ismail info->compl_ctx = compl_ctx << 1;
40863f49d684SMustafa Ismail ae_src = IRDMA_AE_SOURCE_RSVD;
40873f49d684SMustafa Ismail break;
40883f49d684SMustafa Ismail case IRDMA_AE_ROCE_EMPTY_MCG:
40893f49d684SMustafa Ismail case IRDMA_AE_ROCE_BAD_MC_IP_ADDR:
40903f49d684SMustafa Ismail case IRDMA_AE_ROCE_BAD_MC_QPID:
40913f49d684SMustafa Ismail case IRDMA_AE_MCG_QP_PROTOCOL_MISMATCH:
40923f49d684SMustafa Ismail fallthrough;
40933f49d684SMustafa Ismail case IRDMA_AE_LLP_CONNECTION_RESET:
40943f49d684SMustafa Ismail case IRDMA_AE_LLP_SYN_RECEIVED:
40953f49d684SMustafa Ismail case IRDMA_AE_LLP_FIN_RECEIVED:
40963f49d684SMustafa Ismail case IRDMA_AE_LLP_CLOSE_COMPLETE:
40973f49d684SMustafa Ismail case IRDMA_AE_LLP_TERMINATE_RECEIVED:
40983f49d684SMustafa Ismail case IRDMA_AE_RDMAP_ROE_BAD_LLP_CLOSE:
40993f49d684SMustafa Ismail ae_src = IRDMA_AE_SOURCE_RSVD;
41003f49d684SMustafa Ismail info->qp = true;
41013f49d684SMustafa Ismail info->compl_ctx = compl_ctx;
41023f49d684SMustafa Ismail break;
41033f49d684SMustafa Ismail default:
41043f49d684SMustafa Ismail break;
41053f49d684SMustafa Ismail }
41063f49d684SMustafa Ismail
41073f49d684SMustafa Ismail switch (ae_src) {
41083f49d684SMustafa Ismail case IRDMA_AE_SOURCE_RQ:
41093f49d684SMustafa Ismail case IRDMA_AE_SOURCE_RQ_0011:
41103f49d684SMustafa Ismail info->qp = true;
41113f49d684SMustafa Ismail info->rq = true;
41123f49d684SMustafa Ismail info->compl_ctx = compl_ctx;
41133f49d684SMustafa Ismail break;
41143f49d684SMustafa Ismail case IRDMA_AE_SOURCE_CQ:
41153f49d684SMustafa Ismail case IRDMA_AE_SOURCE_CQ_0110:
41163f49d684SMustafa Ismail case IRDMA_AE_SOURCE_CQ_1010:
41173f49d684SMustafa Ismail case IRDMA_AE_SOURCE_CQ_1110:
41183f49d684SMustafa Ismail info->cq = true;
41193f49d684SMustafa Ismail info->compl_ctx = compl_ctx << 1;
41203f49d684SMustafa Ismail break;
41213f49d684SMustafa Ismail case IRDMA_AE_SOURCE_SQ:
41223f49d684SMustafa Ismail case IRDMA_AE_SOURCE_SQ_0111:
41233f49d684SMustafa Ismail info->qp = true;
41243f49d684SMustafa Ismail info->sq = true;
41253f49d684SMustafa Ismail info->compl_ctx = compl_ctx;
41263f49d684SMustafa Ismail break;
41273f49d684SMustafa Ismail case IRDMA_AE_SOURCE_IN_RR_WR:
41283f49d684SMustafa Ismail case IRDMA_AE_SOURCE_IN_RR_WR_1011:
41293f49d684SMustafa Ismail info->qp = true;
41303f49d684SMustafa Ismail info->compl_ctx = compl_ctx;
41313f49d684SMustafa Ismail info->in_rdrsp_wr = true;
41323f49d684SMustafa Ismail break;
41333f49d684SMustafa Ismail case IRDMA_AE_SOURCE_OUT_RR:
41343f49d684SMustafa Ismail case IRDMA_AE_SOURCE_OUT_RR_1111:
41353f49d684SMustafa Ismail info->qp = true;
41363f49d684SMustafa Ismail info->compl_ctx = compl_ctx;
41373f49d684SMustafa Ismail info->out_rdrsp = true;
41383f49d684SMustafa Ismail break;
41393f49d684SMustafa Ismail case IRDMA_AE_SOURCE_RSVD:
41403f49d684SMustafa Ismail default:
41413f49d684SMustafa Ismail break;
41423f49d684SMustafa Ismail }
41433f49d684SMustafa Ismail
41443f49d684SMustafa Ismail IRDMA_RING_MOVE_TAIL(aeq->aeq_ring);
41453f49d684SMustafa Ismail if (!IRDMA_RING_CURRENT_TAIL(aeq->aeq_ring))
41463f49d684SMustafa Ismail aeq->polarity ^= 1;
41473f49d684SMustafa Ismail
41483f49d684SMustafa Ismail return 0;
41493f49d684SMustafa Ismail }
41503f49d684SMustafa Ismail
41513f49d684SMustafa Ismail /**
41523f49d684SMustafa Ismail * irdma_sc_repost_aeq_entries - repost completed aeq entries
41533f49d684SMustafa Ismail * @dev: sc device struct
41543f49d684SMustafa Ismail * @count: allocate count
41553f49d684SMustafa Ismail */
irdma_sc_repost_aeq_entries(struct irdma_sc_dev * dev,u32 count)4156a323da0bSZhu Yanjun void irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, u32 count)
41573f49d684SMustafa Ismail {
41583f49d684SMustafa Ismail writel(count, dev->hw_regs[IRDMA_AEQALLOC]);
41593f49d684SMustafa Ismail }
41603f49d684SMustafa Ismail
41613f49d684SMustafa Ismail /**
41623f49d684SMustafa Ismail * irdma_sc_ccq_init - initialize control cq
41633f49d684SMustafa Ismail * @cq: sc's cq ctruct
41643f49d684SMustafa Ismail * @info: info for control cq initialization
41653f49d684SMustafa Ismail */
irdma_sc_ccq_init(struct irdma_sc_cq * cq,struct irdma_ccq_init_info * info)41662c4b14eaSShiraz Saleem int irdma_sc_ccq_init(struct irdma_sc_cq *cq, struct irdma_ccq_init_info *info)
41673f49d684SMustafa Ismail {
41683f49d684SMustafa Ismail u32 pble_obj_cnt;
41693f49d684SMustafa Ismail
41703f49d684SMustafa Ismail if (info->num_elem < info->dev->hw_attrs.uk_attrs.min_hw_cq_size ||
41713f49d684SMustafa Ismail info->num_elem > info->dev->hw_attrs.uk_attrs.max_hw_cq_size)
41722c4b14eaSShiraz Saleem return -EINVAL;
41733f49d684SMustafa Ismail
41746f6dbb81SDan Carpenter if (info->ceq_id >= info->dev->hmc_fpm_misc.max_ceqs)
41752c4b14eaSShiraz Saleem return -EINVAL;
41763f49d684SMustafa Ismail
41773f49d684SMustafa Ismail pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
41783f49d684SMustafa Ismail
41793f49d684SMustafa Ismail if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt)
41802c4b14eaSShiraz Saleem return -EINVAL;
41813f49d684SMustafa Ismail
41823f49d684SMustafa Ismail cq->cq_pa = info->cq_pa;
41833f49d684SMustafa Ismail cq->cq_uk.cq_base = info->cq_base;
41843f49d684SMustafa Ismail cq->shadow_area_pa = info->shadow_area_pa;
41853f49d684SMustafa Ismail cq->cq_uk.shadow_area = info->shadow_area;
41863f49d684SMustafa Ismail cq->shadow_read_threshold = info->shadow_read_threshold;
41873f49d684SMustafa Ismail cq->dev = info->dev;
41883f49d684SMustafa Ismail cq->ceq_id = info->ceq_id;
41893f49d684SMustafa Ismail cq->cq_uk.cq_size = info->num_elem;
41903f49d684SMustafa Ismail cq->cq_type = IRDMA_CQ_TYPE_CQP;
41913f49d684SMustafa Ismail cq->ceqe_mask = info->ceqe_mask;
41923f49d684SMustafa Ismail IRDMA_RING_INIT(cq->cq_uk.cq_ring, info->num_elem);
41933f49d684SMustafa Ismail cq->cq_uk.cq_id = 0; /* control cq is id 0 always */
41943f49d684SMustafa Ismail cq->ceq_id_valid = info->ceq_id_valid;
41953f49d684SMustafa Ismail cq->tph_en = info->tph_en;
41963f49d684SMustafa Ismail cq->tph_val = info->tph_val;
41973f49d684SMustafa Ismail cq->cq_uk.avoid_mem_cflct = info->avoid_mem_cflct;
41983f49d684SMustafa Ismail cq->pbl_list = info->pbl_list;
41993f49d684SMustafa Ismail cq->virtual_map = info->virtual_map;
42003f49d684SMustafa Ismail cq->pbl_chunk_size = info->pbl_chunk_size;
42013f49d684SMustafa Ismail cq->first_pm_pbl_idx = info->first_pm_pbl_idx;
42023f49d684SMustafa Ismail cq->cq_uk.polarity = true;
42033f49d684SMustafa Ismail cq->vsi = info->vsi;
42043f49d684SMustafa Ismail cq->cq_uk.cq_ack_db = cq->dev->cq_ack_db;
42053f49d684SMustafa Ismail
42063f49d684SMustafa Ismail /* Only applicable to CQs other than CCQ so initialize to zero */
42073f49d684SMustafa Ismail cq->cq_uk.cqe_alloc_db = NULL;
42083f49d684SMustafa Ismail
42093f49d684SMustafa Ismail info->dev->ccq = cq;
42103f49d684SMustafa Ismail return 0;
42113f49d684SMustafa Ismail }
42123f49d684SMustafa Ismail
42133f49d684SMustafa Ismail /**
42143f49d684SMustafa Ismail * irdma_sc_ccq_create_done - poll cqp for ccq create
42153f49d684SMustafa Ismail * @ccq: ccq sc struct
42163f49d684SMustafa Ismail */
irdma_sc_ccq_create_done(struct irdma_sc_cq * ccq)42172c4b14eaSShiraz Saleem static inline int irdma_sc_ccq_create_done(struct irdma_sc_cq *ccq)
42183f49d684SMustafa Ismail {
42193f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
42203f49d684SMustafa Ismail
42213f49d684SMustafa Ismail cqp = ccq->dev->cqp;
42223f49d684SMustafa Ismail
42233f49d684SMustafa Ismail return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_CREATE_CQ, NULL);
42243f49d684SMustafa Ismail }
42253f49d684SMustafa Ismail
42263f49d684SMustafa Ismail /**
42273f49d684SMustafa Ismail * irdma_sc_ccq_create - create control cq
42283f49d684SMustafa Ismail * @ccq: ccq sc struct
42293f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
42303f49d684SMustafa Ismail * @check_overflow: overlow flag for ccq
42313f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
42323f49d684SMustafa Ismail */
irdma_sc_ccq_create(struct irdma_sc_cq * ccq,u64 scratch,bool check_overflow,bool post_sq)42332c4b14eaSShiraz Saleem int irdma_sc_ccq_create(struct irdma_sc_cq *ccq, u64 scratch,
42343f49d684SMustafa Ismail bool check_overflow, bool post_sq)
42353f49d684SMustafa Ismail {
42362c4b14eaSShiraz Saleem int ret_code;
42373f49d684SMustafa Ismail
42383f49d684SMustafa Ismail ret_code = irdma_sc_cq_create(ccq, scratch, check_overflow, post_sq);
42393f49d684SMustafa Ismail if (ret_code)
42403f49d684SMustafa Ismail return ret_code;
42413f49d684SMustafa Ismail
42423f49d684SMustafa Ismail if (post_sq) {
42433f49d684SMustafa Ismail ret_code = irdma_sc_ccq_create_done(ccq);
42443f49d684SMustafa Ismail if (ret_code)
42453f49d684SMustafa Ismail return ret_code;
42463f49d684SMustafa Ismail }
42473f49d684SMustafa Ismail ccq->dev->cqp->process_cqp_sds = irdma_cqp_sds_cmd;
42483f49d684SMustafa Ismail
42493f49d684SMustafa Ismail return 0;
42503f49d684SMustafa Ismail }
42513f49d684SMustafa Ismail
42523f49d684SMustafa Ismail /**
42533f49d684SMustafa Ismail * irdma_sc_ccq_destroy - destroy ccq during close
42543f49d684SMustafa Ismail * @ccq: ccq sc struct
42553f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
42563f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
42573f49d684SMustafa Ismail */
irdma_sc_ccq_destroy(struct irdma_sc_cq * ccq,u64 scratch,bool post_sq)42582c4b14eaSShiraz Saleem int irdma_sc_ccq_destroy(struct irdma_sc_cq *ccq, u64 scratch, bool post_sq)
42593f49d684SMustafa Ismail {
42603f49d684SMustafa Ismail struct irdma_sc_cqp *cqp;
42613f49d684SMustafa Ismail __le64 *wqe;
42623f49d684SMustafa Ismail u64 hdr;
42632c4b14eaSShiraz Saleem int ret_code = 0;
42643f49d684SMustafa Ismail u32 tail, val, error;
42653f49d684SMustafa Ismail
42663f49d684SMustafa Ismail cqp = ccq->dev->cqp;
42673f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
42683f49d684SMustafa Ismail if (!wqe)
42692c4b14eaSShiraz Saleem return -ENOMEM;
42703f49d684SMustafa Ismail
42713f49d684SMustafa Ismail set_64bit_val(wqe, 0, ccq->cq_uk.cq_size);
42723f49d684SMustafa Ismail set_64bit_val(wqe, 8, (uintptr_t)ccq >> 1);
42733f49d684SMustafa Ismail set_64bit_val(wqe, 40, ccq->shadow_area_pa);
42743f49d684SMustafa Ismail
42753f49d684SMustafa Ismail hdr = ccq->cq_uk.cq_id |
42763f49d684SMustafa Ismail FLD_LS_64(ccq->dev, (ccq->ceq_id_valid ? ccq->ceq_id : 0),
42773f49d684SMustafa Ismail IRDMA_CQPSQ_CQ_CEQID) |
42783f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_CQ) |
42793f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, ccq->ceqe_mask) |
42803f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_CEQIDVALID, ccq->ceq_id_valid) |
42813f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_TPHEN, ccq->tph_en) |
42823f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT, ccq->cq_uk.avoid_mem_cflct) |
42833f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
42843f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
42853f49d684SMustafa Ismail
42863f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
42873f49d684SMustafa Ismail
42883f49d684SMustafa Ismail print_hex_dump_debug("WQE: CCQ_DESTROY WQE", DUMP_PREFIX_OFFSET, 16,
42893f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
42903f49d684SMustafa Ismail irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
42913f49d684SMustafa Ismail
42923f49d684SMustafa Ismail if (post_sq) {
42933f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
42943f49d684SMustafa Ismail ret_code = irdma_cqp_poll_registers(cqp, tail,
42953f49d684SMustafa Ismail cqp->dev->hw_attrs.max_done_count);
42963f49d684SMustafa Ismail }
42973f49d684SMustafa Ismail
42983f49d684SMustafa Ismail cqp->process_cqp_sds = irdma_update_sds_noccq;
42993f49d684SMustafa Ismail
43003f49d684SMustafa Ismail return ret_code;
43013f49d684SMustafa Ismail }
43023f49d684SMustafa Ismail
43033f49d684SMustafa Ismail /**
43043f49d684SMustafa Ismail * irdma_sc_init_iw_hmc() - queries fpm values using cqp and populates hmc_info
43053f49d684SMustafa Ismail * @dev : ptr to irdma_dev struct
43063f49d684SMustafa Ismail * @hmc_fn_id: hmc function id
43073f49d684SMustafa Ismail */
irdma_sc_init_iw_hmc(struct irdma_sc_dev * dev,u8 hmc_fn_id)43082c4b14eaSShiraz Saleem int irdma_sc_init_iw_hmc(struct irdma_sc_dev *dev, u8 hmc_fn_id)
43093f49d684SMustafa Ismail {
43103f49d684SMustafa Ismail struct irdma_hmc_info *hmc_info;
43113f49d684SMustafa Ismail struct irdma_hmc_fpm_misc *hmc_fpm_misc;
43123f49d684SMustafa Ismail struct irdma_dma_mem query_fpm_mem;
43132c4b14eaSShiraz Saleem int ret_code = 0;
43143f49d684SMustafa Ismail u8 wait_type;
43153f49d684SMustafa Ismail
43163f49d684SMustafa Ismail hmc_info = dev->hmc_info;
43173f49d684SMustafa Ismail hmc_fpm_misc = &dev->hmc_fpm_misc;
43183f49d684SMustafa Ismail query_fpm_mem.pa = dev->fpm_query_buf_pa;
43193f49d684SMustafa Ismail query_fpm_mem.va = dev->fpm_query_buf;
43203f49d684SMustafa Ismail hmc_info->hmc_fn_id = hmc_fn_id;
43213f49d684SMustafa Ismail wait_type = (u8)IRDMA_CQP_WAIT_POLL_REGS;
43223f49d684SMustafa Ismail
43233f49d684SMustafa Ismail ret_code = irdma_sc_query_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id,
43243f49d684SMustafa Ismail &query_fpm_mem, true, wait_type);
43253f49d684SMustafa Ismail if (ret_code)
43263f49d684SMustafa Ismail return ret_code;
43273f49d684SMustafa Ismail
43283f49d684SMustafa Ismail /* parse the fpm_query_buf and fill hmc obj info */
43293f49d684SMustafa Ismail ret_code = irdma_sc_parse_fpm_query_buf(dev, query_fpm_mem.va, hmc_info,
43303f49d684SMustafa Ismail hmc_fpm_misc);
43313f49d684SMustafa Ismail
43323f49d684SMustafa Ismail print_hex_dump_debug("HMC: QUERY FPM BUFFER", DUMP_PREFIX_OFFSET, 16,
43333f49d684SMustafa Ismail 8, query_fpm_mem.va, IRDMA_QUERY_FPM_BUF_SIZE,
43343f49d684SMustafa Ismail false);
43353f49d684SMustafa Ismail return ret_code;
43363f49d684SMustafa Ismail }
43373f49d684SMustafa Ismail
43383f49d684SMustafa Ismail /**
43393f49d684SMustafa Ismail * irdma_sc_cfg_iw_fpm() - commits hmc obj cnt values using cqp
43403f49d684SMustafa Ismail * command and populates fpm base address in hmc_info
43413f49d684SMustafa Ismail * @dev : ptr to irdma_dev struct
43423f49d684SMustafa Ismail * @hmc_fn_id: hmc function id
43433f49d684SMustafa Ismail */
irdma_sc_cfg_iw_fpm(struct irdma_sc_dev * dev,u8 hmc_fn_id)43442c4b14eaSShiraz Saleem static int irdma_sc_cfg_iw_fpm(struct irdma_sc_dev *dev, u8 hmc_fn_id)
43453f49d684SMustafa Ismail {
43463f49d684SMustafa Ismail struct irdma_hmc_info *hmc_info;
43473f49d684SMustafa Ismail struct irdma_hmc_obj_info *obj_info;
43483f49d684SMustafa Ismail __le64 *buf;
43493f49d684SMustafa Ismail struct irdma_dma_mem commit_fpm_mem;
43502c4b14eaSShiraz Saleem int ret_code = 0;
43513f49d684SMustafa Ismail u8 wait_type;
43523f49d684SMustafa Ismail
43533f49d684SMustafa Ismail hmc_info = dev->hmc_info;
43543f49d684SMustafa Ismail obj_info = hmc_info->hmc_obj;
43553f49d684SMustafa Ismail buf = dev->fpm_commit_buf;
43563f49d684SMustafa Ismail
43573f49d684SMustafa Ismail set_64bit_val(buf, 0, (u64)obj_info[IRDMA_HMC_IW_QP].cnt);
43583f49d684SMustafa Ismail set_64bit_val(buf, 8, (u64)obj_info[IRDMA_HMC_IW_CQ].cnt);
43593f49d684SMustafa Ismail set_64bit_val(buf, 16, (u64)0); /* RSRVD */
43603f49d684SMustafa Ismail set_64bit_val(buf, 24, (u64)obj_info[IRDMA_HMC_IW_HTE].cnt);
43613f49d684SMustafa Ismail set_64bit_val(buf, 32, (u64)obj_info[IRDMA_HMC_IW_ARP].cnt);
43623f49d684SMustafa Ismail set_64bit_val(buf, 40, (u64)0); /* RSVD */
43633f49d684SMustafa Ismail set_64bit_val(buf, 48, (u64)obj_info[IRDMA_HMC_IW_MR].cnt);
43643f49d684SMustafa Ismail set_64bit_val(buf, 56, (u64)obj_info[IRDMA_HMC_IW_XF].cnt);
43653f49d684SMustafa Ismail set_64bit_val(buf, 64, (u64)obj_info[IRDMA_HMC_IW_XFFL].cnt);
43663f49d684SMustafa Ismail set_64bit_val(buf, 72, (u64)obj_info[IRDMA_HMC_IW_Q1].cnt);
43673f49d684SMustafa Ismail set_64bit_val(buf, 80, (u64)obj_info[IRDMA_HMC_IW_Q1FL].cnt);
43683f49d684SMustafa Ismail set_64bit_val(buf, 88,
43693f49d684SMustafa Ismail (u64)obj_info[IRDMA_HMC_IW_TIMER].cnt);
43703f49d684SMustafa Ismail set_64bit_val(buf, 96,
43713f49d684SMustafa Ismail (u64)obj_info[IRDMA_HMC_IW_FSIMC].cnt);
43723f49d684SMustafa Ismail set_64bit_val(buf, 104,
43733f49d684SMustafa Ismail (u64)obj_info[IRDMA_HMC_IW_FSIAV].cnt);
43743f49d684SMustafa Ismail set_64bit_val(buf, 112,
43753f49d684SMustafa Ismail (u64)obj_info[IRDMA_HMC_IW_PBLE].cnt);
43763f49d684SMustafa Ismail set_64bit_val(buf, 120, (u64)0); /* RSVD */
43773f49d684SMustafa Ismail set_64bit_val(buf, 128, (u64)obj_info[IRDMA_HMC_IW_RRF].cnt);
43783f49d684SMustafa Ismail set_64bit_val(buf, 136,
43793f49d684SMustafa Ismail (u64)obj_info[IRDMA_HMC_IW_RRFFL].cnt);
43803f49d684SMustafa Ismail set_64bit_val(buf, 144, (u64)obj_info[IRDMA_HMC_IW_HDR].cnt);
43813f49d684SMustafa Ismail set_64bit_val(buf, 152, (u64)obj_info[IRDMA_HMC_IW_MD].cnt);
43823f49d684SMustafa Ismail set_64bit_val(buf, 160,
43833f49d684SMustafa Ismail (u64)obj_info[IRDMA_HMC_IW_OOISC].cnt);
43843f49d684SMustafa Ismail set_64bit_val(buf, 168,
43853f49d684SMustafa Ismail (u64)obj_info[IRDMA_HMC_IW_OOISCFFL].cnt);
43863f49d684SMustafa Ismail
43873f49d684SMustafa Ismail commit_fpm_mem.pa = dev->fpm_commit_buf_pa;
43883f49d684SMustafa Ismail commit_fpm_mem.va = dev->fpm_commit_buf;
43893f49d684SMustafa Ismail
43903f49d684SMustafa Ismail wait_type = (u8)IRDMA_CQP_WAIT_POLL_REGS;
43913f49d684SMustafa Ismail print_hex_dump_debug("HMC: COMMIT FPM BUFFER", DUMP_PREFIX_OFFSET, 16,
43923f49d684SMustafa Ismail 8, commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE,
43933f49d684SMustafa Ismail false);
43943f49d684SMustafa Ismail ret_code = irdma_sc_commit_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id,
43953f49d684SMustafa Ismail &commit_fpm_mem, true, wait_type);
43963f49d684SMustafa Ismail if (!ret_code)
4397c9538831SZhu Yanjun irdma_sc_parse_fpm_commit_buf(dev, dev->fpm_commit_buf,
43983f49d684SMustafa Ismail hmc_info->hmc_obj,
43993f49d684SMustafa Ismail &hmc_info->sd_table.sd_cnt);
44003f49d684SMustafa Ismail print_hex_dump_debug("HMC: COMMIT FPM BUFFER", DUMP_PREFIX_OFFSET, 16,
44013f49d684SMustafa Ismail 8, commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE,
44023f49d684SMustafa Ismail false);
44033f49d684SMustafa Ismail
44043f49d684SMustafa Ismail return ret_code;
44053f49d684SMustafa Ismail }
44063f49d684SMustafa Ismail
44073f49d684SMustafa Ismail /**
44083f49d684SMustafa Ismail * cqp_sds_wqe_fill - fill cqp wqe doe sd
44093f49d684SMustafa Ismail * @cqp: struct for cqp hw
44103f49d684SMustafa Ismail * @info: sd info for wqe
44113f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
44123f49d684SMustafa Ismail */
cqp_sds_wqe_fill(struct irdma_sc_cqp * cqp,struct irdma_update_sds_info * info,u64 scratch)44132c4b14eaSShiraz Saleem static int cqp_sds_wqe_fill(struct irdma_sc_cqp *cqp,
44142c4b14eaSShiraz Saleem struct irdma_update_sds_info *info, u64 scratch)
44153f49d684SMustafa Ismail {
44163f49d684SMustafa Ismail u64 data;
44173f49d684SMustafa Ismail u64 hdr;
44183f49d684SMustafa Ismail __le64 *wqe;
44193f49d684SMustafa Ismail int mem_entries, wqe_entries;
44203f49d684SMustafa Ismail struct irdma_dma_mem *sdbuf = &cqp->sdbuf;
44213f49d684SMustafa Ismail u64 offset = 0;
44223f49d684SMustafa Ismail u32 wqe_idx;
44233f49d684SMustafa Ismail
44243f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe_idx(cqp, scratch, &wqe_idx);
44253f49d684SMustafa Ismail if (!wqe)
44262c4b14eaSShiraz Saleem return -ENOMEM;
44273f49d684SMustafa Ismail
44283f49d684SMustafa Ismail wqe_entries = (info->cnt > 3) ? 3 : info->cnt;
44293f49d684SMustafa Ismail mem_entries = info->cnt - wqe_entries;
44303f49d684SMustafa Ismail
44313f49d684SMustafa Ismail if (mem_entries) {
44323f49d684SMustafa Ismail offset = wqe_idx * IRDMA_UPDATE_SD_BUFF_SIZE;
44333f49d684SMustafa Ismail memcpy(((char *)sdbuf->va + offset), &info->entry[3], mem_entries << 4);
44343f49d684SMustafa Ismail
44353f49d684SMustafa Ismail data = (u64)sdbuf->pa + offset;
44363f49d684SMustafa Ismail } else {
44373f49d684SMustafa Ismail data = 0;
44383f49d684SMustafa Ismail }
44393f49d684SMustafa Ismail data |= FIELD_PREP(IRDMA_CQPSQ_UPESD_HMCFNID, info->hmc_fn_id);
44403f49d684SMustafa Ismail set_64bit_val(wqe, 16, data);
44413f49d684SMustafa Ismail
44423f49d684SMustafa Ismail switch (wqe_entries) {
44433f49d684SMustafa Ismail case 3:
44443f49d684SMustafa Ismail set_64bit_val(wqe, 48,
44453f49d684SMustafa Ismail (FIELD_PREP(IRDMA_CQPSQ_UPESD_SDCMD, info->entry[2].cmd) |
44463f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UPESD_ENTRY_VALID, 1)));
44473f49d684SMustafa Ismail
44483f49d684SMustafa Ismail set_64bit_val(wqe, 56, info->entry[2].data);
44493f49d684SMustafa Ismail fallthrough;
44503f49d684SMustafa Ismail case 2:
44513f49d684SMustafa Ismail set_64bit_val(wqe, 32,
44523f49d684SMustafa Ismail (FIELD_PREP(IRDMA_CQPSQ_UPESD_SDCMD, info->entry[1].cmd) |
44533f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UPESD_ENTRY_VALID, 1)));
44543f49d684SMustafa Ismail
44553f49d684SMustafa Ismail set_64bit_val(wqe, 40, info->entry[1].data);
44563f49d684SMustafa Ismail fallthrough;
44573f49d684SMustafa Ismail case 1:
44583f49d684SMustafa Ismail set_64bit_val(wqe, 0,
44593f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UPESD_SDCMD, info->entry[0].cmd));
44603f49d684SMustafa Ismail
44613f49d684SMustafa Ismail set_64bit_val(wqe, 8, info->entry[0].data);
44623f49d684SMustafa Ismail break;
44633f49d684SMustafa Ismail default:
44643f49d684SMustafa Ismail break;
44653f49d684SMustafa Ismail }
44663f49d684SMustafa Ismail
44673f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_UPDATE_PE_SDS) |
44683f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity) |
44693f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UPESD_ENTRY_COUNT, mem_entries);
44703f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
44713f49d684SMustafa Ismail
44723f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
44733f49d684SMustafa Ismail
44743f49d684SMustafa Ismail if (mem_entries)
44753f49d684SMustafa Ismail print_hex_dump_debug("WQE: UPDATE_PE_SDS WQE Buffer",
44763f49d684SMustafa Ismail DUMP_PREFIX_OFFSET, 16, 8,
44773f49d684SMustafa Ismail (char *)sdbuf->va + offset,
44783f49d684SMustafa Ismail mem_entries << 4, false);
44793f49d684SMustafa Ismail
44803f49d684SMustafa Ismail print_hex_dump_debug("WQE: UPDATE_PE_SDS WQE", DUMP_PREFIX_OFFSET, 16,
44813f49d684SMustafa Ismail 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
44823f49d684SMustafa Ismail
44833f49d684SMustafa Ismail return 0;
44843f49d684SMustafa Ismail }
44853f49d684SMustafa Ismail
44863f49d684SMustafa Ismail /**
44873f49d684SMustafa Ismail * irdma_update_pe_sds - cqp wqe for sd
44883f49d684SMustafa Ismail * @dev: ptr to irdma_dev struct
44893f49d684SMustafa Ismail * @info: sd info for sd's
44903f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
44913f49d684SMustafa Ismail */
irdma_update_pe_sds(struct irdma_sc_dev * dev,struct irdma_update_sds_info * info,u64 scratch)44922c4b14eaSShiraz Saleem static int irdma_update_pe_sds(struct irdma_sc_dev *dev,
44933f49d684SMustafa Ismail struct irdma_update_sds_info *info, u64 scratch)
44943f49d684SMustafa Ismail {
44953f49d684SMustafa Ismail struct irdma_sc_cqp *cqp = dev->cqp;
44962c4b14eaSShiraz Saleem int ret_code;
44973f49d684SMustafa Ismail
44983f49d684SMustafa Ismail ret_code = cqp_sds_wqe_fill(cqp, info, scratch);
44993f49d684SMustafa Ismail if (!ret_code)
45003f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
45013f49d684SMustafa Ismail
45023f49d684SMustafa Ismail return ret_code;
45033f49d684SMustafa Ismail }
45043f49d684SMustafa Ismail
45053f49d684SMustafa Ismail /**
45063f49d684SMustafa Ismail * irdma_update_sds_noccq - update sd before ccq created
45073f49d684SMustafa Ismail * @dev: sc device struct
45083f49d684SMustafa Ismail * @info: sd info for sd's
45093f49d684SMustafa Ismail */
irdma_update_sds_noccq(struct irdma_sc_dev * dev,struct irdma_update_sds_info * info)45102c4b14eaSShiraz Saleem int irdma_update_sds_noccq(struct irdma_sc_dev *dev,
45113f49d684SMustafa Ismail struct irdma_update_sds_info *info)
45123f49d684SMustafa Ismail {
45133f49d684SMustafa Ismail u32 error, val, tail;
45143f49d684SMustafa Ismail struct irdma_sc_cqp *cqp = dev->cqp;
45152c4b14eaSShiraz Saleem int ret_code;
45163f49d684SMustafa Ismail
45173f49d684SMustafa Ismail ret_code = cqp_sds_wqe_fill(cqp, info, 0);
45183f49d684SMustafa Ismail if (ret_code)
45193f49d684SMustafa Ismail return ret_code;
45203f49d684SMustafa Ismail
45213f49d684SMustafa Ismail irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
45223f49d684SMustafa Ismail
45233f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
45243f49d684SMustafa Ismail return irdma_cqp_poll_registers(cqp, tail,
45253f49d684SMustafa Ismail cqp->dev->hw_attrs.max_done_count);
45263f49d684SMustafa Ismail }
45273f49d684SMustafa Ismail
45283f49d684SMustafa Ismail /**
45293f49d684SMustafa Ismail * irdma_sc_static_hmc_pages_allocated - cqp wqe to allocate hmc pages
45303f49d684SMustafa Ismail * @cqp: struct for cqp hw
45313f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
45323f49d684SMustafa Ismail * @hmc_fn_id: hmc function id
45333f49d684SMustafa Ismail * @post_sq: flag for cqp db to ring
45343f49d684SMustafa Ismail * @poll_registers: flag to poll register for cqp completion
45353f49d684SMustafa Ismail */
irdma_sc_static_hmc_pages_allocated(struct irdma_sc_cqp * cqp,u64 scratch,u8 hmc_fn_id,bool post_sq,bool poll_registers)45362c4b14eaSShiraz Saleem int irdma_sc_static_hmc_pages_allocated(struct irdma_sc_cqp *cqp, u64 scratch,
45373f49d684SMustafa Ismail u8 hmc_fn_id, bool post_sq,
45383f49d684SMustafa Ismail bool poll_registers)
45393f49d684SMustafa Ismail {
45403f49d684SMustafa Ismail u64 hdr;
45413f49d684SMustafa Ismail __le64 *wqe;
45423f49d684SMustafa Ismail u32 tail, val, error;
45433f49d684SMustafa Ismail
45443f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
45453f49d684SMustafa Ismail if (!wqe)
45462c4b14eaSShiraz Saleem return -ENOMEM;
45473f49d684SMustafa Ismail
45483f49d684SMustafa Ismail set_64bit_val(wqe, 16,
45493f49d684SMustafa Ismail FIELD_PREP(IRDMA_SHMC_PAGE_ALLOCATED_HMC_FN_ID, hmc_fn_id));
45503f49d684SMustafa Ismail
45513f49d684SMustafa Ismail hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE,
45523f49d684SMustafa Ismail IRDMA_CQP_OP_SHMC_PAGES_ALLOCATED) |
45533f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
45543f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
45553f49d684SMustafa Ismail
45563f49d684SMustafa Ismail set_64bit_val(wqe, 24, hdr);
45573f49d684SMustafa Ismail
45583f49d684SMustafa Ismail print_hex_dump_debug("WQE: SHMC_PAGES_ALLOCATED WQE",
45593f49d684SMustafa Ismail DUMP_PREFIX_OFFSET, 16, 8, wqe,
45603f49d684SMustafa Ismail IRDMA_CQP_WQE_SIZE * 8, false);
45613f49d684SMustafa Ismail irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
45623f49d684SMustafa Ismail
45633f49d684SMustafa Ismail if (post_sq) {
45643f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
45653f49d684SMustafa Ismail if (poll_registers)
45663f49d684SMustafa Ismail /* check for cqp sq tail update */
45673f49d684SMustafa Ismail return irdma_cqp_poll_registers(cqp, tail,
45683f49d684SMustafa Ismail cqp->dev->hw_attrs.max_done_count);
45693f49d684SMustafa Ismail else
45703f49d684SMustafa Ismail return irdma_sc_poll_for_cqp_op_done(cqp,
45713f49d684SMustafa Ismail IRDMA_CQP_OP_SHMC_PAGES_ALLOCATED,
45723f49d684SMustafa Ismail NULL);
45733f49d684SMustafa Ismail }
45743f49d684SMustafa Ismail
45753f49d684SMustafa Ismail return 0;
45763f49d684SMustafa Ismail }
45773f49d684SMustafa Ismail
45783f49d684SMustafa Ismail /**
45793f49d684SMustafa Ismail * irdma_cqp_ring_full - check if cqp ring is full
45803f49d684SMustafa Ismail * @cqp: struct for cqp hw
45813f49d684SMustafa Ismail */
irdma_cqp_ring_full(struct irdma_sc_cqp * cqp)45823f49d684SMustafa Ismail static bool irdma_cqp_ring_full(struct irdma_sc_cqp *cqp)
45833f49d684SMustafa Ismail {
45843f49d684SMustafa Ismail return IRDMA_RING_FULL_ERR(cqp->sq_ring);
45853f49d684SMustafa Ismail }
45863f49d684SMustafa Ismail
45873f49d684SMustafa Ismail /**
45883f49d684SMustafa Ismail * irdma_est_sd - returns approximate number of SDs for HMC
45893f49d684SMustafa Ismail * @dev: sc device struct
45903f49d684SMustafa Ismail * @hmc_info: hmc structure, size and count for HMC objects
45913f49d684SMustafa Ismail */
irdma_est_sd(struct irdma_sc_dev * dev,struct irdma_hmc_info * hmc_info)45923f49d684SMustafa Ismail static u32 irdma_est_sd(struct irdma_sc_dev *dev,
45933f49d684SMustafa Ismail struct irdma_hmc_info *hmc_info)
45943f49d684SMustafa Ismail {
45953f49d684SMustafa Ismail int i;
45963f49d684SMustafa Ismail u64 size = 0;
45973f49d684SMustafa Ismail u64 sd;
45983f49d684SMustafa Ismail
45993f49d684SMustafa Ismail for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++)
46003f49d684SMustafa Ismail if (i != IRDMA_HMC_IW_PBLE)
46013f49d684SMustafa Ismail size += round_up(hmc_info->hmc_obj[i].cnt *
46023f49d684SMustafa Ismail hmc_info->hmc_obj[i].size, 512);
46033f49d684SMustafa Ismail size += round_up(hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt *
46043f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].size, 512);
46053f49d684SMustafa Ismail if (size & 0x1FFFFF)
46063f49d684SMustafa Ismail sd = (size >> 21) + 1; /* add 1 for remainder */
46073f49d684SMustafa Ismail else
46083f49d684SMustafa Ismail sd = size >> 21;
46093f49d684SMustafa Ismail if (sd > 0xFFFFFFFF) {
46103f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev), "HMC: sd overflow[%lld]\n", sd);
46113f49d684SMustafa Ismail sd = 0xFFFFFFFF - 1;
46123f49d684SMustafa Ismail }
46133f49d684SMustafa Ismail
46143f49d684SMustafa Ismail return (u32)sd;
46153f49d684SMustafa Ismail }
46163f49d684SMustafa Ismail
46173f49d684SMustafa Ismail /**
46183f49d684SMustafa Ismail * irdma_sc_query_rdma_features_done - poll cqp for query features done
46193f49d684SMustafa Ismail * @cqp: struct for cqp hw
46203f49d684SMustafa Ismail */
irdma_sc_query_rdma_features_done(struct irdma_sc_cqp * cqp)46212c4b14eaSShiraz Saleem static int irdma_sc_query_rdma_features_done(struct irdma_sc_cqp *cqp)
46223f49d684SMustafa Ismail {
46233f49d684SMustafa Ismail return irdma_sc_poll_for_cqp_op_done(cqp,
46243f49d684SMustafa Ismail IRDMA_CQP_OP_QUERY_RDMA_FEATURES,
46253f49d684SMustafa Ismail NULL);
46263f49d684SMustafa Ismail }
46273f49d684SMustafa Ismail
46283f49d684SMustafa Ismail /**
46293f49d684SMustafa Ismail * irdma_sc_query_rdma_features - query RDMA features and FW ver
46303f49d684SMustafa Ismail * @cqp: struct for cqp hw
46313f49d684SMustafa Ismail * @buf: buffer to hold query info
46323f49d684SMustafa Ismail * @scratch: u64 saved to be used during cqp completion
46333f49d684SMustafa Ismail */
irdma_sc_query_rdma_features(struct irdma_sc_cqp * cqp,struct irdma_dma_mem * buf,u64 scratch)46342c4b14eaSShiraz Saleem static int irdma_sc_query_rdma_features(struct irdma_sc_cqp *cqp,
46353f49d684SMustafa Ismail struct irdma_dma_mem *buf, u64 scratch)
46363f49d684SMustafa Ismail {
46373f49d684SMustafa Ismail __le64 *wqe;
46383f49d684SMustafa Ismail u64 temp;
46393f49d684SMustafa Ismail
46403f49d684SMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
46413f49d684SMustafa Ismail if (!wqe)
46422c4b14eaSShiraz Saleem return -ENOMEM;
46433f49d684SMustafa Ismail
46443f49d684SMustafa Ismail temp = buf->pa;
46453f49d684SMustafa Ismail set_64bit_val(wqe, 32, temp);
46463f49d684SMustafa Ismail
46473f49d684SMustafa Ismail temp = FIELD_PREP(IRDMA_CQPSQ_QUERY_RDMA_FEATURES_WQEVALID,
46483f49d684SMustafa Ismail cqp->polarity) |
46493f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_QUERY_RDMA_FEATURES_BUF_LEN, buf->size) |
46503f49d684SMustafa Ismail FIELD_PREP(IRDMA_CQPSQ_UP_OP, IRDMA_CQP_OP_QUERY_RDMA_FEATURES);
46513f49d684SMustafa Ismail dma_wmb(); /* make sure WQE is written before valid bit is set */
46523f49d684SMustafa Ismail
46533f49d684SMustafa Ismail set_64bit_val(wqe, 24, temp);
46543f49d684SMustafa Ismail
46553f49d684SMustafa Ismail print_hex_dump_debug("WQE: QUERY RDMA FEATURES", DUMP_PREFIX_OFFSET,
46563f49d684SMustafa Ismail 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false);
46573f49d684SMustafa Ismail irdma_sc_cqp_post_sq(cqp);
46583f49d684SMustafa Ismail
46593f49d684SMustafa Ismail return 0;
46603f49d684SMustafa Ismail }
46613f49d684SMustafa Ismail
46623f49d684SMustafa Ismail /**
46633f49d684SMustafa Ismail * irdma_get_rdma_features - get RDMA features
46643f49d684SMustafa Ismail * @dev: sc device struct
46653f49d684SMustafa Ismail */
irdma_get_rdma_features(struct irdma_sc_dev * dev)46662c4b14eaSShiraz Saleem int irdma_get_rdma_features(struct irdma_sc_dev *dev)
46673f49d684SMustafa Ismail {
46682c4b14eaSShiraz Saleem int ret_code;
46693f49d684SMustafa Ismail struct irdma_dma_mem feat_buf;
46703f49d684SMustafa Ismail u64 temp;
46713f49d684SMustafa Ismail u16 byte_idx, feat_type, feat_cnt, feat_idx;
46723f49d684SMustafa Ismail
46733f49d684SMustafa Ismail feat_buf.size = ALIGN(IRDMA_FEATURE_BUF_SIZE,
46743f49d684SMustafa Ismail IRDMA_FEATURE_BUF_ALIGNMENT);
46753f49d684SMustafa Ismail feat_buf.va = dma_alloc_coherent(dev->hw->device, feat_buf.size,
46763f49d684SMustafa Ismail &feat_buf.pa, GFP_KERNEL);
46773f49d684SMustafa Ismail if (!feat_buf.va)
46782c4b14eaSShiraz Saleem return -ENOMEM;
46793f49d684SMustafa Ismail
46803f49d684SMustafa Ismail ret_code = irdma_sc_query_rdma_features(dev->cqp, &feat_buf, 0);
46813f49d684SMustafa Ismail if (!ret_code)
46823f49d684SMustafa Ismail ret_code = irdma_sc_query_rdma_features_done(dev->cqp);
46833f49d684SMustafa Ismail if (ret_code)
46843f49d684SMustafa Ismail goto exit;
46853f49d684SMustafa Ismail
46863f49d684SMustafa Ismail get_64bit_val(feat_buf.va, 0, &temp);
46873f49d684SMustafa Ismail feat_cnt = (u16)FIELD_GET(IRDMA_FEATURE_CNT, temp);
46883f49d684SMustafa Ismail if (feat_cnt < 2) {
46892c4b14eaSShiraz Saleem ret_code = -EINVAL;
46903f49d684SMustafa Ismail goto exit;
46913f49d684SMustafa Ismail } else if (feat_cnt > IRDMA_MAX_FEATURES) {
46923f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
46933f49d684SMustafa Ismail "DEV: feature buf size insufficient, retrying with larger buffer\n");
46943f49d684SMustafa Ismail dma_free_coherent(dev->hw->device, feat_buf.size, feat_buf.va,
46953f49d684SMustafa Ismail feat_buf.pa);
46963f49d684SMustafa Ismail feat_buf.va = NULL;
46973f49d684SMustafa Ismail feat_buf.size = ALIGN(8 * feat_cnt,
46983f49d684SMustafa Ismail IRDMA_FEATURE_BUF_ALIGNMENT);
46993f49d684SMustafa Ismail feat_buf.va = dma_alloc_coherent(dev->hw->device,
47003f49d684SMustafa Ismail feat_buf.size, &feat_buf.pa,
47013f49d684SMustafa Ismail GFP_KERNEL);
47023f49d684SMustafa Ismail if (!feat_buf.va)
47032c4b14eaSShiraz Saleem return -ENOMEM;
47043f49d684SMustafa Ismail
47053f49d684SMustafa Ismail ret_code = irdma_sc_query_rdma_features(dev->cqp, &feat_buf, 0);
47063f49d684SMustafa Ismail if (!ret_code)
47073f49d684SMustafa Ismail ret_code = irdma_sc_query_rdma_features_done(dev->cqp);
47083f49d684SMustafa Ismail if (ret_code)
47093f49d684SMustafa Ismail goto exit;
47103f49d684SMustafa Ismail
47113f49d684SMustafa Ismail get_64bit_val(feat_buf.va, 0, &temp);
47123f49d684SMustafa Ismail feat_cnt = (u16)FIELD_GET(IRDMA_FEATURE_CNT, temp);
47133f49d684SMustafa Ismail if (feat_cnt < 2) {
47142c4b14eaSShiraz Saleem ret_code = -EINVAL;
47153f49d684SMustafa Ismail goto exit;
47163f49d684SMustafa Ismail }
47173f49d684SMustafa Ismail }
47183f49d684SMustafa Ismail
47193f49d684SMustafa Ismail print_hex_dump_debug("WQE: QUERY RDMA FEATURES", DUMP_PREFIX_OFFSET,
47203f49d684SMustafa Ismail 16, 8, feat_buf.va, feat_cnt * 8, false);
47213f49d684SMustafa Ismail
47223f49d684SMustafa Ismail for (byte_idx = 0, feat_idx = 0; feat_idx < min(feat_cnt, (u16)IRDMA_MAX_FEATURES);
47233f49d684SMustafa Ismail feat_idx++, byte_idx += 8) {
47243f49d684SMustafa Ismail get_64bit_val(feat_buf.va, byte_idx, &temp);
47253f49d684SMustafa Ismail feat_type = FIELD_GET(IRDMA_FEATURE_TYPE, temp);
47263f49d684SMustafa Ismail if (feat_type >= IRDMA_MAX_FEATURES) {
47273f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
47283f49d684SMustafa Ismail "DEV: found unrecognized feature type %d\n",
47293f49d684SMustafa Ismail feat_type);
47303f49d684SMustafa Ismail continue;
47313f49d684SMustafa Ismail }
47323f49d684SMustafa Ismail dev->feature_info[feat_type] = temp;
47333f49d684SMustafa Ismail }
47343f49d684SMustafa Ismail exit:
47353f49d684SMustafa Ismail dma_free_coherent(dev->hw->device, feat_buf.size, feat_buf.va,
47363f49d684SMustafa Ismail feat_buf.pa);
47373f49d684SMustafa Ismail feat_buf.va = NULL;
47383f49d684SMustafa Ismail return ret_code;
47393f49d684SMustafa Ismail }
47403f49d684SMustafa Ismail
irdma_q1_cnt(struct irdma_sc_dev * dev,struct irdma_hmc_info * hmc_info,u32 qpwanted)47413f49d684SMustafa Ismail static u32 irdma_q1_cnt(struct irdma_sc_dev *dev,
47423f49d684SMustafa Ismail struct irdma_hmc_info *hmc_info, u32 qpwanted)
47433f49d684SMustafa Ismail {
47443f49d684SMustafa Ismail u32 q1_cnt;
47453f49d684SMustafa Ismail
47463f49d684SMustafa Ismail if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) {
47473f49d684SMustafa Ismail q1_cnt = roundup_pow_of_two(dev->hw_attrs.max_hw_ird * 2 * qpwanted);
47483f49d684SMustafa Ismail } else {
47493f49d684SMustafa Ismail if (dev->cqp->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
47503f49d684SMustafa Ismail q1_cnt = roundup_pow_of_two(dev->hw_attrs.max_hw_ird * 2 * qpwanted + 512);
47513f49d684SMustafa Ismail else
47523f49d684SMustafa Ismail q1_cnt = dev->hw_attrs.max_hw_ird * 2 * qpwanted;
47533f49d684SMustafa Ismail }
47543f49d684SMustafa Ismail
47553f49d684SMustafa Ismail return q1_cnt;
47563f49d684SMustafa Ismail }
47573f49d684SMustafa Ismail
cfg_fpm_value_gen_1(struct irdma_sc_dev * dev,struct irdma_hmc_info * hmc_info,u32 qpwanted)47583f49d684SMustafa Ismail static void cfg_fpm_value_gen_1(struct irdma_sc_dev *dev,
47593f49d684SMustafa Ismail struct irdma_hmc_info *hmc_info, u32 qpwanted)
47603f49d684SMustafa Ismail {
47613f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt = roundup_pow_of_two(qpwanted * dev->hw_attrs.max_hw_wqes);
47623f49d684SMustafa Ismail }
47633f49d684SMustafa Ismail
cfg_fpm_value_gen_2(struct irdma_sc_dev * dev,struct irdma_hmc_info * hmc_info,u32 qpwanted)47643f49d684SMustafa Ismail static void cfg_fpm_value_gen_2(struct irdma_sc_dev *dev,
47653f49d684SMustafa Ismail struct irdma_hmc_info *hmc_info, u32 qpwanted)
47663f49d684SMustafa Ismail {
47673f49d684SMustafa Ismail struct irdma_hmc_fpm_misc *hmc_fpm_misc = &dev->hmc_fpm_misc;
47683f49d684SMustafa Ismail
47693f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt =
47703f49d684SMustafa Ismail 4 * hmc_fpm_misc->xf_block_size * qpwanted;
47713f49d684SMustafa Ismail
47723f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_HDR].cnt = qpwanted;
47733f49d684SMustafa Ismail
47743f49d684SMustafa Ismail if (hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].max_cnt)
47753f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].cnt = 32 * qpwanted;
47763f49d684SMustafa Ismail if (hmc_info->hmc_obj[IRDMA_HMC_IW_RRFFL].max_cnt)
47773f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_RRFFL].cnt =
47783f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].cnt /
47793f49d684SMustafa Ismail hmc_fpm_misc->rrf_block_size;
47803f49d684SMustafa Ismail if (hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].max_cnt)
47813f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].cnt = 32 * qpwanted;
47823f49d684SMustafa Ismail if (hmc_info->hmc_obj[IRDMA_HMC_IW_OOISCFFL].max_cnt)
47833f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_OOISCFFL].cnt =
47843f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].cnt /
47853f49d684SMustafa Ismail hmc_fpm_misc->ooiscf_block_size;
47863f49d684SMustafa Ismail }
47873f49d684SMustafa Ismail
47883f49d684SMustafa Ismail /**
47893f49d684SMustafa Ismail * irdma_cfg_fpm_val - configure HMC objects
47903f49d684SMustafa Ismail * @dev: sc device struct
47913f49d684SMustafa Ismail * @qp_count: desired qp count
47923f49d684SMustafa Ismail */
irdma_cfg_fpm_val(struct irdma_sc_dev * dev,u32 qp_count)47932c4b14eaSShiraz Saleem int irdma_cfg_fpm_val(struct irdma_sc_dev *dev, u32 qp_count)
47943f49d684SMustafa Ismail {
47953f49d684SMustafa Ismail struct irdma_virt_mem virt_mem;
47963f49d684SMustafa Ismail u32 i, mem_size;
47973f49d684SMustafa Ismail u32 qpwanted, mrwanted, pblewanted;
47983f49d684SMustafa Ismail u32 powerof2, hte;
47993f49d684SMustafa Ismail u32 sd_needed;
48003f49d684SMustafa Ismail u32 sd_diff;
48013f49d684SMustafa Ismail u32 loop_count = 0;
48023f49d684SMustafa Ismail struct irdma_hmc_info *hmc_info;
48033f49d684SMustafa Ismail struct irdma_hmc_fpm_misc *hmc_fpm_misc;
48042c4b14eaSShiraz Saleem int ret_code = 0;
48053f49d684SMustafa Ismail
48063f49d684SMustafa Ismail hmc_info = dev->hmc_info;
48073f49d684SMustafa Ismail hmc_fpm_misc = &dev->hmc_fpm_misc;
48083f49d684SMustafa Ismail
48093f49d684SMustafa Ismail ret_code = irdma_sc_init_iw_hmc(dev, dev->hmc_fn_id);
48103f49d684SMustafa Ismail if (ret_code) {
48113f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
48123f49d684SMustafa Ismail "HMC: irdma_sc_init_iw_hmc returned error_code = %d\n",
48133f49d684SMustafa Ismail ret_code);
48143f49d684SMustafa Ismail return ret_code;
48153f49d684SMustafa Ismail }
48163f49d684SMustafa Ismail
48173f49d684SMustafa Ismail for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++)
48183f49d684SMustafa Ismail hmc_info->hmc_obj[i].cnt = hmc_info->hmc_obj[i].max_cnt;
48193f49d684SMustafa Ismail sd_needed = irdma_est_sd(dev, hmc_info);
48203f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
48213f49d684SMustafa Ismail "HMC: FW max resources sd_needed[%08d] first_sd_index[%04d]\n",
48223f49d684SMustafa Ismail sd_needed, hmc_info->first_sd_index);
48233f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev), "HMC: sd count %d where max sd is %d\n",
48243f49d684SMustafa Ismail hmc_info->sd_table.sd_cnt, hmc_fpm_misc->max_sds);
48253f49d684SMustafa Ismail
48263f49d684SMustafa Ismail qpwanted = min(qp_count, hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt);
48273f49d684SMustafa Ismail
48283f49d684SMustafa Ismail powerof2 = 1;
48293f49d684SMustafa Ismail while (powerof2 <= qpwanted)
48303f49d684SMustafa Ismail powerof2 *= 2;
48313f49d684SMustafa Ismail powerof2 /= 2;
48323f49d684SMustafa Ismail qpwanted = powerof2;
48333f49d684SMustafa Ismail
48343f49d684SMustafa Ismail mrwanted = hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt;
48353f49d684SMustafa Ismail pblewanted = hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].max_cnt;
48363f49d684SMustafa Ismail
48373f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
48383f49d684SMustafa Ismail "HMC: req_qp=%d max_sd=%d, max_qp = %d, max_cq=%d, max_mr=%d, max_pble=%d, mc=%d, av=%d\n",
48393f49d684SMustafa Ismail qp_count, hmc_fpm_misc->max_sds,
48403f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt,
48413f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].max_cnt,
48423f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt,
48433f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].max_cnt,
48443f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].max_cnt,
48453f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt);
48463f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt =
48473f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].max_cnt;
48483f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt =
48493f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt;
48503f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_ARP].cnt =
48513f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_ARP].max_cnt;
48523f49d684SMustafa Ismail
48533f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_APBVT_ENTRY].cnt = 1;
48543f49d684SMustafa Ismail
48553f49d684SMustafa Ismail while (irdma_q1_cnt(dev, hmc_info, qpwanted) > hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].max_cnt)
48563f49d684SMustafa Ismail qpwanted /= 2;
48573f49d684SMustafa Ismail
48583f49d684SMustafa Ismail do {
48593f49d684SMustafa Ismail ++loop_count;
48603f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_QP].cnt = qpwanted;
48613f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt =
48623f49d684SMustafa Ismail min(2 * qpwanted, hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt);
48633f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_RESERVED].cnt = 0; /* Reserved */
48643f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt = mrwanted;
48653f49d684SMustafa Ismail
48663f49d684SMustafa Ismail hte = round_up(qpwanted + hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt, 512);
48673f49d684SMustafa Ismail powerof2 = 1;
48683f49d684SMustafa Ismail while (powerof2 < hte)
48693f49d684SMustafa Ismail powerof2 *= 2;
48703f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_HTE].cnt =
48713f49d684SMustafa Ismail powerof2 * hmc_fpm_misc->ht_multiplier;
48723f49d684SMustafa Ismail if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
48733f49d684SMustafa Ismail cfg_fpm_value_gen_1(dev, hmc_info, qpwanted);
48743f49d684SMustafa Ismail else
48753f49d684SMustafa Ismail cfg_fpm_value_gen_2(dev, hmc_info, qpwanted);
48763f49d684SMustafa Ismail
48773f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt = irdma_q1_cnt(dev, hmc_info, qpwanted);
48783f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_XFFL].cnt =
48793f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt / hmc_fpm_misc->xf_block_size;
48803f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_Q1FL].cnt =
48813f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt / hmc_fpm_misc->q1_block_size;
48823f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_TIMER].cnt =
48833f49d684SMustafa Ismail (round_up(qpwanted, 512) / 512 + 1) * hmc_fpm_misc->timer_bucket;
48843f49d684SMustafa Ismail
48853f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt = pblewanted;
48863f49d684SMustafa Ismail sd_needed = irdma_est_sd(dev, hmc_info);
48873f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
48883f49d684SMustafa Ismail "HMC: sd_needed = %d, hmc_fpm_misc->max_sds=%d, mrwanted=%d, pblewanted=%d qpwanted=%d\n",
48893f49d684SMustafa Ismail sd_needed, hmc_fpm_misc->max_sds, mrwanted,
48903f49d684SMustafa Ismail pblewanted, qpwanted);
48913f49d684SMustafa Ismail
48923f49d684SMustafa Ismail /* Do not reduce resources further. All objects fit with max SDs */
48933f49d684SMustafa Ismail if (sd_needed <= hmc_fpm_misc->max_sds)
48943f49d684SMustafa Ismail break;
48953f49d684SMustafa Ismail
48963f49d684SMustafa Ismail sd_diff = sd_needed - hmc_fpm_misc->max_sds;
48973f49d684SMustafa Ismail if (sd_diff > 128) {
4898c8c7c075SNayan Kumar if (!(loop_count % 2) && qpwanted > 128) {
48993f49d684SMustafa Ismail qpwanted /= 2;
4900c8c7c075SNayan Kumar } else {
49013f49d684SMustafa Ismail mrwanted /= 2;
49023f49d684SMustafa Ismail pblewanted /= 2;
4903c8c7c075SNayan Kumar }
49043f49d684SMustafa Ismail continue;
49053f49d684SMustafa Ismail }
49063f49d684SMustafa Ismail if (dev->cqp->hmc_profile != IRDMA_HMC_PROFILE_FAVOR_VF &&
49073f49d684SMustafa Ismail pblewanted > (512 * FPM_MULTIPLIER * sd_diff)) {
49083f49d684SMustafa Ismail pblewanted -= 256 * FPM_MULTIPLIER * sd_diff;
49093f49d684SMustafa Ismail continue;
49103f49d684SMustafa Ismail } else if (pblewanted > (100 * FPM_MULTIPLIER)) {
49113f49d684SMustafa Ismail pblewanted -= 10 * FPM_MULTIPLIER;
49123f49d684SMustafa Ismail } else if (pblewanted > FPM_MULTIPLIER) {
49133f49d684SMustafa Ismail pblewanted -= FPM_MULTIPLIER;
49143f49d684SMustafa Ismail } else if (qpwanted <= 128) {
49153f49d684SMustafa Ismail if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt > 256)
49163f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt /= 2;
49173f49d684SMustafa Ismail if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt > 256)
49183f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt /= 2;
49193f49d684SMustafa Ismail }
49203f49d684SMustafa Ismail if (mrwanted > FPM_MULTIPLIER)
49213f49d684SMustafa Ismail mrwanted -= FPM_MULTIPLIER;
49223f49d684SMustafa Ismail if (!(loop_count % 10) && qpwanted > 128) {
49233f49d684SMustafa Ismail qpwanted /= 2;
49243f49d684SMustafa Ismail if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt > 256)
49253f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt /= 2;
49263f49d684SMustafa Ismail }
49273f49d684SMustafa Ismail } while (loop_count < 2000);
49283f49d684SMustafa Ismail
49293f49d684SMustafa Ismail if (sd_needed > hmc_fpm_misc->max_sds) {
49303f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
49313f49d684SMustafa Ismail "HMC: cfg_fpm failed loop_cnt=%d, sd_needed=%d, max sd count %d\n",
49323f49d684SMustafa Ismail loop_count, sd_needed, hmc_info->sd_table.sd_cnt);
49332c4b14eaSShiraz Saleem return -EINVAL;
49343f49d684SMustafa Ismail }
49353f49d684SMustafa Ismail
49363f49d684SMustafa Ismail if (loop_count > 1 && sd_needed < hmc_fpm_misc->max_sds) {
49373f49d684SMustafa Ismail pblewanted += (hmc_fpm_misc->max_sds - sd_needed) * 256 *
49383f49d684SMustafa Ismail FPM_MULTIPLIER;
49393f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt = pblewanted;
49403f49d684SMustafa Ismail sd_needed = irdma_est_sd(dev, hmc_info);
49413f49d684SMustafa Ismail }
49423f49d684SMustafa Ismail
49433f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
49443f49d684SMustafa Ismail "HMC: loop_cnt=%d, sd_needed=%d, qpcnt = %d, cqcnt=%d, mrcnt=%d, pblecnt=%d, mc=%d, ah=%d, max sd count %d, first sd index %d\n",
49453f49d684SMustafa Ismail loop_count, sd_needed,
49463f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_QP].cnt,
49473f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt,
49483f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt,
49493f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt,
49503f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt,
49513f49d684SMustafa Ismail hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt,
49523f49d684SMustafa Ismail hmc_info->sd_table.sd_cnt, hmc_info->first_sd_index);
49533f49d684SMustafa Ismail
49543f49d684SMustafa Ismail ret_code = irdma_sc_cfg_iw_fpm(dev, dev->hmc_fn_id);
49553f49d684SMustafa Ismail if (ret_code) {
49563f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
49573f49d684SMustafa Ismail "HMC: cfg_iw_fpm returned error_code[x%08X]\n",
49583f49d684SMustafa Ismail readl(dev->hw_regs[IRDMA_CQPERRCODES]));
49593f49d684SMustafa Ismail return ret_code;
49603f49d684SMustafa Ismail }
49613f49d684SMustafa Ismail
49623f49d684SMustafa Ismail mem_size = sizeof(struct irdma_hmc_sd_entry) *
49633f49d684SMustafa Ismail (hmc_info->sd_table.sd_cnt + hmc_info->first_sd_index + 1);
49643f49d684SMustafa Ismail virt_mem.size = mem_size;
49653f49d684SMustafa Ismail virt_mem.va = kzalloc(virt_mem.size, GFP_KERNEL);
49663f49d684SMustafa Ismail if (!virt_mem.va) {
49673f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
49683f49d684SMustafa Ismail "HMC: failed to allocate memory for sd_entry buffer\n");
49692c4b14eaSShiraz Saleem return -ENOMEM;
49703f49d684SMustafa Ismail }
49713f49d684SMustafa Ismail hmc_info->sd_table.sd_entry = virt_mem.va;
49723f49d684SMustafa Ismail
49733f49d684SMustafa Ismail return ret_code;
49743f49d684SMustafa Ismail }
49753f49d684SMustafa Ismail
49763f49d684SMustafa Ismail /**
49773f49d684SMustafa Ismail * irdma_exec_cqp_cmd - execute cqp cmd when wqe are available
49783f49d684SMustafa Ismail * @dev: rdma device
49793f49d684SMustafa Ismail * @pcmdinfo: cqp command info
49803f49d684SMustafa Ismail */
irdma_exec_cqp_cmd(struct irdma_sc_dev * dev,struct cqp_cmds_info * pcmdinfo)49812c4b14eaSShiraz Saleem static int irdma_exec_cqp_cmd(struct irdma_sc_dev *dev,
49823f49d684SMustafa Ismail struct cqp_cmds_info *pcmdinfo)
49833f49d684SMustafa Ismail {
49842c4b14eaSShiraz Saleem int status;
49853f49d684SMustafa Ismail struct irdma_dma_mem val_mem;
49863f49d684SMustafa Ismail bool alloc = false;
49873f49d684SMustafa Ismail
49883f49d684SMustafa Ismail dev->cqp_cmd_stats[pcmdinfo->cqp_cmd]++;
49893f49d684SMustafa Ismail switch (pcmdinfo->cqp_cmd) {
49903f49d684SMustafa Ismail case IRDMA_OP_CEQ_DESTROY:
49913f49d684SMustafa Ismail status = irdma_sc_ceq_destroy(pcmdinfo->in.u.ceq_destroy.ceq,
49923f49d684SMustafa Ismail pcmdinfo->in.u.ceq_destroy.scratch,
49933f49d684SMustafa Ismail pcmdinfo->post_sq);
49943f49d684SMustafa Ismail break;
49953f49d684SMustafa Ismail case IRDMA_OP_AEQ_DESTROY:
49963f49d684SMustafa Ismail status = irdma_sc_aeq_destroy(pcmdinfo->in.u.aeq_destroy.aeq,
49973f49d684SMustafa Ismail pcmdinfo->in.u.aeq_destroy.scratch,
49983f49d684SMustafa Ismail pcmdinfo->post_sq);
49993f49d684SMustafa Ismail
50003f49d684SMustafa Ismail break;
50013f49d684SMustafa Ismail case IRDMA_OP_CEQ_CREATE:
50023f49d684SMustafa Ismail status = irdma_sc_ceq_create(pcmdinfo->in.u.ceq_create.ceq,
50033f49d684SMustafa Ismail pcmdinfo->in.u.ceq_create.scratch,
50043f49d684SMustafa Ismail pcmdinfo->post_sq);
50053f49d684SMustafa Ismail break;
50063f49d684SMustafa Ismail case IRDMA_OP_AEQ_CREATE:
50073f49d684SMustafa Ismail status = irdma_sc_aeq_create(pcmdinfo->in.u.aeq_create.aeq,
50083f49d684SMustafa Ismail pcmdinfo->in.u.aeq_create.scratch,
50093f49d684SMustafa Ismail pcmdinfo->post_sq);
50103f49d684SMustafa Ismail break;
50113f49d684SMustafa Ismail case IRDMA_OP_QP_UPLOAD_CONTEXT:
50123f49d684SMustafa Ismail status = irdma_sc_qp_upload_context(pcmdinfo->in.u.qp_upload_context.dev,
50133f49d684SMustafa Ismail &pcmdinfo->in.u.qp_upload_context.info,
50143f49d684SMustafa Ismail pcmdinfo->in.u.qp_upload_context.scratch,
50153f49d684SMustafa Ismail pcmdinfo->post_sq);
50163f49d684SMustafa Ismail break;
50173f49d684SMustafa Ismail case IRDMA_OP_CQ_CREATE:
50183f49d684SMustafa Ismail status = irdma_sc_cq_create(pcmdinfo->in.u.cq_create.cq,
50193f49d684SMustafa Ismail pcmdinfo->in.u.cq_create.scratch,
50203f49d684SMustafa Ismail pcmdinfo->in.u.cq_create.check_overflow,
50213f49d684SMustafa Ismail pcmdinfo->post_sq);
50223f49d684SMustafa Ismail break;
50233f49d684SMustafa Ismail case IRDMA_OP_CQ_MODIFY:
50243f49d684SMustafa Ismail status = irdma_sc_cq_modify(pcmdinfo->in.u.cq_modify.cq,
50253f49d684SMustafa Ismail &pcmdinfo->in.u.cq_modify.info,
50263f49d684SMustafa Ismail pcmdinfo->in.u.cq_modify.scratch,
50273f49d684SMustafa Ismail pcmdinfo->post_sq);
50283f49d684SMustafa Ismail break;
50293f49d684SMustafa Ismail case IRDMA_OP_CQ_DESTROY:
50303f49d684SMustafa Ismail status = irdma_sc_cq_destroy(pcmdinfo->in.u.cq_destroy.cq,
50313f49d684SMustafa Ismail pcmdinfo->in.u.cq_destroy.scratch,
50323f49d684SMustafa Ismail pcmdinfo->post_sq);
50333f49d684SMustafa Ismail break;
50343f49d684SMustafa Ismail case IRDMA_OP_QP_FLUSH_WQES:
50353f49d684SMustafa Ismail status = irdma_sc_qp_flush_wqes(pcmdinfo->in.u.qp_flush_wqes.qp,
50363f49d684SMustafa Ismail &pcmdinfo->in.u.qp_flush_wqes.info,
50373f49d684SMustafa Ismail pcmdinfo->in.u.qp_flush_wqes.scratch,
50383f49d684SMustafa Ismail pcmdinfo->post_sq);
50393f49d684SMustafa Ismail break;
50403f49d684SMustafa Ismail case IRDMA_OP_GEN_AE:
50413f49d684SMustafa Ismail status = irdma_sc_gen_ae(pcmdinfo->in.u.gen_ae.qp,
50423f49d684SMustafa Ismail &pcmdinfo->in.u.gen_ae.info,
50433f49d684SMustafa Ismail pcmdinfo->in.u.gen_ae.scratch,
50443f49d684SMustafa Ismail pcmdinfo->post_sq);
50453f49d684SMustafa Ismail break;
50463f49d684SMustafa Ismail case IRDMA_OP_MANAGE_PUSH_PAGE:
50473f49d684SMustafa Ismail status = irdma_sc_manage_push_page(pcmdinfo->in.u.manage_push_page.cqp,
50483f49d684SMustafa Ismail &pcmdinfo->in.u.manage_push_page.info,
50493f49d684SMustafa Ismail pcmdinfo->in.u.manage_push_page.scratch,
50503f49d684SMustafa Ismail pcmdinfo->post_sq);
50513f49d684SMustafa Ismail break;
50523f49d684SMustafa Ismail case IRDMA_OP_UPDATE_PE_SDS:
50533f49d684SMustafa Ismail status = irdma_update_pe_sds(pcmdinfo->in.u.update_pe_sds.dev,
50543f49d684SMustafa Ismail &pcmdinfo->in.u.update_pe_sds.info,
50553f49d684SMustafa Ismail pcmdinfo->in.u.update_pe_sds.scratch);
50563f49d684SMustafa Ismail break;
50573f49d684SMustafa Ismail case IRDMA_OP_MANAGE_HMC_PM_FUNC_TABLE:
50583f49d684SMustafa Ismail /* switch to calling through the call table */
50593f49d684SMustafa Ismail status =
50603f49d684SMustafa Ismail irdma_sc_manage_hmc_pm_func_table(pcmdinfo->in.u.manage_hmc_pm.dev->cqp,
50613f49d684SMustafa Ismail &pcmdinfo->in.u.manage_hmc_pm.info,
50623f49d684SMustafa Ismail pcmdinfo->in.u.manage_hmc_pm.scratch,
50633f49d684SMustafa Ismail true);
50643f49d684SMustafa Ismail break;
50653f49d684SMustafa Ismail case IRDMA_OP_SUSPEND:
50663f49d684SMustafa Ismail status = irdma_sc_suspend_qp(pcmdinfo->in.u.suspend_resume.cqp,
50673f49d684SMustafa Ismail pcmdinfo->in.u.suspend_resume.qp,
50683f49d684SMustafa Ismail pcmdinfo->in.u.suspend_resume.scratch);
50693f49d684SMustafa Ismail break;
50703f49d684SMustafa Ismail case IRDMA_OP_RESUME:
50713f49d684SMustafa Ismail status = irdma_sc_resume_qp(pcmdinfo->in.u.suspend_resume.cqp,
50723f49d684SMustafa Ismail pcmdinfo->in.u.suspend_resume.qp,
50733f49d684SMustafa Ismail pcmdinfo->in.u.suspend_resume.scratch);
50743f49d684SMustafa Ismail break;
50753f49d684SMustafa Ismail case IRDMA_OP_QUERY_FPM_VAL:
50763f49d684SMustafa Ismail val_mem.pa = pcmdinfo->in.u.query_fpm_val.fpm_val_pa;
50773f49d684SMustafa Ismail val_mem.va = pcmdinfo->in.u.query_fpm_val.fpm_val_va;
50783f49d684SMustafa Ismail status = irdma_sc_query_fpm_val(pcmdinfo->in.u.query_fpm_val.cqp,
50793f49d684SMustafa Ismail pcmdinfo->in.u.query_fpm_val.scratch,
50803f49d684SMustafa Ismail pcmdinfo->in.u.query_fpm_val.hmc_fn_id,
50813f49d684SMustafa Ismail &val_mem, true, IRDMA_CQP_WAIT_EVENT);
50823f49d684SMustafa Ismail break;
50833f49d684SMustafa Ismail case IRDMA_OP_COMMIT_FPM_VAL:
50843f49d684SMustafa Ismail val_mem.pa = pcmdinfo->in.u.commit_fpm_val.fpm_val_pa;
50853f49d684SMustafa Ismail val_mem.va = pcmdinfo->in.u.commit_fpm_val.fpm_val_va;
50863f49d684SMustafa Ismail status = irdma_sc_commit_fpm_val(pcmdinfo->in.u.commit_fpm_val.cqp,
50873f49d684SMustafa Ismail pcmdinfo->in.u.commit_fpm_val.scratch,
50883f49d684SMustafa Ismail pcmdinfo->in.u.commit_fpm_val.hmc_fn_id,
50893f49d684SMustafa Ismail &val_mem,
50903f49d684SMustafa Ismail true,
50913f49d684SMustafa Ismail IRDMA_CQP_WAIT_EVENT);
50923f49d684SMustafa Ismail break;
50933f49d684SMustafa Ismail case IRDMA_OP_STATS_ALLOCATE:
50943f49d684SMustafa Ismail alloc = true;
50953f49d684SMustafa Ismail fallthrough;
50963f49d684SMustafa Ismail case IRDMA_OP_STATS_FREE:
50973f49d684SMustafa Ismail status = irdma_sc_manage_stats_inst(pcmdinfo->in.u.stats_manage.cqp,
50983f49d684SMustafa Ismail &pcmdinfo->in.u.stats_manage.info,
50993f49d684SMustafa Ismail alloc,
51003f49d684SMustafa Ismail pcmdinfo->in.u.stats_manage.scratch);
51013f49d684SMustafa Ismail break;
51023f49d684SMustafa Ismail case IRDMA_OP_STATS_GATHER:
51033f49d684SMustafa Ismail status = irdma_sc_gather_stats(pcmdinfo->in.u.stats_gather.cqp,
51043f49d684SMustafa Ismail &pcmdinfo->in.u.stats_gather.info,
51053f49d684SMustafa Ismail pcmdinfo->in.u.stats_gather.scratch);
51063f49d684SMustafa Ismail break;
51073f49d684SMustafa Ismail case IRDMA_OP_WS_MODIFY_NODE:
51083f49d684SMustafa Ismail status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp,
51093f49d684SMustafa Ismail &pcmdinfo->in.u.ws_node.info,
51103f49d684SMustafa Ismail IRDMA_MODIFY_NODE,
51113f49d684SMustafa Ismail pcmdinfo->in.u.ws_node.scratch);
51123f49d684SMustafa Ismail break;
51133f49d684SMustafa Ismail case IRDMA_OP_WS_DELETE_NODE:
51143f49d684SMustafa Ismail status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp,
51153f49d684SMustafa Ismail &pcmdinfo->in.u.ws_node.info,
51163f49d684SMustafa Ismail IRDMA_DEL_NODE,
51173f49d684SMustafa Ismail pcmdinfo->in.u.ws_node.scratch);
51183f49d684SMustafa Ismail break;
51193f49d684SMustafa Ismail case IRDMA_OP_WS_ADD_NODE:
51203f49d684SMustafa Ismail status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp,
51213f49d684SMustafa Ismail &pcmdinfo->in.u.ws_node.info,
51223f49d684SMustafa Ismail IRDMA_ADD_NODE,
51233f49d684SMustafa Ismail pcmdinfo->in.u.ws_node.scratch);
51243f49d684SMustafa Ismail break;
51253f49d684SMustafa Ismail case IRDMA_OP_SET_UP_MAP:
51263f49d684SMustafa Ismail status = irdma_sc_set_up_map(pcmdinfo->in.u.up_map.cqp,
51273f49d684SMustafa Ismail &pcmdinfo->in.u.up_map.info,
51283f49d684SMustafa Ismail pcmdinfo->in.u.up_map.scratch);
51293f49d684SMustafa Ismail break;
51303f49d684SMustafa Ismail case IRDMA_OP_QUERY_RDMA_FEATURES:
51313f49d684SMustafa Ismail status = irdma_sc_query_rdma_features(pcmdinfo->in.u.query_rdma.cqp,
51323f49d684SMustafa Ismail &pcmdinfo->in.u.query_rdma.query_buff_mem,
51333f49d684SMustafa Ismail pcmdinfo->in.u.query_rdma.scratch);
51343f49d684SMustafa Ismail break;
51353f49d684SMustafa Ismail case IRDMA_OP_DELETE_ARP_CACHE_ENTRY:
51363f49d684SMustafa Ismail status = irdma_sc_del_arp_cache_entry(pcmdinfo->in.u.del_arp_cache_entry.cqp,
51373f49d684SMustafa Ismail pcmdinfo->in.u.del_arp_cache_entry.scratch,
51383f49d684SMustafa Ismail pcmdinfo->in.u.del_arp_cache_entry.arp_index,
51393f49d684SMustafa Ismail pcmdinfo->post_sq);
51403f49d684SMustafa Ismail break;
51413f49d684SMustafa Ismail case IRDMA_OP_MANAGE_APBVT_ENTRY:
51423f49d684SMustafa Ismail status = irdma_sc_manage_apbvt_entry(pcmdinfo->in.u.manage_apbvt_entry.cqp,
51433f49d684SMustafa Ismail &pcmdinfo->in.u.manage_apbvt_entry.info,
51443f49d684SMustafa Ismail pcmdinfo->in.u.manage_apbvt_entry.scratch,
51453f49d684SMustafa Ismail pcmdinfo->post_sq);
51463f49d684SMustafa Ismail break;
51473f49d684SMustafa Ismail case IRDMA_OP_MANAGE_QHASH_TABLE_ENTRY:
51483f49d684SMustafa Ismail status = irdma_sc_manage_qhash_table_entry(pcmdinfo->in.u.manage_qhash_table_entry.cqp,
51493f49d684SMustafa Ismail &pcmdinfo->in.u.manage_qhash_table_entry.info,
51503f49d684SMustafa Ismail pcmdinfo->in.u.manage_qhash_table_entry.scratch,
51513f49d684SMustafa Ismail pcmdinfo->post_sq);
51523f49d684SMustafa Ismail break;
51533f49d684SMustafa Ismail case IRDMA_OP_QP_MODIFY:
51543f49d684SMustafa Ismail status = irdma_sc_qp_modify(pcmdinfo->in.u.qp_modify.qp,
51553f49d684SMustafa Ismail &pcmdinfo->in.u.qp_modify.info,
51563f49d684SMustafa Ismail pcmdinfo->in.u.qp_modify.scratch,
51573f49d684SMustafa Ismail pcmdinfo->post_sq);
51583f49d684SMustafa Ismail break;
51593f49d684SMustafa Ismail case IRDMA_OP_QP_CREATE:
51603f49d684SMustafa Ismail status = irdma_sc_qp_create(pcmdinfo->in.u.qp_create.qp,
51613f49d684SMustafa Ismail &pcmdinfo->in.u.qp_create.info,
51623f49d684SMustafa Ismail pcmdinfo->in.u.qp_create.scratch,
51633f49d684SMustafa Ismail pcmdinfo->post_sq);
51643f49d684SMustafa Ismail break;
51653f49d684SMustafa Ismail case IRDMA_OP_QP_DESTROY:
51663f49d684SMustafa Ismail status = irdma_sc_qp_destroy(pcmdinfo->in.u.qp_destroy.qp,
51673f49d684SMustafa Ismail pcmdinfo->in.u.qp_destroy.scratch,
51683f49d684SMustafa Ismail pcmdinfo->in.u.qp_destroy.remove_hash_idx,
51693f49d684SMustafa Ismail pcmdinfo->in.u.qp_destroy.ignore_mw_bnd,
51703f49d684SMustafa Ismail pcmdinfo->post_sq);
51713f49d684SMustafa Ismail break;
51723f49d684SMustafa Ismail case IRDMA_OP_ALLOC_STAG:
51733f49d684SMustafa Ismail status = irdma_sc_alloc_stag(pcmdinfo->in.u.alloc_stag.dev,
51743f49d684SMustafa Ismail &pcmdinfo->in.u.alloc_stag.info,
51753f49d684SMustafa Ismail pcmdinfo->in.u.alloc_stag.scratch,
51763f49d684SMustafa Ismail pcmdinfo->post_sq);
51773f49d684SMustafa Ismail break;
51783f49d684SMustafa Ismail case IRDMA_OP_MR_REG_NON_SHARED:
51793f49d684SMustafa Ismail status = irdma_sc_mr_reg_non_shared(pcmdinfo->in.u.mr_reg_non_shared.dev,
51803f49d684SMustafa Ismail &pcmdinfo->in.u.mr_reg_non_shared.info,
51813f49d684SMustafa Ismail pcmdinfo->in.u.mr_reg_non_shared.scratch,
51823f49d684SMustafa Ismail pcmdinfo->post_sq);
51833f49d684SMustafa Ismail break;
51843f49d684SMustafa Ismail case IRDMA_OP_DEALLOC_STAG:
51853f49d684SMustafa Ismail status = irdma_sc_dealloc_stag(pcmdinfo->in.u.dealloc_stag.dev,
51863f49d684SMustafa Ismail &pcmdinfo->in.u.dealloc_stag.info,
51873f49d684SMustafa Ismail pcmdinfo->in.u.dealloc_stag.scratch,
51883f49d684SMustafa Ismail pcmdinfo->post_sq);
51893f49d684SMustafa Ismail break;
51903f49d684SMustafa Ismail case IRDMA_OP_MW_ALLOC:
51913f49d684SMustafa Ismail status = irdma_sc_mw_alloc(pcmdinfo->in.u.mw_alloc.dev,
51923f49d684SMustafa Ismail &pcmdinfo->in.u.mw_alloc.info,
51933f49d684SMustafa Ismail pcmdinfo->in.u.mw_alloc.scratch,
51943f49d684SMustafa Ismail pcmdinfo->post_sq);
51953f49d684SMustafa Ismail break;
51963f49d684SMustafa Ismail case IRDMA_OP_ADD_ARP_CACHE_ENTRY:
51973f49d684SMustafa Ismail status = irdma_sc_add_arp_cache_entry(pcmdinfo->in.u.add_arp_cache_entry.cqp,
51983f49d684SMustafa Ismail &pcmdinfo->in.u.add_arp_cache_entry.info,
51993f49d684SMustafa Ismail pcmdinfo->in.u.add_arp_cache_entry.scratch,
52003f49d684SMustafa Ismail pcmdinfo->post_sq);
52013f49d684SMustafa Ismail break;
52023f49d684SMustafa Ismail case IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY:
52033f49d684SMustafa Ismail status = irdma_sc_alloc_local_mac_entry(pcmdinfo->in.u.alloc_local_mac_entry.cqp,
52043f49d684SMustafa Ismail pcmdinfo->in.u.alloc_local_mac_entry.scratch,
52053f49d684SMustafa Ismail pcmdinfo->post_sq);
52063f49d684SMustafa Ismail break;
52073f49d684SMustafa Ismail case IRDMA_OP_ADD_LOCAL_MAC_ENTRY:
52083f49d684SMustafa Ismail status = irdma_sc_add_local_mac_entry(pcmdinfo->in.u.add_local_mac_entry.cqp,
52093f49d684SMustafa Ismail &pcmdinfo->in.u.add_local_mac_entry.info,
52103f49d684SMustafa Ismail pcmdinfo->in.u.add_local_mac_entry.scratch,
52113f49d684SMustafa Ismail pcmdinfo->post_sq);
52123f49d684SMustafa Ismail break;
52133f49d684SMustafa Ismail case IRDMA_OP_DELETE_LOCAL_MAC_ENTRY:
52143f49d684SMustafa Ismail status = irdma_sc_del_local_mac_entry(pcmdinfo->in.u.del_local_mac_entry.cqp,
52153f49d684SMustafa Ismail pcmdinfo->in.u.del_local_mac_entry.scratch,
52163f49d684SMustafa Ismail pcmdinfo->in.u.del_local_mac_entry.entry_idx,
52173f49d684SMustafa Ismail pcmdinfo->in.u.del_local_mac_entry.ignore_ref_count,
52183f49d684SMustafa Ismail pcmdinfo->post_sq);
52193f49d684SMustafa Ismail break;
52203f49d684SMustafa Ismail case IRDMA_OP_AH_CREATE:
52213f49d684SMustafa Ismail status = irdma_sc_create_ah(pcmdinfo->in.u.ah_create.cqp,
52223f49d684SMustafa Ismail &pcmdinfo->in.u.ah_create.info,
52233f49d684SMustafa Ismail pcmdinfo->in.u.ah_create.scratch);
52243f49d684SMustafa Ismail break;
52253f49d684SMustafa Ismail case IRDMA_OP_AH_DESTROY:
52263f49d684SMustafa Ismail status = irdma_sc_destroy_ah(pcmdinfo->in.u.ah_destroy.cqp,
52273f49d684SMustafa Ismail &pcmdinfo->in.u.ah_destroy.info,
52283f49d684SMustafa Ismail pcmdinfo->in.u.ah_destroy.scratch);
52293f49d684SMustafa Ismail break;
52303f49d684SMustafa Ismail case IRDMA_OP_MC_CREATE:
52313f49d684SMustafa Ismail status = irdma_sc_create_mcast_grp(pcmdinfo->in.u.mc_create.cqp,
52323f49d684SMustafa Ismail &pcmdinfo->in.u.mc_create.info,
52333f49d684SMustafa Ismail pcmdinfo->in.u.mc_create.scratch);
52343f49d684SMustafa Ismail break;
52353f49d684SMustafa Ismail case IRDMA_OP_MC_DESTROY:
52363f49d684SMustafa Ismail status = irdma_sc_destroy_mcast_grp(pcmdinfo->in.u.mc_destroy.cqp,
52373f49d684SMustafa Ismail &pcmdinfo->in.u.mc_destroy.info,
52383f49d684SMustafa Ismail pcmdinfo->in.u.mc_destroy.scratch);
52393f49d684SMustafa Ismail break;
52403f49d684SMustafa Ismail case IRDMA_OP_MC_MODIFY:
52413f49d684SMustafa Ismail status = irdma_sc_modify_mcast_grp(pcmdinfo->in.u.mc_modify.cqp,
52423f49d684SMustafa Ismail &pcmdinfo->in.u.mc_modify.info,
52433f49d684SMustafa Ismail pcmdinfo->in.u.mc_modify.scratch);
52443f49d684SMustafa Ismail break;
52453f49d684SMustafa Ismail default:
52462c4b14eaSShiraz Saleem status = -EOPNOTSUPP;
52473f49d684SMustafa Ismail break;
52483f49d684SMustafa Ismail }
52493f49d684SMustafa Ismail
52503f49d684SMustafa Ismail return status;
52513f49d684SMustafa Ismail }
52523f49d684SMustafa Ismail
52533f49d684SMustafa Ismail /**
52543f49d684SMustafa Ismail * irdma_process_cqp_cmd - process all cqp commands
52553f49d684SMustafa Ismail * @dev: sc device struct
52563f49d684SMustafa Ismail * @pcmdinfo: cqp command info
52573f49d684SMustafa Ismail */
irdma_process_cqp_cmd(struct irdma_sc_dev * dev,struct cqp_cmds_info * pcmdinfo)52582c4b14eaSShiraz Saleem int irdma_process_cqp_cmd(struct irdma_sc_dev *dev,
52593f49d684SMustafa Ismail struct cqp_cmds_info *pcmdinfo)
52603f49d684SMustafa Ismail {
52612c4b14eaSShiraz Saleem int status = 0;
52623f49d684SMustafa Ismail unsigned long flags;
52633f49d684SMustafa Ismail
52643f49d684SMustafa Ismail spin_lock_irqsave(&dev->cqp_lock, flags);
52653f49d684SMustafa Ismail if (list_empty(&dev->cqp_cmd_head) && !irdma_cqp_ring_full(dev->cqp))
52663f49d684SMustafa Ismail status = irdma_exec_cqp_cmd(dev, pcmdinfo);
52673f49d684SMustafa Ismail else
52683f49d684SMustafa Ismail list_add_tail(&pcmdinfo->cqp_cmd_entry, &dev->cqp_cmd_head);
52693f49d684SMustafa Ismail spin_unlock_irqrestore(&dev->cqp_lock, flags);
52703f49d684SMustafa Ismail return status;
52713f49d684SMustafa Ismail }
52723f49d684SMustafa Ismail
52733f49d684SMustafa Ismail /**
52743f49d684SMustafa Ismail * irdma_process_bh - called from tasklet for cqp list
52753f49d684SMustafa Ismail * @dev: sc device struct
52763f49d684SMustafa Ismail */
irdma_process_bh(struct irdma_sc_dev * dev)52772c4b14eaSShiraz Saleem int irdma_process_bh(struct irdma_sc_dev *dev)
52783f49d684SMustafa Ismail {
52792c4b14eaSShiraz Saleem int status = 0;
52803f49d684SMustafa Ismail struct cqp_cmds_info *pcmdinfo;
52813f49d684SMustafa Ismail unsigned long flags;
52823f49d684SMustafa Ismail
52833f49d684SMustafa Ismail spin_lock_irqsave(&dev->cqp_lock, flags);
52843f49d684SMustafa Ismail while (!list_empty(&dev->cqp_cmd_head) &&
52853f49d684SMustafa Ismail !irdma_cqp_ring_full(dev->cqp)) {
52863f49d684SMustafa Ismail pcmdinfo = (struct cqp_cmds_info *)irdma_remove_cqp_head(dev);
52873f49d684SMustafa Ismail status = irdma_exec_cqp_cmd(dev, pcmdinfo);
52883f49d684SMustafa Ismail if (status)
52893f49d684SMustafa Ismail break;
52903f49d684SMustafa Ismail }
52913f49d684SMustafa Ismail spin_unlock_irqrestore(&dev->cqp_lock, flags);
52923f49d684SMustafa Ismail return status;
52933f49d684SMustafa Ismail }
52943f49d684SMustafa Ismail
52953f49d684SMustafa Ismail /**
52963f49d684SMustafa Ismail * irdma_cfg_aeq- Configure AEQ interrupt
52973f49d684SMustafa Ismail * @dev: pointer to the device structure
52983f49d684SMustafa Ismail * @idx: vector index
52993f49d684SMustafa Ismail * @enable: True to enable, False disables
53003f49d684SMustafa Ismail */
irdma_cfg_aeq(struct irdma_sc_dev * dev,u32 idx,bool enable)53013f49d684SMustafa Ismail void irdma_cfg_aeq(struct irdma_sc_dev *dev, u32 idx, bool enable)
53023f49d684SMustafa Ismail {
53033f49d684SMustafa Ismail u32 reg_val;
53043f49d684SMustafa Ismail
53053f49d684SMustafa Ismail reg_val = FIELD_PREP(IRDMA_PFINT_AEQCTL_CAUSE_ENA, enable) |
53063f49d684SMustafa Ismail FIELD_PREP(IRDMA_PFINT_AEQCTL_MSIX_INDX, idx) |
53073f49d684SMustafa Ismail FIELD_PREP(IRDMA_PFINT_AEQCTL_ITR_INDX, 3);
53083f49d684SMustafa Ismail writel(reg_val, dev->hw_regs[IRDMA_PFINT_AEQCTL]);
53093f49d684SMustafa Ismail }
53103f49d684SMustafa Ismail
53113f49d684SMustafa Ismail /**
53123f49d684SMustafa Ismail * sc_vsi_update_stats - Update statistics
53133f49d684SMustafa Ismail * @vsi: sc_vsi instance to update
53143f49d684SMustafa Ismail */
sc_vsi_update_stats(struct irdma_sc_vsi * vsi)53153f49d684SMustafa Ismail void sc_vsi_update_stats(struct irdma_sc_vsi *vsi)
53163f49d684SMustafa Ismail {
53173f49d684SMustafa Ismail struct irdma_gather_stats *gather_stats;
53183f49d684SMustafa Ismail struct irdma_gather_stats *last_gather_stats;
53193f49d684SMustafa Ismail
53203f49d684SMustafa Ismail gather_stats = vsi->pestat->gather_info.gather_stats_va;
53213f49d684SMustafa Ismail last_gather_stats = vsi->pestat->gather_info.last_gather_stats_va;
53223f49d684SMustafa Ismail irdma_update_stats(&vsi->pestat->hw_stats, gather_stats,
53235a711e58SKrzysztof Czurylo last_gather_stats, vsi->dev->hw_stats_map,
53245a711e58SKrzysztof Czurylo vsi->dev->hw_attrs.max_stat_idx);
53253f49d684SMustafa Ismail }
53263f49d684SMustafa Ismail
53273f49d684SMustafa Ismail /**
53283f49d684SMustafa Ismail * irdma_wait_pe_ready - Check if firmware is ready
53293f49d684SMustafa Ismail * @dev: provides access to registers
53303f49d684SMustafa Ismail */
irdma_wait_pe_ready(struct irdma_sc_dev * dev)53313f49d684SMustafa Ismail static int irdma_wait_pe_ready(struct irdma_sc_dev *dev)
53323f49d684SMustafa Ismail {
53333f49d684SMustafa Ismail u32 statuscpu0;
53343f49d684SMustafa Ismail u32 statuscpu1;
53353f49d684SMustafa Ismail u32 statuscpu2;
53363f49d684SMustafa Ismail u32 retrycount = 0;
53373f49d684SMustafa Ismail
53383f49d684SMustafa Ismail do {
53393f49d684SMustafa Ismail statuscpu0 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS0]);
53403f49d684SMustafa Ismail statuscpu1 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS1]);
53413f49d684SMustafa Ismail statuscpu2 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS2]);
53423f49d684SMustafa Ismail if (statuscpu0 == 0x80 && statuscpu1 == 0x80 &&
53433f49d684SMustafa Ismail statuscpu2 == 0x80)
53443f49d684SMustafa Ismail return 0;
53453f49d684SMustafa Ismail mdelay(1000);
53463f49d684SMustafa Ismail } while (retrycount++ < dev->hw_attrs.max_pe_ready_count);
53473f49d684SMustafa Ismail return -1;
53483f49d684SMustafa Ismail }
53493f49d684SMustafa Ismail
irdma_sc_init_hw(struct irdma_sc_dev * dev)53503f49d684SMustafa Ismail static inline void irdma_sc_init_hw(struct irdma_sc_dev *dev)
53513f49d684SMustafa Ismail {
53523f49d684SMustafa Ismail switch (dev->hw_attrs.uk_attrs.hw_rev) {
53533f49d684SMustafa Ismail case IRDMA_GEN_1:
53543f49d684SMustafa Ismail i40iw_init_hw(dev);
53553f49d684SMustafa Ismail break;
53563f49d684SMustafa Ismail case IRDMA_GEN_2:
53573f49d684SMustafa Ismail icrdma_init_hw(dev);
53583f49d684SMustafa Ismail break;
53593f49d684SMustafa Ismail }
53603f49d684SMustafa Ismail }
53613f49d684SMustafa Ismail
53623f49d684SMustafa Ismail /**
53633f49d684SMustafa Ismail * irdma_sc_dev_init - Initialize control part of device
53643f49d684SMustafa Ismail * @ver: version
53653f49d684SMustafa Ismail * @dev: Device pointer
53663f49d684SMustafa Ismail * @info: Device init info
53673f49d684SMustafa Ismail */
irdma_sc_dev_init(enum irdma_vers ver,struct irdma_sc_dev * dev,struct irdma_device_init_info * info)53682c4b14eaSShiraz Saleem int irdma_sc_dev_init(enum irdma_vers ver, struct irdma_sc_dev *dev,
53693f49d684SMustafa Ismail struct irdma_device_init_info *info)
53703f49d684SMustafa Ismail {
53713f49d684SMustafa Ismail u32 val;
53722c4b14eaSShiraz Saleem int ret_code = 0;
53733f49d684SMustafa Ismail u8 db_size;
53743f49d684SMustafa Ismail
53753f49d684SMustafa Ismail INIT_LIST_HEAD(&dev->cqp_cmd_head); /* for CQP command backlog */
53763f49d684SMustafa Ismail mutex_init(&dev->ws_mutex);
53773f49d684SMustafa Ismail dev->hmc_fn_id = info->hmc_fn_id;
53783f49d684SMustafa Ismail dev->fpm_query_buf_pa = info->fpm_query_buf_pa;
53793f49d684SMustafa Ismail dev->fpm_query_buf = info->fpm_query_buf;
53803f49d684SMustafa Ismail dev->fpm_commit_buf_pa = info->fpm_commit_buf_pa;
53813f49d684SMustafa Ismail dev->fpm_commit_buf = info->fpm_commit_buf;
53823f49d684SMustafa Ismail dev->hw = info->hw;
53833f49d684SMustafa Ismail dev->hw->hw_addr = info->bar0;
53843f49d684SMustafa Ismail /* Setup the hardware limits, hmc may limit further */
53853f49d684SMustafa Ismail dev->hw_attrs.min_hw_qp_id = IRDMA_MIN_IW_QP_ID;
53863f49d684SMustafa Ismail dev->hw_attrs.min_hw_aeq_size = IRDMA_MIN_AEQ_ENTRIES;
53873f49d684SMustafa Ismail dev->hw_attrs.max_hw_aeq_size = IRDMA_MAX_AEQ_ENTRIES;
53883f49d684SMustafa Ismail dev->hw_attrs.min_hw_ceq_size = IRDMA_MIN_CEQ_ENTRIES;
53893f49d684SMustafa Ismail dev->hw_attrs.max_hw_ceq_size = IRDMA_MAX_CEQ_ENTRIES;
53903f49d684SMustafa Ismail dev->hw_attrs.uk_attrs.min_hw_cq_size = IRDMA_MIN_CQ_SIZE;
53913f49d684SMustafa Ismail dev->hw_attrs.uk_attrs.max_hw_cq_size = IRDMA_MAX_CQ_SIZE;
53923f49d684SMustafa Ismail dev->hw_attrs.uk_attrs.max_hw_wq_frags = IRDMA_MAX_WQ_FRAGMENT_COUNT;
53933f49d684SMustafa Ismail dev->hw_attrs.uk_attrs.max_hw_read_sges = IRDMA_MAX_SGE_RD;
53943f49d684SMustafa Ismail dev->hw_attrs.max_hw_outbound_msg_size = IRDMA_MAX_OUTBOUND_MSG_SIZE;
53953f49d684SMustafa Ismail dev->hw_attrs.max_mr_size = IRDMA_MAX_MR_SIZE;
53963f49d684SMustafa Ismail dev->hw_attrs.max_hw_inbound_msg_size = IRDMA_MAX_INBOUND_MSG_SIZE;
53973f49d684SMustafa Ismail dev->hw_attrs.max_hw_device_pages = IRDMA_MAX_PUSH_PAGE_COUNT;
53983f49d684SMustafa Ismail dev->hw_attrs.uk_attrs.max_hw_inline = IRDMA_MAX_INLINE_DATA_SIZE;
53993f49d684SMustafa Ismail dev->hw_attrs.max_hw_wqes = IRDMA_MAX_WQ_ENTRIES;
54003f49d684SMustafa Ismail dev->hw_attrs.max_qp_wr = IRDMA_MAX_QP_WRS(IRDMA_MAX_QUANTA_PER_WR);
54013f49d684SMustafa Ismail
54023f49d684SMustafa Ismail dev->hw_attrs.uk_attrs.max_hw_rq_quanta = IRDMA_QP_SW_MAX_RQ_QUANTA;
54033f49d684SMustafa Ismail dev->hw_attrs.uk_attrs.max_hw_wq_quanta = IRDMA_QP_SW_MAX_WQ_QUANTA;
54043f49d684SMustafa Ismail dev->hw_attrs.max_hw_pds = IRDMA_MAX_PDS;
54053f49d684SMustafa Ismail dev->hw_attrs.max_hw_ena_vf_count = IRDMA_MAX_PE_ENA_VF_COUNT;
54063f49d684SMustafa Ismail
54073f49d684SMustafa Ismail dev->hw_attrs.max_pe_ready_count = 14;
54083f49d684SMustafa Ismail dev->hw_attrs.max_done_count = IRDMA_DONE_COUNT;
54093f49d684SMustafa Ismail dev->hw_attrs.max_sleep_count = IRDMA_SLEEP_COUNT;
54103f49d684SMustafa Ismail dev->hw_attrs.max_cqp_compl_wait_time_ms = CQP_COMPL_WAIT_TIME_MS;
54113f49d684SMustafa Ismail
54123f49d684SMustafa Ismail dev->hw_attrs.uk_attrs.hw_rev = ver;
54133f49d684SMustafa Ismail irdma_sc_init_hw(dev);
54143f49d684SMustafa Ismail
54153f49d684SMustafa Ismail if (irdma_wait_pe_ready(dev))
54162c4b14eaSShiraz Saleem return -ETIMEDOUT;
54173f49d684SMustafa Ismail
54183f49d684SMustafa Ismail val = readl(dev->hw_regs[IRDMA_GLPCI_LBARCTRL]);
54193f49d684SMustafa Ismail db_size = (u8)FIELD_GET(IRDMA_GLPCI_LBARCTRL_PE_DB_SIZE, val);
54203f49d684SMustafa Ismail if (db_size != IRDMA_PE_DB_SIZE_4M && db_size != IRDMA_PE_DB_SIZE_8M) {
54213f49d684SMustafa Ismail ibdev_dbg(to_ibdev(dev),
54223f49d684SMustafa Ismail "DEV: RDMA PE doorbell is not enabled in CSR val 0x%x db_size=%d\n",
54233f49d684SMustafa Ismail val, db_size);
54242c4b14eaSShiraz Saleem return -ENODEV;
54253f49d684SMustafa Ismail }
54263f49d684SMustafa Ismail dev->db_addr = dev->hw->hw_addr + (uintptr_t)dev->hw_regs[IRDMA_DB_ADDR_OFFSET];
54273f49d684SMustafa Ismail
54283f49d684SMustafa Ismail return ret_code;
54293f49d684SMustafa Ismail }
54303f49d684SMustafa Ismail
54313f49d684SMustafa Ismail /**
54325a711e58SKrzysztof Czurylo * irdma_stat_val - Extract HW counter value from statistics buffer
54335a711e58SKrzysztof Czurylo * @stats_val: pointer to statistics buffer
54345a711e58SKrzysztof Czurylo * @byteoff: byte offset of counter value in the buffer (8B-aligned)
54355a711e58SKrzysztof Czurylo * @bitoff: bit offset of counter value within 8B entry
54365a711e58SKrzysztof Czurylo * @bitmask: maximum counter value (e.g. 0xffffff for 24-bit counter)
54375a711e58SKrzysztof Czurylo */
irdma_stat_val(const u64 * stats_val,u16 byteoff,u8 bitoff,u64 bitmask)54385a711e58SKrzysztof Czurylo static inline u64 irdma_stat_val(const u64 *stats_val, u16 byteoff, u8 bitoff,
54395a711e58SKrzysztof Czurylo u64 bitmask)
54405a711e58SKrzysztof Czurylo {
54415a711e58SKrzysztof Czurylo u16 idx = byteoff / sizeof(*stats_val);
54425a711e58SKrzysztof Czurylo
54435a711e58SKrzysztof Czurylo return (stats_val[idx] >> bitoff) & bitmask;
54445a711e58SKrzysztof Czurylo }
54455a711e58SKrzysztof Czurylo
54465a711e58SKrzysztof Czurylo /**
54475a711e58SKrzysztof Czurylo * irdma_stat_delta - Calculate counter delta
54485a711e58SKrzysztof Czurylo * @new_val: updated counter value
54495a711e58SKrzysztof Czurylo * @old_val: last counter value
54505a711e58SKrzysztof Czurylo * @max_val: maximum counter value (e.g. 0xffffff for 24-bit counter)
54515a711e58SKrzysztof Czurylo */
irdma_stat_delta(u64 new_val,u64 old_val,u64 max_val)54525a711e58SKrzysztof Czurylo static inline u64 irdma_stat_delta(u64 new_val, u64 old_val, u64 max_val)
54535a711e58SKrzysztof Czurylo {
54545a711e58SKrzysztof Czurylo if (new_val >= old_val)
54555a711e58SKrzysztof Czurylo return new_val - old_val;
54565a711e58SKrzysztof Czurylo
54575a711e58SKrzysztof Czurylo /* roll-over case */
54585a711e58SKrzysztof Czurylo return max_val - old_val + new_val + 1;
54595a711e58SKrzysztof Czurylo }
54605a711e58SKrzysztof Czurylo
54615a711e58SKrzysztof Czurylo /**
54623f49d684SMustafa Ismail * irdma_update_stats - Update statistics
54633f49d684SMustafa Ismail * @hw_stats: hw_stats instance to update
54643f49d684SMustafa Ismail * @gather_stats: updated stat counters
54653f49d684SMustafa Ismail * @last_gather_stats: last stat counters
54665a711e58SKrzysztof Czurylo * @map: HW stat map (hw_stats => gather_stats)
54675a711e58SKrzysztof Czurylo * @max_stat_idx: number of HW stats
54683f49d684SMustafa Ismail */
irdma_update_stats(struct irdma_dev_hw_stats * hw_stats,struct irdma_gather_stats * gather_stats,struct irdma_gather_stats * last_gather_stats,const struct irdma_hw_stat_map * map,u16 max_stat_idx)54693f49d684SMustafa Ismail void irdma_update_stats(struct irdma_dev_hw_stats *hw_stats,
54703f49d684SMustafa Ismail struct irdma_gather_stats *gather_stats,
54715a711e58SKrzysztof Czurylo struct irdma_gather_stats *last_gather_stats,
54725a711e58SKrzysztof Czurylo const struct irdma_hw_stat_map *map, u16 max_stat_idx)
54733f49d684SMustafa Ismail {
54745a711e58SKrzysztof Czurylo u64 *stats_val = hw_stats->stats_val;
54755a711e58SKrzysztof Czurylo u16 i;
54763f49d684SMustafa Ismail
54775a711e58SKrzysztof Czurylo for (i = 0; i < max_stat_idx; i++) {
54785a711e58SKrzysztof Czurylo u64 new_val = irdma_stat_val(gather_stats->val, map[i].byteoff,
54795a711e58SKrzysztof Czurylo map[i].bitoff, map[i].bitmask);
54805a711e58SKrzysztof Czurylo u64 last_val = irdma_stat_val(last_gather_stats->val,
54815a711e58SKrzysztof Czurylo map[i].byteoff, map[i].bitoff,
54825a711e58SKrzysztof Czurylo map[i].bitmask);
54835a711e58SKrzysztof Czurylo
54845a711e58SKrzysztof Czurylo stats_val[i] +=
54855a711e58SKrzysztof Czurylo irdma_stat_delta(new_val, last_val, map[i].bitmask);
54865a711e58SKrzysztof Czurylo }
54875a711e58SKrzysztof Czurylo
54883f49d684SMustafa Ismail memcpy(last_gather_stats, gather_stats, sizeof(*last_gather_stats));
54893f49d684SMustafa Ismail }
5490