162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 262306a36Sopenharmony_ci/* Copyright (c) 2015 - 2021 Intel Corporation */ 362306a36Sopenharmony_ci#include <linux/etherdevice.h> 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include "osdep.h" 662306a36Sopenharmony_ci#include "hmc.h" 762306a36Sopenharmony_ci#include "defs.h" 862306a36Sopenharmony_ci#include "type.h" 962306a36Sopenharmony_ci#include "ws.h" 1062306a36Sopenharmony_ci#include "protos.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/** 1362306a36Sopenharmony_ci * irdma_get_qp_from_list - get next qp from a list 1462306a36Sopenharmony_ci * @head: Listhead of qp's 1562306a36Sopenharmony_ci * @qp: current qp 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_cistruct irdma_sc_qp *irdma_get_qp_from_list(struct list_head *head, 1862306a36Sopenharmony_ci struct irdma_sc_qp *qp) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci struct list_head *lastentry; 2162306a36Sopenharmony_ci struct list_head *entry = NULL; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci if (list_empty(head)) 2462306a36Sopenharmony_ci return NULL; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci if (!qp) { 2762306a36Sopenharmony_ci entry = head->next; 2862306a36Sopenharmony_ci } else { 2962306a36Sopenharmony_ci lastentry = &qp->list; 3062306a36Sopenharmony_ci entry = lastentry->next; 3162306a36Sopenharmony_ci if (entry == head) 3262306a36Sopenharmony_ci return NULL; 3362306a36Sopenharmony_ci } 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci return container_of(entry, struct irdma_sc_qp, list); 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/** 3962306a36Sopenharmony_ci * irdma_sc_suspend_resume_qps - suspend/resume all qp's on VSI 4062306a36Sopenharmony_ci * @vsi: the VSI struct pointer 4162306a36Sopenharmony_ci * @op: Set to IRDMA_OP_RESUME or IRDMA_OP_SUSPEND 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_civoid irdma_sc_suspend_resume_qps(struct irdma_sc_vsi *vsi, u8 op) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci struct irdma_sc_qp *qp = NULL; 4662306a36Sopenharmony_ci u8 i; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) { 4962306a36Sopenharmony_ci mutex_lock(&vsi->qos[i].qos_mutex); 5062306a36Sopenharmony_ci qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp); 5162306a36Sopenharmony_ci while (qp) { 5262306a36Sopenharmony_ci if (op == IRDMA_OP_RESUME) { 5362306a36Sopenharmony_ci if (!qp->dev->ws_add(vsi, i)) { 5462306a36Sopenharmony_ci qp->qs_handle = 5562306a36Sopenharmony_ci vsi->qos[qp->user_pri].qs_handle; 5662306a36Sopenharmony_ci irdma_cqp_qp_suspend_resume(qp, op); 5762306a36Sopenharmony_ci } else { 5862306a36Sopenharmony_ci irdma_cqp_qp_suspend_resume(qp, op); 5962306a36Sopenharmony_ci irdma_modify_qp_to_err(qp); 6062306a36Sopenharmony_ci } 6162306a36Sopenharmony_ci } else if (op == IRDMA_OP_SUSPEND) { 6262306a36Sopenharmony_ci /* issue cqp suspend command */ 6362306a36Sopenharmony_ci if (!irdma_cqp_qp_suspend_resume(qp, op)) 6462306a36Sopenharmony_ci atomic_inc(&vsi->qp_suspend_reqs); 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp); 6762306a36Sopenharmony_ci } 6862306a36Sopenharmony_ci mutex_unlock(&vsi->qos[i].qos_mutex); 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic void irdma_set_qos_info(struct irdma_sc_vsi *vsi, 7362306a36Sopenharmony_ci struct irdma_l2params *l2p) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci u8 i; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci vsi->qos_rel_bw = l2p->vsi_rel_bw; 7862306a36Sopenharmony_ci vsi->qos_prio_type = l2p->vsi_prio_type; 7962306a36Sopenharmony_ci vsi->dscp_mode = l2p->dscp_mode; 8062306a36Sopenharmony_ci if (l2p->dscp_mode) { 8162306a36Sopenharmony_ci memcpy(vsi->dscp_map, l2p->dscp_map, sizeof(vsi->dscp_map)); 8262306a36Sopenharmony_ci for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) 8362306a36Sopenharmony_ci l2p->up2tc[i] = i; 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) { 8662306a36Sopenharmony_ci if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) 8762306a36Sopenharmony_ci vsi->qos[i].qs_handle = l2p->qs_handle_list[i]; 8862306a36Sopenharmony_ci vsi->qos[i].traffic_class = l2p->up2tc[i]; 8962306a36Sopenharmony_ci vsi->qos[i].rel_bw = 9062306a36Sopenharmony_ci l2p->tc_info[vsi->qos[i].traffic_class].rel_bw; 9162306a36Sopenharmony_ci vsi->qos[i].prio_type = 9262306a36Sopenharmony_ci l2p->tc_info[vsi->qos[i].traffic_class].prio_type; 9362306a36Sopenharmony_ci vsi->qos[i].valid = false; 9462306a36Sopenharmony_ci } 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/** 9862306a36Sopenharmony_ci * irdma_change_l2params - given the new l2 parameters, change all qp 9962306a36Sopenharmony_ci * @vsi: RDMA VSI pointer 10062306a36Sopenharmony_ci * @l2params: New parameters from l2 10162306a36Sopenharmony_ci */ 10262306a36Sopenharmony_civoid irdma_change_l2params(struct irdma_sc_vsi *vsi, 10362306a36Sopenharmony_ci struct irdma_l2params *l2params) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci if (l2params->mtu_changed) { 10662306a36Sopenharmony_ci vsi->mtu = l2params->mtu; 10762306a36Sopenharmony_ci if (vsi->ieq) 10862306a36Sopenharmony_ci irdma_reinitialize_ieq(vsi); 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci if (!l2params->tc_changed) 11262306a36Sopenharmony_ci return; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci vsi->tc_change_pending = false; 11562306a36Sopenharmony_ci irdma_set_qos_info(vsi, l2params); 11662306a36Sopenharmony_ci irdma_sc_suspend_resume_qps(vsi, IRDMA_OP_RESUME); 11762306a36Sopenharmony_ci} 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/** 12062306a36Sopenharmony_ci * irdma_qp_rem_qos - remove qp from qos lists during destroy qp 12162306a36Sopenharmony_ci * @qp: qp to be removed from qos 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_civoid irdma_qp_rem_qos(struct irdma_sc_qp *qp) 12462306a36Sopenharmony_ci{ 12562306a36Sopenharmony_ci struct irdma_sc_vsi *vsi = qp->vsi; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci ibdev_dbg(to_ibdev(qp->dev), 12862306a36Sopenharmony_ci "DCB: DCB: Remove qp[%d] UP[%d] qset[%d] on_qoslist[%d]\n", 12962306a36Sopenharmony_ci qp->qp_uk.qp_id, qp->user_pri, qp->qs_handle, 13062306a36Sopenharmony_ci qp->on_qoslist); 13162306a36Sopenharmony_ci mutex_lock(&vsi->qos[qp->user_pri].qos_mutex); 13262306a36Sopenharmony_ci if (qp->on_qoslist) { 13362306a36Sopenharmony_ci qp->on_qoslist = false; 13462306a36Sopenharmony_ci list_del(&qp->list); 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci mutex_unlock(&vsi->qos[qp->user_pri].qos_mutex); 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci/** 14062306a36Sopenharmony_ci * irdma_qp_add_qos - called during setctx for qp to be added to qos 14162306a36Sopenharmony_ci * @qp: qp to be added to qos 14262306a36Sopenharmony_ci */ 14362306a36Sopenharmony_civoid irdma_qp_add_qos(struct irdma_sc_qp *qp) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci struct irdma_sc_vsi *vsi = qp->vsi; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci ibdev_dbg(to_ibdev(qp->dev), 14862306a36Sopenharmony_ci "DCB: DCB: Add qp[%d] UP[%d] qset[%d] on_qoslist[%d]\n", 14962306a36Sopenharmony_ci qp->qp_uk.qp_id, qp->user_pri, qp->qs_handle, 15062306a36Sopenharmony_ci qp->on_qoslist); 15162306a36Sopenharmony_ci mutex_lock(&vsi->qos[qp->user_pri].qos_mutex); 15262306a36Sopenharmony_ci if (!qp->on_qoslist) { 15362306a36Sopenharmony_ci list_add(&qp->list, &vsi->qos[qp->user_pri].qplist); 15462306a36Sopenharmony_ci qp->on_qoslist = true; 15562306a36Sopenharmony_ci qp->qs_handle = vsi->qos[qp->user_pri].qs_handle; 15662306a36Sopenharmony_ci } 15762306a36Sopenharmony_ci mutex_unlock(&vsi->qos[qp->user_pri].qos_mutex); 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci/** 16162306a36Sopenharmony_ci * irdma_sc_pd_init - initialize sc pd struct 16262306a36Sopenharmony_ci * @dev: sc device struct 16362306a36Sopenharmony_ci * @pd: sc pd ptr 16462306a36Sopenharmony_ci * @pd_id: pd_id for allocated pd 16562306a36Sopenharmony_ci * @abi_ver: User/Kernel ABI version 16662306a36Sopenharmony_ci */ 16762306a36Sopenharmony_civoid irdma_sc_pd_init(struct irdma_sc_dev *dev, struct irdma_sc_pd *pd, u32 pd_id, 16862306a36Sopenharmony_ci int abi_ver) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci pd->pd_id = pd_id; 17162306a36Sopenharmony_ci pd->abi_ver = abi_ver; 17262306a36Sopenharmony_ci pd->dev = dev; 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci/** 17662306a36Sopenharmony_ci * irdma_sc_add_arp_cache_entry - cqp wqe add arp cache entry 17762306a36Sopenharmony_ci * @cqp: struct for cqp hw 17862306a36Sopenharmony_ci * @info: arp entry information 17962306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 18062306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 18162306a36Sopenharmony_ci */ 18262306a36Sopenharmony_cistatic int irdma_sc_add_arp_cache_entry(struct irdma_sc_cqp *cqp, 18362306a36Sopenharmony_ci struct irdma_add_arp_cache_entry_info *info, 18462306a36Sopenharmony_ci u64 scratch, bool post_sq) 18562306a36Sopenharmony_ci{ 18662306a36Sopenharmony_ci __le64 *wqe; 18762306a36Sopenharmony_ci u64 hdr; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 19062306a36Sopenharmony_ci if (!wqe) 19162306a36Sopenharmony_ci return -ENOMEM; 19262306a36Sopenharmony_ci set_64bit_val(wqe, 8, info->reach_max); 19362306a36Sopenharmony_ci set_64bit_val(wqe, 16, ether_addr_to_u64(info->mac_addr)); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci hdr = info->arp_index | 19662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MANAGE_ARP) | 19762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_MAT_PERMANENT, (info->permanent ? 1 : 0)) | 19862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_MAT_ENTRYVALID, 1) | 19962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 20062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci print_hex_dump_debug("WQE: ARP_CACHE_ENTRY WQE", DUMP_PREFIX_OFFSET, 20562306a36Sopenharmony_ci 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 20662306a36Sopenharmony_ci if (post_sq) 20762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci return 0; 21062306a36Sopenharmony_ci} 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/** 21362306a36Sopenharmony_ci * irdma_sc_del_arp_cache_entry - dele arp cache entry 21462306a36Sopenharmony_ci * @cqp: struct for cqp hw 21562306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 21662306a36Sopenharmony_ci * @arp_index: arp index to delete arp entry 21762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 21862306a36Sopenharmony_ci */ 21962306a36Sopenharmony_cistatic int irdma_sc_del_arp_cache_entry(struct irdma_sc_cqp *cqp, u64 scratch, 22062306a36Sopenharmony_ci u16 arp_index, bool post_sq) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci __le64 *wqe; 22362306a36Sopenharmony_ci u64 hdr; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 22662306a36Sopenharmony_ci if (!wqe) 22762306a36Sopenharmony_ci return -ENOMEM; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci hdr = arp_index | 23062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MANAGE_ARP) | 23162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 23262306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci print_hex_dump_debug("WQE: ARP_CACHE_DEL_ENTRY WQE", 23762306a36Sopenharmony_ci DUMP_PREFIX_OFFSET, 16, 8, wqe, 23862306a36Sopenharmony_ci IRDMA_CQP_WQE_SIZE * 8, false); 23962306a36Sopenharmony_ci if (post_sq) 24062306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci return 0; 24362306a36Sopenharmony_ci} 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci/** 24662306a36Sopenharmony_ci * irdma_sc_manage_apbvt_entry - for adding and deleting apbvt entries 24762306a36Sopenharmony_ci * @cqp: struct for cqp hw 24862306a36Sopenharmony_ci * @info: info for apbvt entry to add or delete 24962306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 25062306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_cistatic int irdma_sc_manage_apbvt_entry(struct irdma_sc_cqp *cqp, 25362306a36Sopenharmony_ci struct irdma_apbvt_info *info, 25462306a36Sopenharmony_ci u64 scratch, bool post_sq) 25562306a36Sopenharmony_ci{ 25662306a36Sopenharmony_ci __le64 *wqe; 25762306a36Sopenharmony_ci u64 hdr; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 26062306a36Sopenharmony_ci if (!wqe) 26162306a36Sopenharmony_ci return -ENOMEM; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci set_64bit_val(wqe, 16, info->port); 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MANAGE_APBVT) | 26662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_MAPT_ADDPORT, info->add) | 26762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 26862306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci print_hex_dump_debug("WQE: MANAGE_APBVT WQE", DUMP_PREFIX_OFFSET, 16, 27362306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 27462306a36Sopenharmony_ci if (post_sq) 27562306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci return 0; 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci/** 28162306a36Sopenharmony_ci * irdma_sc_manage_qhash_table_entry - manage quad hash entries 28262306a36Sopenharmony_ci * @cqp: struct for cqp hw 28362306a36Sopenharmony_ci * @info: info for quad hash to manage 28462306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 28562306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 28662306a36Sopenharmony_ci * 28762306a36Sopenharmony_ci * This is called before connection establishment is started. 28862306a36Sopenharmony_ci * For passive connections, when listener is created, it will 28962306a36Sopenharmony_ci * call with entry type of IRDMA_QHASH_TYPE_TCP_SYN with local 29062306a36Sopenharmony_ci * ip address and tcp port. When SYN is received (passive 29162306a36Sopenharmony_ci * connections) or sent (active connections), this routine is 29262306a36Sopenharmony_ci * called with entry type of IRDMA_QHASH_TYPE_TCP_ESTABLISHED 29362306a36Sopenharmony_ci * and quad is passed in info. 29462306a36Sopenharmony_ci * 29562306a36Sopenharmony_ci * When iwarp connection is done and its state moves to RTS, the 29662306a36Sopenharmony_ci * quad hash entry in the hardware will point to iwarp's qp 29762306a36Sopenharmony_ci * number and requires no calls from the driver. 29862306a36Sopenharmony_ci */ 29962306a36Sopenharmony_cistatic int 30062306a36Sopenharmony_ciirdma_sc_manage_qhash_table_entry(struct irdma_sc_cqp *cqp, 30162306a36Sopenharmony_ci struct irdma_qhash_table_info *info, 30262306a36Sopenharmony_ci u64 scratch, bool post_sq) 30362306a36Sopenharmony_ci{ 30462306a36Sopenharmony_ci __le64 *wqe; 30562306a36Sopenharmony_ci u64 qw1 = 0; 30662306a36Sopenharmony_ci u64 qw2 = 0; 30762306a36Sopenharmony_ci u64 temp; 30862306a36Sopenharmony_ci struct irdma_sc_vsi *vsi = info->vsi; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 31162306a36Sopenharmony_ci if (!wqe) 31262306a36Sopenharmony_ci return -ENOMEM; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci set_64bit_val(wqe, 0, ether_addr_to_u64(info->mac_addr)); 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci qw1 = FIELD_PREP(IRDMA_CQPSQ_QHASH_QPN, info->qp_num) | 31762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_DEST_PORT, info->dest_port); 31862306a36Sopenharmony_ci if (info->ipv4_valid) { 31962306a36Sopenharmony_ci set_64bit_val(wqe, 48, 32062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR3, info->dest_ip[0])); 32162306a36Sopenharmony_ci } else { 32262306a36Sopenharmony_ci set_64bit_val(wqe, 56, 32362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR0, info->dest_ip[0]) | 32462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR1, info->dest_ip[1])); 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci set_64bit_val(wqe, 48, 32762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR2, info->dest_ip[2]) | 32862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR3, info->dest_ip[3])); 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci qw2 = FIELD_PREP(IRDMA_CQPSQ_QHASH_QS_HANDLE, 33162306a36Sopenharmony_ci vsi->qos[info->user_pri].qs_handle); 33262306a36Sopenharmony_ci if (info->vlan_valid) 33362306a36Sopenharmony_ci qw2 |= FIELD_PREP(IRDMA_CQPSQ_QHASH_VLANID, info->vlan_id); 33462306a36Sopenharmony_ci set_64bit_val(wqe, 16, qw2); 33562306a36Sopenharmony_ci if (info->entry_type == IRDMA_QHASH_TYPE_TCP_ESTABLISHED) { 33662306a36Sopenharmony_ci qw1 |= FIELD_PREP(IRDMA_CQPSQ_QHASH_SRC_PORT, info->src_port); 33762306a36Sopenharmony_ci if (!info->ipv4_valid) { 33862306a36Sopenharmony_ci set_64bit_val(wqe, 40, 33962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR0, info->src_ip[0]) | 34062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR1, info->src_ip[1])); 34162306a36Sopenharmony_ci set_64bit_val(wqe, 32, 34262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR2, info->src_ip[2]) | 34362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR3, info->src_ip[3])); 34462306a36Sopenharmony_ci } else { 34562306a36Sopenharmony_ci set_64bit_val(wqe, 32, 34662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ADDR3, info->src_ip[0])); 34762306a36Sopenharmony_ci } 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci set_64bit_val(wqe, 8, qw1); 35162306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPSQ_QHASH_WQEVALID, cqp->polarity) | 35262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_OPCODE, 35362306a36Sopenharmony_ci IRDMA_CQP_OP_MANAGE_QUAD_HASH_TABLE_ENTRY) | 35462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_MANAGE, info->manage) | 35562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_IPV4VALID, info->ipv4_valid) | 35662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_VLANVALID, info->vlan_valid) | 35762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QHASH_ENTRYTYPE, info->entry_type); 35862306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci set_64bit_val(wqe, 24, temp); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci print_hex_dump_debug("WQE: MANAGE_QHASH WQE", DUMP_PREFIX_OFFSET, 16, 36362306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 36462306a36Sopenharmony_ci if (post_sq) 36562306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci return 0; 36862306a36Sopenharmony_ci} 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci/** 37162306a36Sopenharmony_ci * irdma_sc_qp_init - initialize qp 37262306a36Sopenharmony_ci * @qp: sc qp 37362306a36Sopenharmony_ci * @info: initialization qp info 37462306a36Sopenharmony_ci */ 37562306a36Sopenharmony_ciint irdma_sc_qp_init(struct irdma_sc_qp *qp, struct irdma_qp_init_info *info) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci int ret_code; 37862306a36Sopenharmony_ci u32 pble_obj_cnt; 37962306a36Sopenharmony_ci u16 wqe_size; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci if (info->qp_uk_init_info.max_sq_frag_cnt > 38262306a36Sopenharmony_ci info->pd->dev->hw_attrs.uk_attrs.max_hw_wq_frags || 38362306a36Sopenharmony_ci info->qp_uk_init_info.max_rq_frag_cnt > 38462306a36Sopenharmony_ci info->pd->dev->hw_attrs.uk_attrs.max_hw_wq_frags) 38562306a36Sopenharmony_ci return -EINVAL; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci qp->dev = info->pd->dev; 38862306a36Sopenharmony_ci qp->vsi = info->vsi; 38962306a36Sopenharmony_ci qp->ieq_qp = info->vsi->exception_lan_q; 39062306a36Sopenharmony_ci qp->sq_pa = info->sq_pa; 39162306a36Sopenharmony_ci qp->rq_pa = info->rq_pa; 39262306a36Sopenharmony_ci qp->hw_host_ctx_pa = info->host_ctx_pa; 39362306a36Sopenharmony_ci qp->q2_pa = info->q2_pa; 39462306a36Sopenharmony_ci qp->shadow_area_pa = info->shadow_area_pa; 39562306a36Sopenharmony_ci qp->q2_buf = info->q2; 39662306a36Sopenharmony_ci qp->pd = info->pd; 39762306a36Sopenharmony_ci qp->hw_host_ctx = info->host_ctx; 39862306a36Sopenharmony_ci info->qp_uk_init_info.wqe_alloc_db = qp->pd->dev->wqe_alloc_db; 39962306a36Sopenharmony_ci ret_code = irdma_uk_qp_init(&qp->qp_uk, &info->qp_uk_init_info); 40062306a36Sopenharmony_ci if (ret_code) 40162306a36Sopenharmony_ci return ret_code; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci qp->virtual_map = info->virtual_map; 40462306a36Sopenharmony_ci pble_obj_cnt = info->pd->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci if ((info->virtual_map && info->sq_pa >= pble_obj_cnt) || 40762306a36Sopenharmony_ci (info->virtual_map && info->rq_pa >= pble_obj_cnt)) 40862306a36Sopenharmony_ci return -EINVAL; 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci qp->llp_stream_handle = (void *)(-1); 41162306a36Sopenharmony_ci qp->hw_sq_size = irdma_get_encoded_wqe_size(qp->qp_uk.sq_ring.size, 41262306a36Sopenharmony_ci IRDMA_QUEUE_TYPE_SQ_RQ); 41362306a36Sopenharmony_ci ibdev_dbg(to_ibdev(qp->dev), 41462306a36Sopenharmony_ci "WQE: hw_sq_size[%04d] sq_ring.size[%04d]\n", 41562306a36Sopenharmony_ci qp->hw_sq_size, qp->qp_uk.sq_ring.size); 41662306a36Sopenharmony_ci if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1 && qp->pd->abi_ver > 4) 41762306a36Sopenharmony_ci wqe_size = IRDMA_WQE_SIZE_128; 41862306a36Sopenharmony_ci else 41962306a36Sopenharmony_ci ret_code = irdma_fragcnt_to_wqesize_rq(qp->qp_uk.max_rq_frag_cnt, 42062306a36Sopenharmony_ci &wqe_size); 42162306a36Sopenharmony_ci if (ret_code) 42262306a36Sopenharmony_ci return ret_code; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci qp->hw_rq_size = irdma_get_encoded_wqe_size(qp->qp_uk.rq_size * 42562306a36Sopenharmony_ci (wqe_size / IRDMA_QP_WQE_MIN_SIZE), IRDMA_QUEUE_TYPE_SQ_RQ); 42662306a36Sopenharmony_ci ibdev_dbg(to_ibdev(qp->dev), 42762306a36Sopenharmony_ci "WQE: hw_rq_size[%04d] qp_uk.rq_size[%04d] wqe_size[%04d]\n", 42862306a36Sopenharmony_ci qp->hw_rq_size, qp->qp_uk.rq_size, wqe_size); 42962306a36Sopenharmony_ci qp->sq_tph_val = info->sq_tph_val; 43062306a36Sopenharmony_ci qp->rq_tph_val = info->rq_tph_val; 43162306a36Sopenharmony_ci qp->sq_tph_en = info->sq_tph_en; 43262306a36Sopenharmony_ci qp->rq_tph_en = info->rq_tph_en; 43362306a36Sopenharmony_ci qp->rcv_tph_en = info->rcv_tph_en; 43462306a36Sopenharmony_ci qp->xmit_tph_en = info->xmit_tph_en; 43562306a36Sopenharmony_ci qp->qp_uk.first_sq_wq = info->qp_uk_init_info.first_sq_wq; 43662306a36Sopenharmony_ci qp->qs_handle = qp->vsi->qos[qp->user_pri].qs_handle; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci return 0; 43962306a36Sopenharmony_ci} 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci/** 44262306a36Sopenharmony_ci * irdma_sc_qp_create - create qp 44362306a36Sopenharmony_ci * @qp: sc qp 44462306a36Sopenharmony_ci * @info: qp create info 44562306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 44662306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 44762306a36Sopenharmony_ci */ 44862306a36Sopenharmony_ciint irdma_sc_qp_create(struct irdma_sc_qp *qp, struct irdma_create_qp_info *info, 44962306a36Sopenharmony_ci u64 scratch, bool post_sq) 45062306a36Sopenharmony_ci{ 45162306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 45262306a36Sopenharmony_ci __le64 *wqe; 45362306a36Sopenharmony_ci u64 hdr; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci cqp = qp->dev->cqp; 45662306a36Sopenharmony_ci if (qp->qp_uk.qp_id < cqp->dev->hw_attrs.min_hw_qp_id || 45762306a36Sopenharmony_ci qp->qp_uk.qp_id >= cqp->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt) 45862306a36Sopenharmony_ci return -EINVAL; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 46162306a36Sopenharmony_ci if (!wqe) 46262306a36Sopenharmony_ci return -ENOMEM; 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci set_64bit_val(wqe, 16, qp->hw_host_ctx_pa); 46562306a36Sopenharmony_ci set_64bit_val(wqe, 40, qp->shadow_area_pa); 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci hdr = qp->qp_uk.qp_id | 46862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_QP) | 46962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_ORDVALID, (info->ord_valid ? 1 : 0)) | 47062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_TOECTXVALID, info->tcp_ctx_valid) | 47162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_MACVALID, info->mac_valid) | 47262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_QPTYPE, qp->qp_uk.qp_type) | 47362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_VQ, qp->virtual_map) | 47462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_FORCELOOPBACK, info->force_lpb) | 47562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_CQNUMVALID, info->cq_num_valid) | 47662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_ARPTABIDXVALID, 47762306a36Sopenharmony_ci info->arp_cache_idx_valid) | 47862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_NEXTIWSTATE, info->next_iwarp_state) | 47962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 48062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci print_hex_dump_debug("WQE: QP_CREATE WQE", DUMP_PREFIX_OFFSET, 16, 8, 48562306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 48662306a36Sopenharmony_ci if (post_sq) 48762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci return 0; 49062306a36Sopenharmony_ci} 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci/** 49362306a36Sopenharmony_ci * irdma_sc_qp_modify - modify qp cqp wqe 49462306a36Sopenharmony_ci * @qp: sc qp 49562306a36Sopenharmony_ci * @info: modify qp info 49662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 49762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 49862306a36Sopenharmony_ci */ 49962306a36Sopenharmony_ciint irdma_sc_qp_modify(struct irdma_sc_qp *qp, struct irdma_modify_qp_info *info, 50062306a36Sopenharmony_ci u64 scratch, bool post_sq) 50162306a36Sopenharmony_ci{ 50262306a36Sopenharmony_ci __le64 *wqe; 50362306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 50462306a36Sopenharmony_ci u64 hdr; 50562306a36Sopenharmony_ci u8 term_actions = 0; 50662306a36Sopenharmony_ci u8 term_len = 0; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci cqp = qp->dev->cqp; 50962306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 51062306a36Sopenharmony_ci if (!wqe) 51162306a36Sopenharmony_ci return -ENOMEM; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci if (info->next_iwarp_state == IRDMA_QP_STATE_TERMINATE) { 51462306a36Sopenharmony_ci if (info->dont_send_fin) 51562306a36Sopenharmony_ci term_actions += IRDMAQP_TERM_SEND_TERM_ONLY; 51662306a36Sopenharmony_ci if (info->dont_send_term) 51762306a36Sopenharmony_ci term_actions += IRDMAQP_TERM_SEND_FIN_ONLY; 51862306a36Sopenharmony_ci if (term_actions == IRDMAQP_TERM_SEND_TERM_AND_FIN || 51962306a36Sopenharmony_ci term_actions == IRDMAQP_TERM_SEND_TERM_ONLY) 52062306a36Sopenharmony_ci term_len = info->termlen; 52162306a36Sopenharmony_ci } 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci set_64bit_val(wqe, 8, 52462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_NEWMSS, info->new_mss) | 52562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_TERMLEN, term_len)); 52662306a36Sopenharmony_ci set_64bit_val(wqe, 16, qp->hw_host_ctx_pa); 52762306a36Sopenharmony_ci set_64bit_val(wqe, 40, qp->shadow_area_pa); 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci hdr = qp->qp_uk.qp_id | 53062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MODIFY_QP) | 53162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_ORDVALID, info->ord_valid) | 53262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_TOECTXVALID, info->tcp_ctx_valid) | 53362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_CACHEDVARVALID, 53462306a36Sopenharmony_ci info->cached_var_valid) | 53562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_VQ, qp->virtual_map) | 53662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_FORCELOOPBACK, info->force_lpb) | 53762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_CQNUMVALID, info->cq_num_valid) | 53862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_MACVALID, info->mac_valid) | 53962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_QPTYPE, qp->qp_uk.qp_type) | 54062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_MSSCHANGE, info->mss_change) | 54162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_REMOVEHASHENTRY, 54262306a36Sopenharmony_ci info->remove_hash_idx) | 54362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_TERMACT, term_actions) | 54462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_RESETCON, info->reset_tcp_conn) | 54562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_ARPTABIDXVALID, 54662306a36Sopenharmony_ci info->arp_cache_idx_valid) | 54762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_NEXTIWSTATE, info->next_iwarp_state) | 54862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 54962306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci print_hex_dump_debug("WQE: QP_MODIFY WQE", DUMP_PREFIX_OFFSET, 16, 8, 55462306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 55562306a36Sopenharmony_ci if (post_sq) 55662306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci return 0; 55962306a36Sopenharmony_ci} 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci/** 56262306a36Sopenharmony_ci * irdma_sc_qp_destroy - cqp destroy qp 56362306a36Sopenharmony_ci * @qp: sc qp 56462306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 56562306a36Sopenharmony_ci * @remove_hash_idx: flag if to remove hash idx 56662306a36Sopenharmony_ci * @ignore_mw_bnd: memory window bind flag 56762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 56862306a36Sopenharmony_ci */ 56962306a36Sopenharmony_ciint irdma_sc_qp_destroy(struct irdma_sc_qp *qp, u64 scratch, 57062306a36Sopenharmony_ci bool remove_hash_idx, bool ignore_mw_bnd, bool post_sq) 57162306a36Sopenharmony_ci{ 57262306a36Sopenharmony_ci __le64 *wqe; 57362306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 57462306a36Sopenharmony_ci u64 hdr; 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci cqp = qp->dev->cqp; 57762306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 57862306a36Sopenharmony_ci if (!wqe) 57962306a36Sopenharmony_ci return -ENOMEM; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci set_64bit_val(wqe, 16, qp->hw_host_ctx_pa); 58262306a36Sopenharmony_ci set_64bit_val(wqe, 40, qp->shadow_area_pa); 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci hdr = qp->qp_uk.qp_id | 58562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_QP) | 58662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_QPTYPE, qp->qp_uk.qp_type) | 58762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_IGNOREMWBOUND, ignore_mw_bnd) | 58862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QP_REMOVEHASHENTRY, remove_hash_idx) | 58962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 59062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci print_hex_dump_debug("WQE: QP_DESTROY WQE", DUMP_PREFIX_OFFSET, 16, 8, 59562306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 59662306a36Sopenharmony_ci if (post_sq) 59762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci return 0; 60062306a36Sopenharmony_ci} 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci/** 60362306a36Sopenharmony_ci * irdma_sc_get_encoded_ird_size - 60462306a36Sopenharmony_ci * @ird_size: IRD size 60562306a36Sopenharmony_ci * The ird from the connection is rounded to a supported HW setting and then encoded 60662306a36Sopenharmony_ci * for ird_size field of qp_ctx. Consumers are expected to provide valid ird size based 60762306a36Sopenharmony_ci * on hardware attributes. IRD size defaults to a value of 4 in case of invalid input 60862306a36Sopenharmony_ci */ 60962306a36Sopenharmony_cistatic u8 irdma_sc_get_encoded_ird_size(u16 ird_size) 61062306a36Sopenharmony_ci{ 61162306a36Sopenharmony_ci switch (ird_size ? 61262306a36Sopenharmony_ci roundup_pow_of_two(2 * ird_size) : 4) { 61362306a36Sopenharmony_ci case 256: 61462306a36Sopenharmony_ci return IRDMA_IRD_HW_SIZE_256; 61562306a36Sopenharmony_ci case 128: 61662306a36Sopenharmony_ci return IRDMA_IRD_HW_SIZE_128; 61762306a36Sopenharmony_ci case 64: 61862306a36Sopenharmony_ci case 32: 61962306a36Sopenharmony_ci return IRDMA_IRD_HW_SIZE_64; 62062306a36Sopenharmony_ci case 16: 62162306a36Sopenharmony_ci case 8: 62262306a36Sopenharmony_ci return IRDMA_IRD_HW_SIZE_16; 62362306a36Sopenharmony_ci case 4: 62462306a36Sopenharmony_ci default: 62562306a36Sopenharmony_ci break; 62662306a36Sopenharmony_ci } 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci return IRDMA_IRD_HW_SIZE_4; 62962306a36Sopenharmony_ci} 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci/** 63262306a36Sopenharmony_ci * irdma_sc_qp_setctx_roce - set qp's context 63362306a36Sopenharmony_ci * @qp: sc qp 63462306a36Sopenharmony_ci * @qp_ctx: context ptr 63562306a36Sopenharmony_ci * @info: ctx info 63662306a36Sopenharmony_ci */ 63762306a36Sopenharmony_civoid irdma_sc_qp_setctx_roce(struct irdma_sc_qp *qp, __le64 *qp_ctx, 63862306a36Sopenharmony_ci struct irdma_qp_host_ctx_info *info) 63962306a36Sopenharmony_ci{ 64062306a36Sopenharmony_ci struct irdma_roce_offload_info *roce_info; 64162306a36Sopenharmony_ci struct irdma_udp_offload_info *udp; 64262306a36Sopenharmony_ci u8 push_mode_en; 64362306a36Sopenharmony_ci u32 push_idx; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci roce_info = info->roce_info; 64662306a36Sopenharmony_ci udp = info->udp_info; 64762306a36Sopenharmony_ci qp->user_pri = info->user_pri; 64862306a36Sopenharmony_ci if (qp->push_idx == IRDMA_INVALID_PUSH_PAGE_INDEX) { 64962306a36Sopenharmony_ci push_mode_en = 0; 65062306a36Sopenharmony_ci push_idx = 0; 65162306a36Sopenharmony_ci } else { 65262306a36Sopenharmony_ci push_mode_en = 1; 65362306a36Sopenharmony_ci push_idx = qp->push_idx; 65462306a36Sopenharmony_ci } 65562306a36Sopenharmony_ci set_64bit_val(qp_ctx, 0, 65662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RQWQESIZE, qp->qp_uk.rq_wqe_size) | 65762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVTPHEN, qp->rcv_tph_en) | 65862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_XMITTPHEN, qp->xmit_tph_en) | 65962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RQTPHEN, qp->rq_tph_en) | 66062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SQTPHEN, qp->sq_tph_en) | 66162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PPIDX, push_idx) | 66262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PMENA, push_mode_en) | 66362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PDIDXHI, roce_info->pd_id >> 16) | 66462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DC_TCP_EN, roce_info->dctcp_en) | 66562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ERR_RQ_IDX_VALID, roce_info->err_rq_idx_valid) | 66662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ISQP1, roce_info->is_qp1) | 66762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ROCE_TVER, roce_info->roce_tver) | 66862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_IPV4, udp->ipv4) | 66962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_INSERTVLANTAG, udp->insert_vlan_tag)); 67062306a36Sopenharmony_ci set_64bit_val(qp_ctx, 8, qp->sq_pa); 67162306a36Sopenharmony_ci set_64bit_val(qp_ctx, 16, qp->rq_pa); 67262306a36Sopenharmony_ci if ((roce_info->dcqcn_en || roce_info->dctcp_en) && 67362306a36Sopenharmony_ci !(udp->tos & 0x03)) 67462306a36Sopenharmony_ci udp->tos |= ECN_CODE_PT_VAL; 67562306a36Sopenharmony_ci set_64bit_val(qp_ctx, 24, 67662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RQSIZE, qp->hw_rq_size) | 67762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SQSIZE, qp->hw_sq_size) | 67862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TTL, udp->ttl) | FIELD_PREP(IRDMAQPC_TOS, udp->tos) | 67962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SRCPORTNUM, udp->src_port) | 68062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTPORTNUM, udp->dst_port)); 68162306a36Sopenharmony_ci set_64bit_val(qp_ctx, 32, 68262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTIPADDR2, udp->dest_ip_addr[2]) | 68362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTIPADDR3, udp->dest_ip_addr[3])); 68462306a36Sopenharmony_ci set_64bit_val(qp_ctx, 40, 68562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTIPADDR0, udp->dest_ip_addr[0]) | 68662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTIPADDR1, udp->dest_ip_addr[1])); 68762306a36Sopenharmony_ci set_64bit_val(qp_ctx, 48, 68862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDMSS, udp->snd_mss) | 68962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_VLANTAG, udp->vlan_tag) | 69062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ARPIDX, udp->arp_idx)); 69162306a36Sopenharmony_ci set_64bit_val(qp_ctx, 56, 69262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PKEY, roce_info->p_key) | 69362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PDIDX, roce_info->pd_id) | 69462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ACKCREDITS, roce_info->ack_credits) | 69562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_FLOWLABEL, udp->flow_label)); 69662306a36Sopenharmony_ci set_64bit_val(qp_ctx, 64, 69762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_QKEY, roce_info->qkey) | 69862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTQP, roce_info->dest_qp)); 69962306a36Sopenharmony_ci set_64bit_val(qp_ctx, 80, 70062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PSNNXT, udp->psn_nxt) | 70162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LSN, udp->lsn)); 70262306a36Sopenharmony_ci set_64bit_val(qp_ctx, 88, 70362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_EPSN, udp->epsn)); 70462306a36Sopenharmony_ci set_64bit_val(qp_ctx, 96, 70562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PSNMAX, udp->psn_max) | 70662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PSNUNA, udp->psn_una)); 70762306a36Sopenharmony_ci set_64bit_val(qp_ctx, 112, 70862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_CWNDROCE, udp->cwnd)); 70962306a36Sopenharmony_ci set_64bit_val(qp_ctx, 128, 71062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ERR_RQ_IDX, roce_info->err_rq_idx) | 71162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RNRNAK_THRESH, udp->rnr_nak_thresh) | 71262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_REXMIT_THRESH, udp->rexmit_thresh) | 71362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RTOMIN, roce_info->rtomin)); 71462306a36Sopenharmony_ci set_64bit_val(qp_ctx, 136, 71562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TXCQNUM, info->send_cq_num) | 71662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RXCQNUM, info->rcv_cq_num)); 71762306a36Sopenharmony_ci set_64bit_val(qp_ctx, 144, 71862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_STAT_INDEX, info->stats_idx)); 71962306a36Sopenharmony_ci set_64bit_val(qp_ctx, 152, ether_addr_to_u64(roce_info->mac_addr) << 16); 72062306a36Sopenharmony_ci set_64bit_val(qp_ctx, 160, 72162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ORDSIZE, roce_info->ord_size) | 72262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_IRDSIZE, irdma_sc_get_encoded_ird_size(roce_info->ird_size)) | 72362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_WRRDRSPOK, roce_info->wr_rdresp_en) | 72462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RDOK, roce_info->rd_en) | 72562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_USESTATSINSTANCE, info->stats_idx_valid) | 72662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_BINDEN, roce_info->bind_en) | 72762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_FASTREGEN, roce_info->fast_reg_en) | 72862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DCQCNENABLE, roce_info->dcqcn_en) | 72962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVNOICRC, roce_info->rcv_no_icrc) | 73062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_FW_CC_ENABLE, roce_info->fw_cc_enable) | 73162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_UDPRIVCQENABLE, roce_info->udprivcq_en) | 73262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PRIVEN, roce_info->priv_mode_en) | 73362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TIMELYENABLE, roce_info->timely_en)); 73462306a36Sopenharmony_ci set_64bit_val(qp_ctx, 168, 73562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_QPCOMPCTX, info->qp_compl_ctx)); 73662306a36Sopenharmony_ci set_64bit_val(qp_ctx, 176, 73762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SQTPHVAL, qp->sq_tph_val) | 73862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RQTPHVAL, qp->rq_tph_val) | 73962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_QSHANDLE, qp->qs_handle)); 74062306a36Sopenharmony_ci set_64bit_val(qp_ctx, 184, 74162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LOCAL_IPADDR3, udp->local_ipaddr[3]) | 74262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LOCAL_IPADDR2, udp->local_ipaddr[2])); 74362306a36Sopenharmony_ci set_64bit_val(qp_ctx, 192, 74462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LOCAL_IPADDR1, udp->local_ipaddr[1]) | 74562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LOCAL_IPADDR0, udp->local_ipaddr[0])); 74662306a36Sopenharmony_ci set_64bit_val(qp_ctx, 200, 74762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_THIGH, roce_info->t_high) | 74862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TLOW, roce_info->t_low)); 74962306a36Sopenharmony_ci set_64bit_val(qp_ctx, 208, 75062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_REMENDPOINTIDX, info->rem_endpoint_idx)); 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_ci print_hex_dump_debug("WQE: QP_HOST CTX WQE", DUMP_PREFIX_OFFSET, 16, 75362306a36Sopenharmony_ci 8, qp_ctx, IRDMA_QP_CTX_SIZE, false); 75462306a36Sopenharmony_ci} 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci/* irdma_sc_alloc_local_mac_entry - allocate a mac entry 75762306a36Sopenharmony_ci * @cqp: struct for cqp hw 75862306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 75962306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 76062306a36Sopenharmony_ci */ 76162306a36Sopenharmony_cistatic int irdma_sc_alloc_local_mac_entry(struct irdma_sc_cqp *cqp, u64 scratch, 76262306a36Sopenharmony_ci bool post_sq) 76362306a36Sopenharmony_ci{ 76462306a36Sopenharmony_ci __le64 *wqe; 76562306a36Sopenharmony_ci u64 hdr; 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 76862306a36Sopenharmony_ci if (!wqe) 76962306a36Sopenharmony_ci return -ENOMEM; 77062306a36Sopenharmony_ci 77162306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, 77262306a36Sopenharmony_ci IRDMA_CQP_OP_ALLOCATE_LOC_MAC_TABLE_ENTRY) | 77362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci print_hex_dump_debug("WQE: ALLOCATE_LOCAL_MAC WQE", 78062306a36Sopenharmony_ci DUMP_PREFIX_OFFSET, 16, 8, wqe, 78162306a36Sopenharmony_ci IRDMA_CQP_WQE_SIZE * 8, false); 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_ci if (post_sq) 78462306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 78562306a36Sopenharmony_ci return 0; 78662306a36Sopenharmony_ci} 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci/** 78962306a36Sopenharmony_ci * irdma_sc_add_local_mac_entry - add mac enry 79062306a36Sopenharmony_ci * @cqp: struct for cqp hw 79162306a36Sopenharmony_ci * @info:mac addr info 79262306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 79362306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 79462306a36Sopenharmony_ci */ 79562306a36Sopenharmony_cistatic int irdma_sc_add_local_mac_entry(struct irdma_sc_cqp *cqp, 79662306a36Sopenharmony_ci struct irdma_local_mac_entry_info *info, 79762306a36Sopenharmony_ci u64 scratch, bool post_sq) 79862306a36Sopenharmony_ci{ 79962306a36Sopenharmony_ci __le64 *wqe; 80062306a36Sopenharmony_ci u64 header; 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 80362306a36Sopenharmony_ci if (!wqe) 80462306a36Sopenharmony_ci return -ENOMEM; 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci set_64bit_val(wqe, 32, ether_addr_to_u64(info->mac_addr)); 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci header = FIELD_PREP(IRDMA_CQPSQ_MLM_TABLEIDX, info->entry_idx) | 80962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, 81062306a36Sopenharmony_ci IRDMA_CQP_OP_MANAGE_LOC_MAC_TABLE) | 81162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci set_64bit_val(wqe, 24, header); 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci print_hex_dump_debug("WQE: ADD_LOCAL_MAC WQE", DUMP_PREFIX_OFFSET, 16, 81862306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_ci if (post_sq) 82162306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 82262306a36Sopenharmony_ci return 0; 82362306a36Sopenharmony_ci} 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci/** 82662306a36Sopenharmony_ci * irdma_sc_del_local_mac_entry - cqp wqe to dele local mac 82762306a36Sopenharmony_ci * @cqp: struct for cqp hw 82862306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 82962306a36Sopenharmony_ci * @entry_idx: index of mac entry 83062306a36Sopenharmony_ci * @ignore_ref_count: to force mac adde delete 83162306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 83262306a36Sopenharmony_ci */ 83362306a36Sopenharmony_cistatic int irdma_sc_del_local_mac_entry(struct irdma_sc_cqp *cqp, u64 scratch, 83462306a36Sopenharmony_ci u16 entry_idx, u8 ignore_ref_count, 83562306a36Sopenharmony_ci bool post_sq) 83662306a36Sopenharmony_ci{ 83762306a36Sopenharmony_ci __le64 *wqe; 83862306a36Sopenharmony_ci u64 header; 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 84162306a36Sopenharmony_ci if (!wqe) 84262306a36Sopenharmony_ci return -ENOMEM; 84362306a36Sopenharmony_ci header = FIELD_PREP(IRDMA_CQPSQ_MLM_TABLEIDX, entry_idx) | 84462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, 84562306a36Sopenharmony_ci IRDMA_CQP_OP_MANAGE_LOC_MAC_TABLE) | 84662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_MLM_FREEENTRY, 1) | 84762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity) | 84862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_MLM_IGNORE_REF_CNT, ignore_ref_count); 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci set_64bit_val(wqe, 24, header); 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci print_hex_dump_debug("WQE: DEL_LOCAL_MAC_IPADDR WQE", 85562306a36Sopenharmony_ci DUMP_PREFIX_OFFSET, 16, 8, wqe, 85662306a36Sopenharmony_ci IRDMA_CQP_WQE_SIZE * 8, false); 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci if (post_sq) 85962306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 86062306a36Sopenharmony_ci return 0; 86162306a36Sopenharmony_ci} 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci/** 86462306a36Sopenharmony_ci * irdma_sc_qp_setctx - set qp's context 86562306a36Sopenharmony_ci * @qp: sc qp 86662306a36Sopenharmony_ci * @qp_ctx: context ptr 86762306a36Sopenharmony_ci * @info: ctx info 86862306a36Sopenharmony_ci */ 86962306a36Sopenharmony_civoid irdma_sc_qp_setctx(struct irdma_sc_qp *qp, __le64 *qp_ctx, 87062306a36Sopenharmony_ci struct irdma_qp_host_ctx_info *info) 87162306a36Sopenharmony_ci{ 87262306a36Sopenharmony_ci struct irdma_iwarp_offload_info *iw; 87362306a36Sopenharmony_ci struct irdma_tcp_offload_info *tcp; 87462306a36Sopenharmony_ci struct irdma_sc_dev *dev; 87562306a36Sopenharmony_ci u8 push_mode_en; 87662306a36Sopenharmony_ci u32 push_idx; 87762306a36Sopenharmony_ci u64 qw0, qw3, qw7 = 0, qw16 = 0; 87862306a36Sopenharmony_ci u64 mac = 0; 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci iw = info->iwarp_info; 88162306a36Sopenharmony_ci tcp = info->tcp_info; 88262306a36Sopenharmony_ci dev = qp->dev; 88362306a36Sopenharmony_ci if (iw->rcv_mark_en) { 88462306a36Sopenharmony_ci qp->pfpdu.marker_len = 4; 88562306a36Sopenharmony_ci qp->pfpdu.rcv_start_seq = tcp->rcv_nxt; 88662306a36Sopenharmony_ci } 88762306a36Sopenharmony_ci qp->user_pri = info->user_pri; 88862306a36Sopenharmony_ci if (qp->push_idx == IRDMA_INVALID_PUSH_PAGE_INDEX) { 88962306a36Sopenharmony_ci push_mode_en = 0; 89062306a36Sopenharmony_ci push_idx = 0; 89162306a36Sopenharmony_ci } else { 89262306a36Sopenharmony_ci push_mode_en = 1; 89362306a36Sopenharmony_ci push_idx = qp->push_idx; 89462306a36Sopenharmony_ci } 89562306a36Sopenharmony_ci qw0 = FIELD_PREP(IRDMAQPC_RQWQESIZE, qp->qp_uk.rq_wqe_size) | 89662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVTPHEN, qp->rcv_tph_en) | 89762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_XMITTPHEN, qp->xmit_tph_en) | 89862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RQTPHEN, qp->rq_tph_en) | 89962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SQTPHEN, qp->sq_tph_en) | 90062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PPIDX, push_idx) | 90162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PMENA, push_mode_en); 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_ci set_64bit_val(qp_ctx, 8, qp->sq_pa); 90462306a36Sopenharmony_ci set_64bit_val(qp_ctx, 16, qp->rq_pa); 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci qw3 = FIELD_PREP(IRDMAQPC_RQSIZE, qp->hw_rq_size) | 90762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SQSIZE, qp->hw_sq_size); 90862306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) 90962306a36Sopenharmony_ci qw3 |= FIELD_PREP(IRDMAQPC_GEN1_SRCMACADDRIDX, 91062306a36Sopenharmony_ci qp->src_mac_addr_idx); 91162306a36Sopenharmony_ci set_64bit_val(qp_ctx, 136, 91262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TXCQNUM, info->send_cq_num) | 91362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RXCQNUM, info->rcv_cq_num)); 91462306a36Sopenharmony_ci set_64bit_val(qp_ctx, 168, 91562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_QPCOMPCTX, info->qp_compl_ctx)); 91662306a36Sopenharmony_ci set_64bit_val(qp_ctx, 176, 91762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SQTPHVAL, qp->sq_tph_val) | 91862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RQTPHVAL, qp->rq_tph_val) | 91962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_QSHANDLE, qp->qs_handle) | 92062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_EXCEPTION_LAN_QUEUE, qp->ieq_qp)); 92162306a36Sopenharmony_ci if (info->iwarp_info_valid) { 92262306a36Sopenharmony_ci qw0 |= FIELD_PREP(IRDMAQPC_DDP_VER, iw->ddp_ver) | 92362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RDMAP_VER, iw->rdmap_ver) | 92462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DC_TCP_EN, iw->dctcp_en) | 92562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ECN_EN, iw->ecn_en) | 92662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_IBRDENABLE, iw->ib_rd_en) | 92762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PDIDXHI, iw->pd_id >> 16) | 92862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ERR_RQ_IDX_VALID, 92962306a36Sopenharmony_ci iw->err_rq_idx_valid); 93062306a36Sopenharmony_ci qw7 |= FIELD_PREP(IRDMAQPC_PDIDX, iw->pd_id); 93162306a36Sopenharmony_ci qw16 |= FIELD_PREP(IRDMAQPC_ERR_RQ_IDX, iw->err_rq_idx) | 93262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RTOMIN, iw->rtomin); 93362306a36Sopenharmony_ci set_64bit_val(qp_ctx, 144, 93462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_Q2ADDR, qp->q2_pa >> 8) | 93562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_STAT_INDEX, info->stats_idx)); 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) 93862306a36Sopenharmony_ci mac = ether_addr_to_u64(iw->mac_addr); 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ci set_64bit_val(qp_ctx, 152, 94162306a36Sopenharmony_ci mac << 16 | FIELD_PREP(IRDMAQPC_LASTBYTESENT, iw->last_byte_sent)); 94262306a36Sopenharmony_ci set_64bit_val(qp_ctx, 160, 94362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ORDSIZE, iw->ord_size) | 94462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_IRDSIZE, irdma_sc_get_encoded_ird_size(iw->ird_size)) | 94562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_WRRDRSPOK, iw->wr_rdresp_en) | 94662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RDOK, iw->rd_en) | 94762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDMARKERS, iw->snd_mark_en) | 94862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_BINDEN, iw->bind_en) | 94962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_FASTREGEN, iw->fast_reg_en) | 95062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_PRIVEN, iw->priv_mode_en) | 95162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_USESTATSINSTANCE, info->stats_idx_valid) | 95262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_IWARPMODE, 1) | 95362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVMARKERS, iw->rcv_mark_en) | 95462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ALIGNHDRS, iw->align_hdrs) | 95562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVNOMPACRC, iw->rcv_no_mpa_crc) | 95662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVMARKOFFSET, iw->rcv_mark_offset || !tcp ? iw->rcv_mark_offset : tcp->rcv_nxt) | 95762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDMARKOFFSET, iw->snd_mark_offset || !tcp ? iw->snd_mark_offset : tcp->snd_nxt) | 95862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TIMELYENABLE, iw->timely_en)); 95962306a36Sopenharmony_ci } 96062306a36Sopenharmony_ci if (info->tcp_info_valid) { 96162306a36Sopenharmony_ci qw0 |= FIELD_PREP(IRDMAQPC_IPV4, tcp->ipv4) | 96262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_NONAGLE, tcp->no_nagle) | 96362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_INSERTVLANTAG, 96462306a36Sopenharmony_ci tcp->insert_vlan_tag) | 96562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TIMESTAMP, tcp->time_stamp) | 96662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LIMIT, tcp->cwnd_inc_limit) | 96762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DROPOOOSEG, tcp->drop_ooo_seg) | 96862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DUPACK_THRESH, tcp->dup_ack_thresh); 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci if ((iw->ecn_en || iw->dctcp_en) && !(tcp->tos & 0x03)) 97162306a36Sopenharmony_ci tcp->tos |= ECN_CODE_PT_VAL; 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci qw3 |= FIELD_PREP(IRDMAQPC_TTL, tcp->ttl) | 97462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_AVOIDSTRETCHACK, tcp->avoid_stretch_ack) | 97562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TOS, tcp->tos) | 97662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SRCPORTNUM, tcp->src_port) | 97762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTPORTNUM, tcp->dst_port); 97862306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) { 97962306a36Sopenharmony_ci qw3 |= FIELD_PREP(IRDMAQPC_GEN1_SRCMACADDRIDX, tcp->src_mac_addr_idx); 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci qp->src_mac_addr_idx = tcp->src_mac_addr_idx; 98262306a36Sopenharmony_ci } 98362306a36Sopenharmony_ci set_64bit_val(qp_ctx, 32, 98462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTIPADDR2, tcp->dest_ip_addr[2]) | 98562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTIPADDR3, tcp->dest_ip_addr[3])); 98662306a36Sopenharmony_ci set_64bit_val(qp_ctx, 40, 98762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTIPADDR0, tcp->dest_ip_addr[0]) | 98862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_DESTIPADDR1, tcp->dest_ip_addr[1])); 98962306a36Sopenharmony_ci set_64bit_val(qp_ctx, 48, 99062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDMSS, tcp->snd_mss) | 99162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SYN_RST_HANDLING, tcp->syn_rst_handling) | 99262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_VLANTAG, tcp->vlan_tag) | 99362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_ARPIDX, tcp->arp_idx)); 99462306a36Sopenharmony_ci qw7 |= FIELD_PREP(IRDMAQPC_FLOWLABEL, tcp->flow_label) | 99562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_WSCALE, tcp->wscale) | 99662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_IGNORE_TCP_OPT, 99762306a36Sopenharmony_ci tcp->ignore_tcp_opt) | 99862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_IGNORE_TCP_UNS_OPT, 99962306a36Sopenharmony_ci tcp->ignore_tcp_uns_opt) | 100062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TCPSTATE, tcp->tcp_state) | 100162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVSCALE, tcp->rcv_wscale) | 100262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDSCALE, tcp->snd_wscale); 100362306a36Sopenharmony_ci set_64bit_val(qp_ctx, 72, 100462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TIMESTAMP_RECENT, tcp->time_stamp_recent) | 100562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TIMESTAMP_AGE, tcp->time_stamp_age)); 100662306a36Sopenharmony_ci set_64bit_val(qp_ctx, 80, 100762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDNXT, tcp->snd_nxt) | 100862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDWND, tcp->snd_wnd)); 100962306a36Sopenharmony_ci set_64bit_val(qp_ctx, 88, 101062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVNXT, tcp->rcv_nxt) | 101162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RCVWND, tcp->rcv_wnd)); 101262306a36Sopenharmony_ci set_64bit_val(qp_ctx, 96, 101362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDMAX, tcp->snd_max) | 101462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDUNA, tcp->snd_una)); 101562306a36Sopenharmony_ci set_64bit_val(qp_ctx, 104, 101662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SRTT, tcp->srtt) | 101762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_RTTVAR, tcp->rtt_var)); 101862306a36Sopenharmony_ci set_64bit_val(qp_ctx, 112, 101962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SSTHRESH, tcp->ss_thresh) | 102062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_CWND, tcp->cwnd)); 102162306a36Sopenharmony_ci set_64bit_val(qp_ctx, 120, 102262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDWL1, tcp->snd_wl1) | 102362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_SNDWL2, tcp->snd_wl2)); 102462306a36Sopenharmony_ci qw16 |= FIELD_PREP(IRDMAQPC_MAXSNDWND, tcp->max_snd_window) | 102562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_REXMIT_THRESH, tcp->rexmit_thresh); 102662306a36Sopenharmony_ci set_64bit_val(qp_ctx, 184, 102762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LOCAL_IPADDR3, tcp->local_ipaddr[3]) | 102862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LOCAL_IPADDR2, tcp->local_ipaddr[2])); 102962306a36Sopenharmony_ci set_64bit_val(qp_ctx, 192, 103062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LOCAL_IPADDR1, tcp->local_ipaddr[1]) | 103162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_LOCAL_IPADDR0, tcp->local_ipaddr[0])); 103262306a36Sopenharmony_ci set_64bit_val(qp_ctx, 200, 103362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_THIGH, iw->t_high) | 103462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_TLOW, iw->t_low)); 103562306a36Sopenharmony_ci set_64bit_val(qp_ctx, 208, 103662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPC_REMENDPOINTIDX, info->rem_endpoint_idx)); 103762306a36Sopenharmony_ci } 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_ci set_64bit_val(qp_ctx, 0, qw0); 104062306a36Sopenharmony_ci set_64bit_val(qp_ctx, 24, qw3); 104162306a36Sopenharmony_ci set_64bit_val(qp_ctx, 56, qw7); 104262306a36Sopenharmony_ci set_64bit_val(qp_ctx, 128, qw16); 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ci print_hex_dump_debug("WQE: QP_HOST CTX", DUMP_PREFIX_OFFSET, 16, 8, 104562306a36Sopenharmony_ci qp_ctx, IRDMA_QP_CTX_SIZE, false); 104662306a36Sopenharmony_ci} 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_ci/** 104962306a36Sopenharmony_ci * irdma_sc_alloc_stag - mr stag alloc 105062306a36Sopenharmony_ci * @dev: sc device struct 105162306a36Sopenharmony_ci * @info: stag info 105262306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 105362306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 105462306a36Sopenharmony_ci */ 105562306a36Sopenharmony_cistatic int irdma_sc_alloc_stag(struct irdma_sc_dev *dev, 105662306a36Sopenharmony_ci struct irdma_allocate_stag_info *info, 105762306a36Sopenharmony_ci u64 scratch, bool post_sq) 105862306a36Sopenharmony_ci{ 105962306a36Sopenharmony_ci __le64 *wqe; 106062306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 106162306a36Sopenharmony_ci u64 hdr; 106262306a36Sopenharmony_ci enum irdma_page_size page_size; 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci if (!info->total_len && !info->all_memory) 106562306a36Sopenharmony_ci return -EINVAL; 106662306a36Sopenharmony_ci 106762306a36Sopenharmony_ci if (info->page_size == 0x40000000) 106862306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_1G; 106962306a36Sopenharmony_ci else if (info->page_size == 0x200000) 107062306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_2M; 107162306a36Sopenharmony_ci else 107262306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_4K; 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_ci cqp = dev->cqp; 107562306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 107662306a36Sopenharmony_ci if (!wqe) 107762306a36Sopenharmony_ci return -ENOMEM; 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci set_64bit_val(wqe, 8, 108062306a36Sopenharmony_ci FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID) | 108162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_STAGLEN, info->total_len)); 108262306a36Sopenharmony_ci set_64bit_val(wqe, 16, 108362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx)); 108462306a36Sopenharmony_ci set_64bit_val(wqe, 40, 108562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_HMCFNIDX, info->hmc_fcn_index)); 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci if (info->chunk_size) 108862306a36Sopenharmony_ci set_64bit_val(wqe, 48, 108962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_FIRSTPMPBLIDX, info->first_pm_pbl_idx)); 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_ALLOC_STAG) | 109262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_MR, 1) | 109362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_ARIGHTS, info->access_rights) | 109462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_LPBLSIZE, info->chunk_size) | 109562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_HPAGESIZE, page_size) | 109662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_REMACCENABLED, info->remote_access) | 109762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_USEHMCFNIDX, info->use_hmc_fcn_index) | 109862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_USEPFRID, info->use_pf_rid) | 109962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 110062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ci print_hex_dump_debug("WQE: ALLOC_STAG WQE", DUMP_PREFIX_OFFSET, 16, 8, 110562306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 110662306a36Sopenharmony_ci if (post_sq) 110762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_ci return 0; 111062306a36Sopenharmony_ci} 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_ci/** 111362306a36Sopenharmony_ci * irdma_sc_mr_reg_non_shared - non-shared mr registration 111462306a36Sopenharmony_ci * @dev: sc device struct 111562306a36Sopenharmony_ci * @info: mr info 111662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 111762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 111862306a36Sopenharmony_ci */ 111962306a36Sopenharmony_cistatic int irdma_sc_mr_reg_non_shared(struct irdma_sc_dev *dev, 112062306a36Sopenharmony_ci struct irdma_reg_ns_stag_info *info, 112162306a36Sopenharmony_ci u64 scratch, bool post_sq) 112262306a36Sopenharmony_ci{ 112362306a36Sopenharmony_ci __le64 *wqe; 112462306a36Sopenharmony_ci u64 fbo; 112562306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 112662306a36Sopenharmony_ci u64 hdr; 112762306a36Sopenharmony_ci u32 pble_obj_cnt; 112862306a36Sopenharmony_ci bool remote_access; 112962306a36Sopenharmony_ci u8 addr_type; 113062306a36Sopenharmony_ci enum irdma_page_size page_size; 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_ci if (!info->total_len && !info->all_memory) 113362306a36Sopenharmony_ci return -EINVAL; 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ci if (info->page_size == 0x40000000) 113662306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_1G; 113762306a36Sopenharmony_ci else if (info->page_size == 0x200000) 113862306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_2M; 113962306a36Sopenharmony_ci else if (info->page_size == 0x1000) 114062306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_4K; 114162306a36Sopenharmony_ci else 114262306a36Sopenharmony_ci return -EINVAL; 114362306a36Sopenharmony_ci 114462306a36Sopenharmony_ci if (info->access_rights & (IRDMA_ACCESS_FLAGS_REMOTEREAD_ONLY | 114562306a36Sopenharmony_ci IRDMA_ACCESS_FLAGS_REMOTEWRITE_ONLY)) 114662306a36Sopenharmony_ci remote_access = true; 114762306a36Sopenharmony_ci else 114862306a36Sopenharmony_ci remote_access = false; 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci pble_obj_cnt = dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt; 115162306a36Sopenharmony_ci if (info->chunk_size && info->first_pm_pbl_index >= pble_obj_cnt) 115262306a36Sopenharmony_ci return -EINVAL; 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci cqp = dev->cqp; 115562306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 115662306a36Sopenharmony_ci if (!wqe) 115762306a36Sopenharmony_ci return -ENOMEM; 115862306a36Sopenharmony_ci fbo = info->va & (info->page_size - 1); 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ci set_64bit_val(wqe, 0, 116162306a36Sopenharmony_ci (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED ? 116262306a36Sopenharmony_ci info->va : fbo)); 116362306a36Sopenharmony_ci set_64bit_val(wqe, 8, 116462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_STAGLEN, info->total_len) | 116562306a36Sopenharmony_ci FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID)); 116662306a36Sopenharmony_ci set_64bit_val(wqe, 16, 116762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_KEY, info->stag_key) | 116862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx)); 116962306a36Sopenharmony_ci if (!info->chunk_size) { 117062306a36Sopenharmony_ci set_64bit_val(wqe, 32, info->reg_addr_pa); 117162306a36Sopenharmony_ci set_64bit_val(wqe, 48, 0); 117262306a36Sopenharmony_ci } else { 117362306a36Sopenharmony_ci set_64bit_val(wqe, 32, 0); 117462306a36Sopenharmony_ci set_64bit_val(wqe, 48, 117562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_FIRSTPMPBLIDX, info->first_pm_pbl_index)); 117662306a36Sopenharmony_ci } 117762306a36Sopenharmony_ci set_64bit_val(wqe, 40, info->hmc_fcn_index); 117862306a36Sopenharmony_ci set_64bit_val(wqe, 56, 0); 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci addr_type = (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED) ? 1 : 0; 118162306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_REG_MR) | 118262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_MR, 1) | 118362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_LPBLSIZE, info->chunk_size) | 118462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_HPAGESIZE, page_size) | 118562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_ARIGHTS, info->access_rights) | 118662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_REMACCENABLED, remote_access) | 118762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_VABASEDTO, addr_type) | 118862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_USEHMCFNIDX, info->use_hmc_fcn_index) | 118962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_USEPFRID, info->use_pf_rid) | 119062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 119162306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci print_hex_dump_debug("WQE: MR_REG_NS WQE", DUMP_PREFIX_OFFSET, 16, 8, 119662306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 119762306a36Sopenharmony_ci if (post_sq) 119862306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 119962306a36Sopenharmony_ci 120062306a36Sopenharmony_ci return 0; 120162306a36Sopenharmony_ci} 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_ci/** 120462306a36Sopenharmony_ci * irdma_sc_dealloc_stag - deallocate stag 120562306a36Sopenharmony_ci * @dev: sc device struct 120662306a36Sopenharmony_ci * @info: dealloc stag info 120762306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 120862306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 120962306a36Sopenharmony_ci */ 121062306a36Sopenharmony_cistatic int irdma_sc_dealloc_stag(struct irdma_sc_dev *dev, 121162306a36Sopenharmony_ci struct irdma_dealloc_stag_info *info, 121262306a36Sopenharmony_ci u64 scratch, bool post_sq) 121362306a36Sopenharmony_ci{ 121462306a36Sopenharmony_ci u64 hdr; 121562306a36Sopenharmony_ci __le64 *wqe; 121662306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci cqp = dev->cqp; 121962306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 122062306a36Sopenharmony_ci if (!wqe) 122162306a36Sopenharmony_ci return -ENOMEM; 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci set_64bit_val(wqe, 8, 122462306a36Sopenharmony_ci FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID)); 122562306a36Sopenharmony_ci set_64bit_val(wqe, 16, 122662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx)); 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DEALLOC_STAG) | 122962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_MR, info->mr) | 123062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 123162306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 123462306a36Sopenharmony_ci 123562306a36Sopenharmony_ci print_hex_dump_debug("WQE: DEALLOC_STAG WQE", DUMP_PREFIX_OFFSET, 16, 123662306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 123762306a36Sopenharmony_ci if (post_sq) 123862306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_ci return 0; 124162306a36Sopenharmony_ci} 124262306a36Sopenharmony_ci 124362306a36Sopenharmony_ci/** 124462306a36Sopenharmony_ci * irdma_sc_mw_alloc - mw allocate 124562306a36Sopenharmony_ci * @dev: sc device struct 124662306a36Sopenharmony_ci * @info: memory window allocation information 124762306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 124862306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 124962306a36Sopenharmony_ci */ 125062306a36Sopenharmony_cistatic int irdma_sc_mw_alloc(struct irdma_sc_dev *dev, 125162306a36Sopenharmony_ci struct irdma_mw_alloc_info *info, u64 scratch, 125262306a36Sopenharmony_ci bool post_sq) 125362306a36Sopenharmony_ci{ 125462306a36Sopenharmony_ci u64 hdr; 125562306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 125662306a36Sopenharmony_ci __le64 *wqe; 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ci cqp = dev->cqp; 125962306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 126062306a36Sopenharmony_ci if (!wqe) 126162306a36Sopenharmony_ci return -ENOMEM; 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_ci set_64bit_val(wqe, 8, 126462306a36Sopenharmony_ci FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID)); 126562306a36Sopenharmony_ci set_64bit_val(wqe, 16, 126662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->mw_stag_index)); 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_ALLOC_STAG) | 126962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_MWTYPE, info->mw_wide) | 127062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STAG_MW1_BIND_DONT_VLDT_KEY, 127162306a36Sopenharmony_ci info->mw1_bind_dont_vldt_key) | 127262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 127362306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 127462306a36Sopenharmony_ci 127562306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_ci print_hex_dump_debug("WQE: MW_ALLOC WQE", DUMP_PREFIX_OFFSET, 16, 8, 127862306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 127962306a36Sopenharmony_ci if (post_sq) 128062306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci return 0; 128362306a36Sopenharmony_ci} 128462306a36Sopenharmony_ci 128562306a36Sopenharmony_ci/** 128662306a36Sopenharmony_ci * irdma_sc_mr_fast_register - Posts RDMA fast register mr WR to iwarp qp 128762306a36Sopenharmony_ci * @qp: sc qp struct 128862306a36Sopenharmony_ci * @info: fast mr info 128962306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 129062306a36Sopenharmony_ci */ 129162306a36Sopenharmony_ciint irdma_sc_mr_fast_register(struct irdma_sc_qp *qp, 129262306a36Sopenharmony_ci struct irdma_fast_reg_stag_info *info, 129362306a36Sopenharmony_ci bool post_sq) 129462306a36Sopenharmony_ci{ 129562306a36Sopenharmony_ci u64 temp, hdr; 129662306a36Sopenharmony_ci __le64 *wqe; 129762306a36Sopenharmony_ci u32 wqe_idx; 129862306a36Sopenharmony_ci enum irdma_page_size page_size; 129962306a36Sopenharmony_ci struct irdma_post_sq_info sq_info = {}; 130062306a36Sopenharmony_ci 130162306a36Sopenharmony_ci if (info->page_size == 0x40000000) 130262306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_1G; 130362306a36Sopenharmony_ci else if (info->page_size == 0x200000) 130462306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_2M; 130562306a36Sopenharmony_ci else 130662306a36Sopenharmony_ci page_size = IRDMA_PAGE_SIZE_4K; 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci sq_info.wr_id = info->wr_id; 130962306a36Sopenharmony_ci sq_info.signaled = info->signaled; 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_ci wqe = irdma_qp_get_next_send_wqe(&qp->qp_uk, &wqe_idx, 131262306a36Sopenharmony_ci IRDMA_QP_WQE_MIN_QUANTA, 0, &sq_info); 131362306a36Sopenharmony_ci if (!wqe) 131462306a36Sopenharmony_ci return -ENOMEM; 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_ci irdma_clr_wqes(&qp->qp_uk, wqe_idx); 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_ci ibdev_dbg(to_ibdev(qp->dev), 131962306a36Sopenharmony_ci "MR: wr_id[%llxh] wqe_idx[%04d] location[%p]\n", 132062306a36Sopenharmony_ci info->wr_id, wqe_idx, 132162306a36Sopenharmony_ci &qp->qp_uk.sq_wrtrk_array[wqe_idx].wrid); 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_ci temp = (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED) ? 132462306a36Sopenharmony_ci (uintptr_t)info->va : info->fbo; 132562306a36Sopenharmony_ci set_64bit_val(wqe, 0, temp); 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci temp = FIELD_GET(IRDMAQPSQ_FIRSTPMPBLIDXHI, 132862306a36Sopenharmony_ci info->first_pm_pbl_index >> 16); 132962306a36Sopenharmony_ci set_64bit_val(wqe, 8, 133062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_FIRSTPMPBLIDXHI, temp) | 133162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_PBLADDR >> IRDMA_HW_PAGE_SHIFT, info->reg_addr_pa)); 133262306a36Sopenharmony_ci set_64bit_val(wqe, 16, 133362306a36Sopenharmony_ci info->total_len | 133462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_FIRSTPMPBLIDXLO, info->first_pm_pbl_index)); 133562306a36Sopenharmony_ci 133662306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMAQPSQ_STAGKEY, info->stag_key) | 133762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_STAGINDEX, info->stag_idx) | 133862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_FAST_REGISTER) | 133962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_LPBLSIZE, info->chunk_size) | 134062306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_HPAGESIZE, page_size) | 134162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_STAGRIGHTS, info->access_rights) | 134262306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VABASEDTO, info->addr_type) | 134362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) | 134462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) | 134562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) | 134662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity); 134762306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 134862306a36Sopenharmony_ci 134962306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci print_hex_dump_debug("WQE: FAST_REG WQE", DUMP_PREFIX_OFFSET, 16, 8, 135262306a36Sopenharmony_ci wqe, IRDMA_QP_WQE_MIN_SIZE, false); 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci if (post_sq) 135562306a36Sopenharmony_ci irdma_uk_qp_post_wr(&qp->qp_uk); 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci return 0; 135862306a36Sopenharmony_ci} 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci/** 136162306a36Sopenharmony_ci * irdma_sc_gen_rts_ae - request AE generated after RTS 136262306a36Sopenharmony_ci * @qp: sc qp struct 136362306a36Sopenharmony_ci */ 136462306a36Sopenharmony_cistatic void irdma_sc_gen_rts_ae(struct irdma_sc_qp *qp) 136562306a36Sopenharmony_ci{ 136662306a36Sopenharmony_ci __le64 *wqe; 136762306a36Sopenharmony_ci u64 hdr; 136862306a36Sopenharmony_ci struct irdma_qp_uk *qp_uk; 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci qp_uk = &qp->qp_uk; 137162306a36Sopenharmony_ci 137262306a36Sopenharmony_ci wqe = qp_uk->sq_base[1].elem; 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_NOP) | 137562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_LOCALFENCE, 1) | 137662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity); 137762306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 137862306a36Sopenharmony_ci 137962306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 138062306a36Sopenharmony_ci print_hex_dump_debug("QP: NOP W/LOCAL FENCE WQE", DUMP_PREFIX_OFFSET, 138162306a36Sopenharmony_ci 16, 8, wqe, IRDMA_QP_WQE_MIN_SIZE, false); 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci wqe = qp_uk->sq_base[2].elem; 138462306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_GEN_RTS_AE) | 138562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity); 138662306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 138962306a36Sopenharmony_ci print_hex_dump_debug("QP: CONN EST WQE", DUMP_PREFIX_OFFSET, 16, 8, 139062306a36Sopenharmony_ci wqe, IRDMA_QP_WQE_MIN_SIZE, false); 139162306a36Sopenharmony_ci} 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ci/** 139462306a36Sopenharmony_ci * irdma_sc_send_lsmm - send last streaming mode message 139562306a36Sopenharmony_ci * @qp: sc qp struct 139662306a36Sopenharmony_ci * @lsmm_buf: buffer with lsmm message 139762306a36Sopenharmony_ci * @size: size of lsmm buffer 139862306a36Sopenharmony_ci * @stag: stag of lsmm buffer 139962306a36Sopenharmony_ci */ 140062306a36Sopenharmony_civoid irdma_sc_send_lsmm(struct irdma_sc_qp *qp, void *lsmm_buf, u32 size, 140162306a36Sopenharmony_ci irdma_stag stag) 140262306a36Sopenharmony_ci{ 140362306a36Sopenharmony_ci __le64 *wqe; 140462306a36Sopenharmony_ci u64 hdr; 140562306a36Sopenharmony_ci struct irdma_qp_uk *qp_uk; 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci qp_uk = &qp->qp_uk; 140862306a36Sopenharmony_ci wqe = qp_uk->sq_base->elem; 140962306a36Sopenharmony_ci 141062306a36Sopenharmony_ci set_64bit_val(wqe, 0, (uintptr_t)lsmm_buf); 141162306a36Sopenharmony_ci if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) { 141262306a36Sopenharmony_ci set_64bit_val(wqe, 8, 141362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_LEN, size) | 141462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_STAG, stag)); 141562306a36Sopenharmony_ci } else { 141662306a36Sopenharmony_ci set_64bit_val(wqe, 8, 141762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_FRAG_LEN, size) | 141862306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_FRAG_STAG, stag) | 141962306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity)); 142062306a36Sopenharmony_ci } 142162306a36Sopenharmony_ci set_64bit_val(wqe, 16, 0); 142262306a36Sopenharmony_ci 142362306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_RDMA_SEND) | 142462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_STREAMMODE, 1) | 142562306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_WAITFORRCVPDU, 1) | 142662306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity); 142762306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 142862306a36Sopenharmony_ci 142962306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_ci print_hex_dump_debug("WQE: SEND_LSMM WQE", DUMP_PREFIX_OFFSET, 16, 8, 143262306a36Sopenharmony_ci wqe, IRDMA_QP_WQE_MIN_SIZE, false); 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci if (qp->dev->hw_attrs.uk_attrs.feature_flags & IRDMA_FEATURE_RTS_AE) 143562306a36Sopenharmony_ci irdma_sc_gen_rts_ae(qp); 143662306a36Sopenharmony_ci} 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_ci/** 143962306a36Sopenharmony_ci * irdma_sc_send_rtt - send last read0 or write0 144062306a36Sopenharmony_ci * @qp: sc qp struct 144162306a36Sopenharmony_ci * @read: Do read0 or write0 144262306a36Sopenharmony_ci */ 144362306a36Sopenharmony_civoid irdma_sc_send_rtt(struct irdma_sc_qp *qp, bool read) 144462306a36Sopenharmony_ci{ 144562306a36Sopenharmony_ci __le64 *wqe; 144662306a36Sopenharmony_ci u64 hdr; 144762306a36Sopenharmony_ci struct irdma_qp_uk *qp_uk; 144862306a36Sopenharmony_ci 144962306a36Sopenharmony_ci qp_uk = &qp->qp_uk; 145062306a36Sopenharmony_ci wqe = qp_uk->sq_base->elem; 145162306a36Sopenharmony_ci 145262306a36Sopenharmony_ci set_64bit_val(wqe, 0, 0); 145362306a36Sopenharmony_ci set_64bit_val(wqe, 16, 0); 145462306a36Sopenharmony_ci if (read) { 145562306a36Sopenharmony_ci if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) { 145662306a36Sopenharmony_ci set_64bit_val(wqe, 8, 145762306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_STAG, 0xabcd)); 145862306a36Sopenharmony_ci } else { 145962306a36Sopenharmony_ci set_64bit_val(wqe, 8, 146062306a36Sopenharmony_ci (u64)0xabcd | FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity)); 146162306a36Sopenharmony_ci } 146262306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, 0x1234) | 146362306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_RDMA_READ) | 146462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity); 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci } else { 146762306a36Sopenharmony_ci if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) { 146862306a36Sopenharmony_ci set_64bit_val(wqe, 8, 0); 146962306a36Sopenharmony_ci } else { 147062306a36Sopenharmony_ci set_64bit_val(wqe, 8, 147162306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity)); 147262306a36Sopenharmony_ci } 147362306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_RDMA_WRITE) | 147462306a36Sopenharmony_ci FIELD_PREP(IRDMAQPSQ_VALID, qp->qp_uk.swqe_polarity); 147562306a36Sopenharmony_ci } 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 147862306a36Sopenharmony_ci 147962306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 148062306a36Sopenharmony_ci 148162306a36Sopenharmony_ci print_hex_dump_debug("WQE: RTR WQE", DUMP_PREFIX_OFFSET, 16, 8, wqe, 148262306a36Sopenharmony_ci IRDMA_QP_WQE_MIN_SIZE, false); 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci if (qp->dev->hw_attrs.uk_attrs.feature_flags & IRDMA_FEATURE_RTS_AE) 148562306a36Sopenharmony_ci irdma_sc_gen_rts_ae(qp); 148662306a36Sopenharmony_ci} 148762306a36Sopenharmony_ci 148862306a36Sopenharmony_ci/** 148962306a36Sopenharmony_ci * irdma_iwarp_opcode - determine if incoming is rdma layer 149062306a36Sopenharmony_ci * @info: aeq info for the packet 149162306a36Sopenharmony_ci * @pkt: packet for error 149262306a36Sopenharmony_ci */ 149362306a36Sopenharmony_cistatic u32 irdma_iwarp_opcode(struct irdma_aeqe_info *info, u8 *pkt) 149462306a36Sopenharmony_ci{ 149562306a36Sopenharmony_ci __be16 *mpa; 149662306a36Sopenharmony_ci u32 opcode = 0xffffffff; 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci if (info->q2_data_written) { 149962306a36Sopenharmony_ci mpa = (__be16 *)pkt; 150062306a36Sopenharmony_ci opcode = ntohs(mpa[1]) & 0xf; 150162306a36Sopenharmony_ci } 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_ci return opcode; 150462306a36Sopenharmony_ci} 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci/** 150762306a36Sopenharmony_ci * irdma_locate_mpa - return pointer to mpa in the pkt 150862306a36Sopenharmony_ci * @pkt: packet with data 150962306a36Sopenharmony_ci */ 151062306a36Sopenharmony_cistatic u8 *irdma_locate_mpa(u8 *pkt) 151162306a36Sopenharmony_ci{ 151262306a36Sopenharmony_ci /* skip over ethernet header */ 151362306a36Sopenharmony_ci pkt += IRDMA_MAC_HLEN; 151462306a36Sopenharmony_ci 151562306a36Sopenharmony_ci /* Skip over IP and TCP headers */ 151662306a36Sopenharmony_ci pkt += 4 * (pkt[0] & 0x0f); 151762306a36Sopenharmony_ci pkt += 4 * ((pkt[12] >> 4) & 0x0f); 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_ci return pkt; 152062306a36Sopenharmony_ci} 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci/** 152362306a36Sopenharmony_ci * irdma_bld_termhdr_ctrl - setup terminate hdr control fields 152462306a36Sopenharmony_ci * @qp: sc qp ptr for pkt 152562306a36Sopenharmony_ci * @hdr: term hdr 152662306a36Sopenharmony_ci * @opcode: flush opcode for termhdr 152762306a36Sopenharmony_ci * @layer_etype: error layer + error type 152862306a36Sopenharmony_ci * @err: error cod ein the header 152962306a36Sopenharmony_ci */ 153062306a36Sopenharmony_cistatic void irdma_bld_termhdr_ctrl(struct irdma_sc_qp *qp, 153162306a36Sopenharmony_ci struct irdma_terminate_hdr *hdr, 153262306a36Sopenharmony_ci enum irdma_flush_opcode opcode, 153362306a36Sopenharmony_ci u8 layer_etype, u8 err) 153462306a36Sopenharmony_ci{ 153562306a36Sopenharmony_ci qp->flush_code = opcode; 153662306a36Sopenharmony_ci hdr->layer_etype = layer_etype; 153762306a36Sopenharmony_ci hdr->error_code = err; 153862306a36Sopenharmony_ci} 153962306a36Sopenharmony_ci 154062306a36Sopenharmony_ci/** 154162306a36Sopenharmony_ci * irdma_bld_termhdr_ddp_rdma - setup ddp and rdma hdrs in terminate hdr 154262306a36Sopenharmony_ci * @pkt: ptr to mpa in offending pkt 154362306a36Sopenharmony_ci * @hdr: term hdr 154462306a36Sopenharmony_ci * @copy_len: offending pkt length to be copied to term hdr 154562306a36Sopenharmony_ci * @is_tagged: DDP tagged or untagged 154662306a36Sopenharmony_ci */ 154762306a36Sopenharmony_cistatic void irdma_bld_termhdr_ddp_rdma(u8 *pkt, struct irdma_terminate_hdr *hdr, 154862306a36Sopenharmony_ci int *copy_len, u8 *is_tagged) 154962306a36Sopenharmony_ci{ 155062306a36Sopenharmony_ci u16 ddp_seg_len; 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci ddp_seg_len = ntohs(*(__be16 *)pkt); 155362306a36Sopenharmony_ci if (ddp_seg_len) { 155462306a36Sopenharmony_ci *copy_len = 2; 155562306a36Sopenharmony_ci hdr->hdrct = DDP_LEN_FLAG; 155662306a36Sopenharmony_ci if (pkt[2] & 0x80) { 155762306a36Sopenharmony_ci *is_tagged = 1; 155862306a36Sopenharmony_ci if (ddp_seg_len >= TERM_DDP_LEN_TAGGED) { 155962306a36Sopenharmony_ci *copy_len += TERM_DDP_LEN_TAGGED; 156062306a36Sopenharmony_ci hdr->hdrct |= DDP_HDR_FLAG; 156162306a36Sopenharmony_ci } 156262306a36Sopenharmony_ci } else { 156362306a36Sopenharmony_ci if (ddp_seg_len >= TERM_DDP_LEN_UNTAGGED) { 156462306a36Sopenharmony_ci *copy_len += TERM_DDP_LEN_UNTAGGED; 156562306a36Sopenharmony_ci hdr->hdrct |= DDP_HDR_FLAG; 156662306a36Sopenharmony_ci } 156762306a36Sopenharmony_ci if (ddp_seg_len >= (TERM_DDP_LEN_UNTAGGED + TERM_RDMA_LEN) && 156862306a36Sopenharmony_ci ((pkt[3] & RDMA_OPCODE_M) == RDMA_READ_REQ_OPCODE)) { 156962306a36Sopenharmony_ci *copy_len += TERM_RDMA_LEN; 157062306a36Sopenharmony_ci hdr->hdrct |= RDMA_HDR_FLAG; 157162306a36Sopenharmony_ci } 157262306a36Sopenharmony_ci } 157362306a36Sopenharmony_ci } 157462306a36Sopenharmony_ci} 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci/** 157762306a36Sopenharmony_ci * irdma_bld_terminate_hdr - build terminate message header 157862306a36Sopenharmony_ci * @qp: qp associated with received terminate AE 157962306a36Sopenharmony_ci * @info: the struct contiaing AE information 158062306a36Sopenharmony_ci */ 158162306a36Sopenharmony_cistatic int irdma_bld_terminate_hdr(struct irdma_sc_qp *qp, 158262306a36Sopenharmony_ci struct irdma_aeqe_info *info) 158362306a36Sopenharmony_ci{ 158462306a36Sopenharmony_ci u8 *pkt = qp->q2_buf + Q2_BAD_FRAME_OFFSET; 158562306a36Sopenharmony_ci int copy_len = 0; 158662306a36Sopenharmony_ci u8 is_tagged = 0; 158762306a36Sopenharmony_ci u32 opcode; 158862306a36Sopenharmony_ci struct irdma_terminate_hdr *termhdr; 158962306a36Sopenharmony_ci 159062306a36Sopenharmony_ci termhdr = (struct irdma_terminate_hdr *)qp->q2_buf; 159162306a36Sopenharmony_ci memset(termhdr, 0, Q2_BAD_FRAME_OFFSET); 159262306a36Sopenharmony_ci 159362306a36Sopenharmony_ci if (info->q2_data_written) { 159462306a36Sopenharmony_ci pkt = irdma_locate_mpa(pkt); 159562306a36Sopenharmony_ci irdma_bld_termhdr_ddp_rdma(pkt, termhdr, ©_len, &is_tagged); 159662306a36Sopenharmony_ci } 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_ci opcode = irdma_iwarp_opcode(info, pkt); 159962306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; 160062306a36Sopenharmony_ci qp->sq_flush_code = info->sq; 160162306a36Sopenharmony_ci qp->rq_flush_code = info->rq; 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_ci switch (info->ae_id) { 160462306a36Sopenharmony_ci case IRDMA_AE_AMP_UNALLOCATED_STAG: 160562306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; 160662306a36Sopenharmony_ci if (opcode == IRDMA_OP_TYPE_RDMA_WRITE) 160762306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR, 160862306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_TAGGED_BUF, 160962306a36Sopenharmony_ci DDP_TAGGED_INV_STAG); 161062306a36Sopenharmony_ci else 161162306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR, 161262306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, 161362306a36Sopenharmony_ci RDMAP_INV_STAG); 161462306a36Sopenharmony_ci break; 161562306a36Sopenharmony_ci case IRDMA_AE_AMP_BOUNDS_VIOLATION: 161662306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; 161762306a36Sopenharmony_ci if (info->q2_data_written) 161862306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR, 161962306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_TAGGED_BUF, 162062306a36Sopenharmony_ci DDP_TAGGED_BOUNDS); 162162306a36Sopenharmony_ci else 162262306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR, 162362306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, 162462306a36Sopenharmony_ci RDMAP_INV_BOUNDS); 162562306a36Sopenharmony_ci break; 162662306a36Sopenharmony_ci case IRDMA_AE_AMP_BAD_PD: 162762306a36Sopenharmony_ci switch (opcode) { 162862306a36Sopenharmony_ci case IRDMA_OP_TYPE_RDMA_WRITE: 162962306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR, 163062306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_TAGGED_BUF, 163162306a36Sopenharmony_ci DDP_TAGGED_UNASSOC_STAG); 163262306a36Sopenharmony_ci break; 163362306a36Sopenharmony_ci case IRDMA_OP_TYPE_SEND_INV: 163462306a36Sopenharmony_ci case IRDMA_OP_TYPE_SEND_SOL_INV: 163562306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR, 163662306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, 163762306a36Sopenharmony_ci RDMAP_CANT_INV_STAG); 163862306a36Sopenharmony_ci break; 163962306a36Sopenharmony_ci default: 164062306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR, 164162306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, 164262306a36Sopenharmony_ci RDMAP_UNASSOC_STAG); 164362306a36Sopenharmony_ci } 164462306a36Sopenharmony_ci break; 164562306a36Sopenharmony_ci case IRDMA_AE_AMP_INVALID_STAG: 164662306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; 164762306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR, 164862306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, 164962306a36Sopenharmony_ci RDMAP_INV_STAG); 165062306a36Sopenharmony_ci break; 165162306a36Sopenharmony_ci case IRDMA_AE_AMP_BAD_QP: 165262306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_QP_OP_ERR, 165362306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_UNTAGGED_BUF, 165462306a36Sopenharmony_ci DDP_UNTAGGED_INV_QN); 165562306a36Sopenharmony_ci break; 165662306a36Sopenharmony_ci case IRDMA_AE_AMP_BAD_STAG_KEY: 165762306a36Sopenharmony_ci case IRDMA_AE_AMP_BAD_STAG_INDEX: 165862306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; 165962306a36Sopenharmony_ci switch (opcode) { 166062306a36Sopenharmony_ci case IRDMA_OP_TYPE_SEND_INV: 166162306a36Sopenharmony_ci case IRDMA_OP_TYPE_SEND_SOL_INV: 166262306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_OP_ERR, 166362306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, 166462306a36Sopenharmony_ci RDMAP_CANT_INV_STAG); 166562306a36Sopenharmony_ci break; 166662306a36Sopenharmony_ci default: 166762306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR, 166862306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, 166962306a36Sopenharmony_ci RDMAP_INV_STAG); 167062306a36Sopenharmony_ci } 167162306a36Sopenharmony_ci break; 167262306a36Sopenharmony_ci case IRDMA_AE_AMP_RIGHTS_VIOLATION: 167362306a36Sopenharmony_ci case IRDMA_AE_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS: 167462306a36Sopenharmony_ci case IRDMA_AE_PRIV_OPERATION_DENIED: 167562306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; 167662306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR, 167762306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, 167862306a36Sopenharmony_ci RDMAP_ACCESS); 167962306a36Sopenharmony_ci break; 168062306a36Sopenharmony_ci case IRDMA_AE_AMP_TO_WRAP: 168162306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; 168262306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR, 168362306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, 168462306a36Sopenharmony_ci RDMAP_TO_WRAP); 168562306a36Sopenharmony_ci break; 168662306a36Sopenharmony_ci case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR: 168762306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR, 168862306a36Sopenharmony_ci (LAYER_MPA << 4) | DDP_LLP, MPA_CRC); 168962306a36Sopenharmony_ci break; 169062306a36Sopenharmony_ci case IRDMA_AE_LLP_SEGMENT_TOO_SMALL: 169162306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_LEN_ERR, 169262306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_CATASTROPHIC, 169362306a36Sopenharmony_ci DDP_CATASTROPHIC_LOCAL); 169462306a36Sopenharmony_ci break; 169562306a36Sopenharmony_ci case IRDMA_AE_LCE_QP_CATASTROPHIC: 169662306a36Sopenharmony_ci case IRDMA_AE_DDP_NO_L_BIT: 169762306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_FATAL_ERR, 169862306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_CATASTROPHIC, 169962306a36Sopenharmony_ci DDP_CATASTROPHIC_LOCAL); 170062306a36Sopenharmony_ci break; 170162306a36Sopenharmony_ci case IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN: 170262306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR, 170362306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_UNTAGGED_BUF, 170462306a36Sopenharmony_ci DDP_UNTAGGED_INV_MSN_RANGE); 170562306a36Sopenharmony_ci break; 170662306a36Sopenharmony_ci case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER: 170762306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; 170862306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_LEN_ERR, 170962306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_UNTAGGED_BUF, 171062306a36Sopenharmony_ci DDP_UNTAGGED_INV_TOO_LONG); 171162306a36Sopenharmony_ci break; 171262306a36Sopenharmony_ci case IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION: 171362306a36Sopenharmony_ci if (is_tagged) 171462306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR, 171562306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_TAGGED_BUF, 171662306a36Sopenharmony_ci DDP_TAGGED_INV_DDP_VER); 171762306a36Sopenharmony_ci else 171862306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR, 171962306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_UNTAGGED_BUF, 172062306a36Sopenharmony_ci DDP_UNTAGGED_INV_DDP_VER); 172162306a36Sopenharmony_ci break; 172262306a36Sopenharmony_ci case IRDMA_AE_DDP_UBE_INVALID_MO: 172362306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR, 172462306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_UNTAGGED_BUF, 172562306a36Sopenharmony_ci DDP_UNTAGGED_INV_MO); 172662306a36Sopenharmony_ci break; 172762306a36Sopenharmony_ci case IRDMA_AE_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE: 172862306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_OP_ERR, 172962306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_UNTAGGED_BUF, 173062306a36Sopenharmony_ci DDP_UNTAGGED_INV_MSN_NO_BUF); 173162306a36Sopenharmony_ci break; 173262306a36Sopenharmony_ci case IRDMA_AE_DDP_UBE_INVALID_QN: 173362306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR, 173462306a36Sopenharmony_ci (LAYER_DDP << 4) | DDP_UNTAGGED_BUF, 173562306a36Sopenharmony_ci DDP_UNTAGGED_INV_QN); 173662306a36Sopenharmony_ci break; 173762306a36Sopenharmony_ci case IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION: 173862306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR, 173962306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, 174062306a36Sopenharmony_ci RDMAP_INV_RDMAP_VER); 174162306a36Sopenharmony_ci break; 174262306a36Sopenharmony_ci default: 174362306a36Sopenharmony_ci irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_FATAL_ERR, 174462306a36Sopenharmony_ci (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, 174562306a36Sopenharmony_ci RDMAP_UNSPECIFIED); 174662306a36Sopenharmony_ci break; 174762306a36Sopenharmony_ci } 174862306a36Sopenharmony_ci 174962306a36Sopenharmony_ci if (copy_len) 175062306a36Sopenharmony_ci memcpy(termhdr + 1, pkt, copy_len); 175162306a36Sopenharmony_ci 175262306a36Sopenharmony_ci return sizeof(struct irdma_terminate_hdr) + copy_len; 175362306a36Sopenharmony_ci} 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_ci/** 175662306a36Sopenharmony_ci * irdma_terminate_send_fin() - Send fin for terminate message 175762306a36Sopenharmony_ci * @qp: qp associated with received terminate AE 175862306a36Sopenharmony_ci */ 175962306a36Sopenharmony_civoid irdma_terminate_send_fin(struct irdma_sc_qp *qp) 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci irdma_term_modify_qp(qp, IRDMA_QP_STATE_TERMINATE, 176262306a36Sopenharmony_ci IRDMAQP_TERM_SEND_FIN_ONLY, 0); 176362306a36Sopenharmony_ci} 176462306a36Sopenharmony_ci 176562306a36Sopenharmony_ci/** 176662306a36Sopenharmony_ci * irdma_terminate_connection() - Bad AE and send terminate to remote QP 176762306a36Sopenharmony_ci * @qp: qp associated with received terminate AE 176862306a36Sopenharmony_ci * @info: the struct contiaing AE information 176962306a36Sopenharmony_ci */ 177062306a36Sopenharmony_civoid irdma_terminate_connection(struct irdma_sc_qp *qp, 177162306a36Sopenharmony_ci struct irdma_aeqe_info *info) 177262306a36Sopenharmony_ci{ 177362306a36Sopenharmony_ci u8 termlen = 0; 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_ci if (qp->term_flags & IRDMA_TERM_SENT) 177662306a36Sopenharmony_ci return; 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ci termlen = irdma_bld_terminate_hdr(qp, info); 177962306a36Sopenharmony_ci irdma_terminate_start_timer(qp); 178062306a36Sopenharmony_ci qp->term_flags |= IRDMA_TERM_SENT; 178162306a36Sopenharmony_ci irdma_term_modify_qp(qp, IRDMA_QP_STATE_TERMINATE, 178262306a36Sopenharmony_ci IRDMAQP_TERM_SEND_TERM_ONLY, termlen); 178362306a36Sopenharmony_ci} 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci/** 178662306a36Sopenharmony_ci * irdma_terminate_received - handle terminate received AE 178762306a36Sopenharmony_ci * @qp: qp associated with received terminate AE 178862306a36Sopenharmony_ci * @info: the struct contiaing AE information 178962306a36Sopenharmony_ci */ 179062306a36Sopenharmony_civoid irdma_terminate_received(struct irdma_sc_qp *qp, 179162306a36Sopenharmony_ci struct irdma_aeqe_info *info) 179262306a36Sopenharmony_ci{ 179362306a36Sopenharmony_ci u8 *pkt = qp->q2_buf + Q2_BAD_FRAME_OFFSET; 179462306a36Sopenharmony_ci __be32 *mpa; 179562306a36Sopenharmony_ci u8 ddp_ctl; 179662306a36Sopenharmony_ci u8 rdma_ctl; 179762306a36Sopenharmony_ci u16 aeq_id = 0; 179862306a36Sopenharmony_ci struct irdma_terminate_hdr *termhdr; 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci mpa = (__be32 *)irdma_locate_mpa(pkt); 180162306a36Sopenharmony_ci if (info->q2_data_written) { 180262306a36Sopenharmony_ci /* did not validate the frame - do it now */ 180362306a36Sopenharmony_ci ddp_ctl = (ntohl(mpa[0]) >> 8) & 0xff; 180462306a36Sopenharmony_ci rdma_ctl = ntohl(mpa[0]) & 0xff; 180562306a36Sopenharmony_ci if ((ddp_ctl & 0xc0) != 0x40) 180662306a36Sopenharmony_ci aeq_id = IRDMA_AE_LCE_QP_CATASTROPHIC; 180762306a36Sopenharmony_ci else if ((ddp_ctl & 0x03) != 1) 180862306a36Sopenharmony_ci aeq_id = IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION; 180962306a36Sopenharmony_ci else if (ntohl(mpa[2]) != 2) 181062306a36Sopenharmony_ci aeq_id = IRDMA_AE_DDP_UBE_INVALID_QN; 181162306a36Sopenharmony_ci else if (ntohl(mpa[3]) != 1) 181262306a36Sopenharmony_ci aeq_id = IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN; 181362306a36Sopenharmony_ci else if (ntohl(mpa[4]) != 0) 181462306a36Sopenharmony_ci aeq_id = IRDMA_AE_DDP_UBE_INVALID_MO; 181562306a36Sopenharmony_ci else if ((rdma_ctl & 0xc0) != 0x40) 181662306a36Sopenharmony_ci aeq_id = IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION; 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_ci info->ae_id = aeq_id; 181962306a36Sopenharmony_ci if (info->ae_id) { 182062306a36Sopenharmony_ci /* Bad terminate recvd - send back a terminate */ 182162306a36Sopenharmony_ci irdma_terminate_connection(qp, info); 182262306a36Sopenharmony_ci return; 182362306a36Sopenharmony_ci } 182462306a36Sopenharmony_ci } 182562306a36Sopenharmony_ci 182662306a36Sopenharmony_ci qp->term_flags |= IRDMA_TERM_RCVD; 182762306a36Sopenharmony_ci qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; 182862306a36Sopenharmony_ci termhdr = (struct irdma_terminate_hdr *)&mpa[5]; 182962306a36Sopenharmony_ci if (termhdr->layer_etype == RDMAP_REMOTE_PROT || 183062306a36Sopenharmony_ci termhdr->layer_etype == RDMAP_REMOTE_OP) { 183162306a36Sopenharmony_ci irdma_terminate_done(qp, 0); 183262306a36Sopenharmony_ci } else { 183362306a36Sopenharmony_ci irdma_terminate_start_timer(qp); 183462306a36Sopenharmony_ci irdma_terminate_send_fin(qp); 183562306a36Sopenharmony_ci } 183662306a36Sopenharmony_ci} 183762306a36Sopenharmony_ci 183862306a36Sopenharmony_cistatic int irdma_null_ws_add(struct irdma_sc_vsi *vsi, u8 user_pri) 183962306a36Sopenharmony_ci{ 184062306a36Sopenharmony_ci return 0; 184162306a36Sopenharmony_ci} 184262306a36Sopenharmony_ci 184362306a36Sopenharmony_cistatic void irdma_null_ws_remove(struct irdma_sc_vsi *vsi, u8 user_pri) 184462306a36Sopenharmony_ci{ 184562306a36Sopenharmony_ci /* do nothing */ 184662306a36Sopenharmony_ci} 184762306a36Sopenharmony_ci 184862306a36Sopenharmony_cistatic void irdma_null_ws_reset(struct irdma_sc_vsi *vsi) 184962306a36Sopenharmony_ci{ 185062306a36Sopenharmony_ci /* do nothing */ 185162306a36Sopenharmony_ci} 185262306a36Sopenharmony_ci 185362306a36Sopenharmony_ci/** 185462306a36Sopenharmony_ci * irdma_sc_vsi_init - Init the vsi structure 185562306a36Sopenharmony_ci * @vsi: pointer to vsi structure to initialize 185662306a36Sopenharmony_ci * @info: the info used to initialize the vsi struct 185762306a36Sopenharmony_ci */ 185862306a36Sopenharmony_civoid irdma_sc_vsi_init(struct irdma_sc_vsi *vsi, 185962306a36Sopenharmony_ci struct irdma_vsi_init_info *info) 186062306a36Sopenharmony_ci{ 186162306a36Sopenharmony_ci int i; 186262306a36Sopenharmony_ci 186362306a36Sopenharmony_ci vsi->dev = info->dev; 186462306a36Sopenharmony_ci vsi->back_vsi = info->back_vsi; 186562306a36Sopenharmony_ci vsi->register_qset = info->register_qset; 186662306a36Sopenharmony_ci vsi->unregister_qset = info->unregister_qset; 186762306a36Sopenharmony_ci vsi->mtu = info->params->mtu; 186862306a36Sopenharmony_ci vsi->exception_lan_q = info->exception_lan_q; 186962306a36Sopenharmony_ci vsi->vsi_idx = info->pf_data_vsi_num; 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci irdma_set_qos_info(vsi, info->params); 187262306a36Sopenharmony_ci for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) { 187362306a36Sopenharmony_ci mutex_init(&vsi->qos[i].qos_mutex); 187462306a36Sopenharmony_ci INIT_LIST_HEAD(&vsi->qos[i].qplist); 187562306a36Sopenharmony_ci } 187662306a36Sopenharmony_ci if (vsi->register_qset) { 187762306a36Sopenharmony_ci vsi->dev->ws_add = irdma_ws_add; 187862306a36Sopenharmony_ci vsi->dev->ws_remove = irdma_ws_remove; 187962306a36Sopenharmony_ci vsi->dev->ws_reset = irdma_ws_reset; 188062306a36Sopenharmony_ci } else { 188162306a36Sopenharmony_ci vsi->dev->ws_add = irdma_null_ws_add; 188262306a36Sopenharmony_ci vsi->dev->ws_remove = irdma_null_ws_remove; 188362306a36Sopenharmony_ci vsi->dev->ws_reset = irdma_null_ws_reset; 188462306a36Sopenharmony_ci } 188562306a36Sopenharmony_ci} 188662306a36Sopenharmony_ci 188762306a36Sopenharmony_ci/** 188862306a36Sopenharmony_ci * irdma_get_stats_idx - Return stats index 188962306a36Sopenharmony_ci * @vsi: pointer to the vsi 189062306a36Sopenharmony_ci */ 189162306a36Sopenharmony_cistatic u8 irdma_get_stats_idx(struct irdma_sc_vsi *vsi) 189262306a36Sopenharmony_ci{ 189362306a36Sopenharmony_ci struct irdma_stats_inst_info stats_info = {}; 189462306a36Sopenharmony_ci struct irdma_sc_dev *dev = vsi->dev; 189562306a36Sopenharmony_ci u8 i; 189662306a36Sopenharmony_ci 189762306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 189862306a36Sopenharmony_ci if (!irdma_cqp_stats_inst_cmd(vsi, IRDMA_OP_STATS_ALLOCATE, 189962306a36Sopenharmony_ci &stats_info)) 190062306a36Sopenharmony_ci return stats_info.stats_idx; 190162306a36Sopenharmony_ci } 190262306a36Sopenharmony_ci 190362306a36Sopenharmony_ci for (i = 0; i < IRDMA_MAX_STATS_COUNT_GEN_1; i++) { 190462306a36Sopenharmony_ci if (!dev->stats_idx_array[i]) { 190562306a36Sopenharmony_ci dev->stats_idx_array[i] = true; 190662306a36Sopenharmony_ci return i; 190762306a36Sopenharmony_ci } 190862306a36Sopenharmony_ci } 190962306a36Sopenharmony_ci 191062306a36Sopenharmony_ci return IRDMA_INVALID_STATS_IDX; 191162306a36Sopenharmony_ci} 191262306a36Sopenharmony_ci 191362306a36Sopenharmony_ci/** 191462306a36Sopenharmony_ci * irdma_hw_stats_init_gen1 - Initialize stat reg table used for gen1 191562306a36Sopenharmony_ci * @vsi: vsi structure where hw_regs are set 191662306a36Sopenharmony_ci * 191762306a36Sopenharmony_ci * Populate the HW stats table 191862306a36Sopenharmony_ci */ 191962306a36Sopenharmony_cistatic void irdma_hw_stats_init_gen1(struct irdma_sc_vsi *vsi) 192062306a36Sopenharmony_ci{ 192162306a36Sopenharmony_ci struct irdma_sc_dev *dev = vsi->dev; 192262306a36Sopenharmony_ci const struct irdma_hw_stat_map *map; 192362306a36Sopenharmony_ci u64 *stat_reg = vsi->hw_stats_regs; 192462306a36Sopenharmony_ci u64 *regs = dev->hw_stats_regs; 192562306a36Sopenharmony_ci u16 i, stats_reg_set = vsi->stats_idx; 192662306a36Sopenharmony_ci 192762306a36Sopenharmony_ci map = dev->hw_stats_map; 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci /* First 4 stat instances are reserved for port level statistics. */ 193062306a36Sopenharmony_ci stats_reg_set += vsi->stats_inst_alloc ? IRDMA_FIRST_NON_PF_STAT : 0; 193162306a36Sopenharmony_ci 193262306a36Sopenharmony_ci for (i = 0; i < dev->hw_attrs.max_stat_idx; i++) { 193362306a36Sopenharmony_ci if (map[i].bitmask <= IRDMA_MAX_STATS_32) 193462306a36Sopenharmony_ci stat_reg[i] = regs[i] + stats_reg_set * sizeof(u32); 193562306a36Sopenharmony_ci else 193662306a36Sopenharmony_ci stat_reg[i] = regs[i] + stats_reg_set * sizeof(u64); 193762306a36Sopenharmony_ci } 193862306a36Sopenharmony_ci} 193962306a36Sopenharmony_ci 194062306a36Sopenharmony_ci/** 194162306a36Sopenharmony_ci * irdma_vsi_stats_init - Initialize the vsi statistics 194262306a36Sopenharmony_ci * @vsi: pointer to the vsi structure 194362306a36Sopenharmony_ci * @info: The info structure used for initialization 194462306a36Sopenharmony_ci */ 194562306a36Sopenharmony_ciint irdma_vsi_stats_init(struct irdma_sc_vsi *vsi, 194662306a36Sopenharmony_ci struct irdma_vsi_stats_info *info) 194762306a36Sopenharmony_ci{ 194862306a36Sopenharmony_ci struct irdma_dma_mem *stats_buff_mem; 194962306a36Sopenharmony_ci 195062306a36Sopenharmony_ci vsi->pestat = info->pestat; 195162306a36Sopenharmony_ci vsi->pestat->hw = vsi->dev->hw; 195262306a36Sopenharmony_ci vsi->pestat->vsi = vsi; 195362306a36Sopenharmony_ci stats_buff_mem = &vsi->pestat->gather_info.stats_buff_mem; 195462306a36Sopenharmony_ci stats_buff_mem->size = ALIGN(IRDMA_GATHER_STATS_BUF_SIZE * 2, 1); 195562306a36Sopenharmony_ci stats_buff_mem->va = dma_alloc_coherent(vsi->pestat->hw->device, 195662306a36Sopenharmony_ci stats_buff_mem->size, 195762306a36Sopenharmony_ci &stats_buff_mem->pa, 195862306a36Sopenharmony_ci GFP_KERNEL); 195962306a36Sopenharmony_ci if (!stats_buff_mem->va) 196062306a36Sopenharmony_ci return -ENOMEM; 196162306a36Sopenharmony_ci 196262306a36Sopenharmony_ci vsi->pestat->gather_info.gather_stats_va = stats_buff_mem->va; 196362306a36Sopenharmony_ci vsi->pestat->gather_info.last_gather_stats_va = 196462306a36Sopenharmony_ci (void *)((uintptr_t)stats_buff_mem->va + 196562306a36Sopenharmony_ci IRDMA_GATHER_STATS_BUF_SIZE); 196662306a36Sopenharmony_ci 196762306a36Sopenharmony_ci irdma_hw_stats_start_timer(vsi); 196862306a36Sopenharmony_ci 196962306a36Sopenharmony_ci /* when stat allocation is not required default to fcn_id. */ 197062306a36Sopenharmony_ci vsi->stats_idx = info->fcn_id; 197162306a36Sopenharmony_ci if (info->alloc_stats_inst) { 197262306a36Sopenharmony_ci u8 stats_idx = irdma_get_stats_idx(vsi); 197362306a36Sopenharmony_ci 197462306a36Sopenharmony_ci if (stats_idx != IRDMA_INVALID_STATS_IDX) { 197562306a36Sopenharmony_ci vsi->stats_inst_alloc = true; 197662306a36Sopenharmony_ci vsi->stats_idx = stats_idx; 197762306a36Sopenharmony_ci vsi->pestat->gather_info.use_stats_inst = true; 197862306a36Sopenharmony_ci vsi->pestat->gather_info.stats_inst_index = stats_idx; 197962306a36Sopenharmony_ci } 198062306a36Sopenharmony_ci } 198162306a36Sopenharmony_ci 198262306a36Sopenharmony_ci if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) 198362306a36Sopenharmony_ci irdma_hw_stats_init_gen1(vsi); 198462306a36Sopenharmony_ci 198562306a36Sopenharmony_ci return 0; 198662306a36Sopenharmony_ci} 198762306a36Sopenharmony_ci 198862306a36Sopenharmony_ci/** 198962306a36Sopenharmony_ci * irdma_vsi_stats_free - Free the vsi stats 199062306a36Sopenharmony_ci * @vsi: pointer to the vsi structure 199162306a36Sopenharmony_ci */ 199262306a36Sopenharmony_civoid irdma_vsi_stats_free(struct irdma_sc_vsi *vsi) 199362306a36Sopenharmony_ci{ 199462306a36Sopenharmony_ci struct irdma_stats_inst_info stats_info = {}; 199562306a36Sopenharmony_ci struct irdma_sc_dev *dev = vsi->dev; 199662306a36Sopenharmony_ci u8 stats_idx = vsi->stats_idx; 199762306a36Sopenharmony_ci 199862306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 199962306a36Sopenharmony_ci if (vsi->stats_inst_alloc) { 200062306a36Sopenharmony_ci stats_info.stats_idx = vsi->stats_idx; 200162306a36Sopenharmony_ci irdma_cqp_stats_inst_cmd(vsi, IRDMA_OP_STATS_FREE, 200262306a36Sopenharmony_ci &stats_info); 200362306a36Sopenharmony_ci } 200462306a36Sopenharmony_ci } else { 200562306a36Sopenharmony_ci if (vsi->stats_inst_alloc && 200662306a36Sopenharmony_ci stats_idx < vsi->dev->hw_attrs.max_stat_inst) 200762306a36Sopenharmony_ci vsi->dev->stats_idx_array[stats_idx] = false; 200862306a36Sopenharmony_ci } 200962306a36Sopenharmony_ci 201062306a36Sopenharmony_ci if (!vsi->pestat) 201162306a36Sopenharmony_ci return; 201262306a36Sopenharmony_ci irdma_hw_stats_stop_timer(vsi); 201362306a36Sopenharmony_ci dma_free_coherent(vsi->pestat->hw->device, 201462306a36Sopenharmony_ci vsi->pestat->gather_info.stats_buff_mem.size, 201562306a36Sopenharmony_ci vsi->pestat->gather_info.stats_buff_mem.va, 201662306a36Sopenharmony_ci vsi->pestat->gather_info.stats_buff_mem.pa); 201762306a36Sopenharmony_ci vsi->pestat->gather_info.stats_buff_mem.va = NULL; 201862306a36Sopenharmony_ci} 201962306a36Sopenharmony_ci 202062306a36Sopenharmony_ci/** 202162306a36Sopenharmony_ci * irdma_get_encoded_wqe_size - given wq size, returns hardware encoded size 202262306a36Sopenharmony_ci * @wqsize: size of the wq (sq, rq) to encoded_size 202362306a36Sopenharmony_ci * @queue_type: queue type selected for the calculation algorithm 202462306a36Sopenharmony_ci */ 202562306a36Sopenharmony_ciu8 irdma_get_encoded_wqe_size(u32 wqsize, enum irdma_queue_type queue_type) 202662306a36Sopenharmony_ci{ 202762306a36Sopenharmony_ci u8 encoded_size = 0; 202862306a36Sopenharmony_ci 202962306a36Sopenharmony_ci /* cqp sq's hw coded value starts from 1 for size of 4 203062306a36Sopenharmony_ci * while it starts from 0 for qp' wq's. 203162306a36Sopenharmony_ci */ 203262306a36Sopenharmony_ci if (queue_type == IRDMA_QUEUE_TYPE_CQP) 203362306a36Sopenharmony_ci encoded_size = 1; 203462306a36Sopenharmony_ci wqsize >>= 2; 203562306a36Sopenharmony_ci while (wqsize >>= 1) 203662306a36Sopenharmony_ci encoded_size++; 203762306a36Sopenharmony_ci 203862306a36Sopenharmony_ci return encoded_size; 203962306a36Sopenharmony_ci} 204062306a36Sopenharmony_ci 204162306a36Sopenharmony_ci/** 204262306a36Sopenharmony_ci * irdma_sc_gather_stats - collect the statistics 204362306a36Sopenharmony_ci * @cqp: struct for cqp hw 204462306a36Sopenharmony_ci * @info: gather stats info structure 204562306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 204662306a36Sopenharmony_ci */ 204762306a36Sopenharmony_cistatic int irdma_sc_gather_stats(struct irdma_sc_cqp *cqp, 204862306a36Sopenharmony_ci struct irdma_stats_gather_info *info, 204962306a36Sopenharmony_ci u64 scratch) 205062306a36Sopenharmony_ci{ 205162306a36Sopenharmony_ci __le64 *wqe; 205262306a36Sopenharmony_ci u64 temp; 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_ci if (info->stats_buff_mem.size < IRDMA_GATHER_STATS_BUF_SIZE) 205562306a36Sopenharmony_ci return -ENOMEM; 205662306a36Sopenharmony_ci 205762306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 205862306a36Sopenharmony_ci if (!wqe) 205962306a36Sopenharmony_ci return -ENOMEM; 206062306a36Sopenharmony_ci 206162306a36Sopenharmony_ci set_64bit_val(wqe, 40, 206262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_HMC_FCN_INDEX, info->hmc_fcn_index)); 206362306a36Sopenharmony_ci set_64bit_val(wqe, 32, info->stats_buff_mem.pa); 206462306a36Sopenharmony_ci 206562306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPSQ_STATS_WQEVALID, cqp->polarity) | 206662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_USE_INST, info->use_stats_inst) | 206762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_INST_INDEX, 206862306a36Sopenharmony_ci info->stats_inst_index) | 206962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_USE_HMC_FCN_INDEX, 207062306a36Sopenharmony_ci info->use_hmc_fcn_index) | 207162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_OP, IRDMA_CQP_OP_GATHER_STATS); 207262306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 207362306a36Sopenharmony_ci 207462306a36Sopenharmony_ci set_64bit_val(wqe, 24, temp); 207562306a36Sopenharmony_ci 207662306a36Sopenharmony_ci print_hex_dump_debug("STATS: GATHER_STATS WQE", DUMP_PREFIX_OFFSET, 207762306a36Sopenharmony_ci 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 208062306a36Sopenharmony_ci ibdev_dbg(to_ibdev(cqp->dev), 208162306a36Sopenharmony_ci "STATS: CQP SQ head 0x%x tail 0x%x size 0x%x\n", 208262306a36Sopenharmony_ci cqp->sq_ring.head, cqp->sq_ring.tail, cqp->sq_ring.size); 208362306a36Sopenharmony_ci 208462306a36Sopenharmony_ci return 0; 208562306a36Sopenharmony_ci} 208662306a36Sopenharmony_ci 208762306a36Sopenharmony_ci/** 208862306a36Sopenharmony_ci * irdma_sc_manage_stats_inst - allocate or free stats instance 208962306a36Sopenharmony_ci * @cqp: struct for cqp hw 209062306a36Sopenharmony_ci * @info: stats info structure 209162306a36Sopenharmony_ci * @alloc: alloc vs. delete flag 209262306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 209362306a36Sopenharmony_ci */ 209462306a36Sopenharmony_cistatic int irdma_sc_manage_stats_inst(struct irdma_sc_cqp *cqp, 209562306a36Sopenharmony_ci struct irdma_stats_inst_info *info, 209662306a36Sopenharmony_ci bool alloc, u64 scratch) 209762306a36Sopenharmony_ci{ 209862306a36Sopenharmony_ci __le64 *wqe; 209962306a36Sopenharmony_ci u64 temp; 210062306a36Sopenharmony_ci 210162306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 210262306a36Sopenharmony_ci if (!wqe) 210362306a36Sopenharmony_ci return -ENOMEM; 210462306a36Sopenharmony_ci 210562306a36Sopenharmony_ci set_64bit_val(wqe, 40, 210662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_HMC_FCN_INDEX, info->hmc_fn_id)); 210762306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPSQ_STATS_WQEVALID, cqp->polarity) | 210862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_ALLOC_INST, alloc) | 210962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_USE_HMC_FCN_INDEX, 211062306a36Sopenharmony_ci info->use_hmc_fcn_index) | 211162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_INST_INDEX, info->stats_idx) | 211262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_STATS_OP, IRDMA_CQP_OP_MANAGE_STATS); 211362306a36Sopenharmony_ci 211462306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 211562306a36Sopenharmony_ci 211662306a36Sopenharmony_ci set_64bit_val(wqe, 24, temp); 211762306a36Sopenharmony_ci 211862306a36Sopenharmony_ci print_hex_dump_debug("WQE: MANAGE_STATS WQE", DUMP_PREFIX_OFFSET, 16, 211962306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 212062306a36Sopenharmony_ci 212162306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 212262306a36Sopenharmony_ci return 0; 212362306a36Sopenharmony_ci} 212462306a36Sopenharmony_ci 212562306a36Sopenharmony_ci/** 212662306a36Sopenharmony_ci * irdma_sc_set_up_map - set the up map table 212762306a36Sopenharmony_ci * @cqp: struct for cqp hw 212862306a36Sopenharmony_ci * @info: User priority map info 212962306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 213062306a36Sopenharmony_ci */ 213162306a36Sopenharmony_cistatic int irdma_sc_set_up_map(struct irdma_sc_cqp *cqp, 213262306a36Sopenharmony_ci struct irdma_up_info *info, u64 scratch) 213362306a36Sopenharmony_ci{ 213462306a36Sopenharmony_ci __le64 *wqe; 213562306a36Sopenharmony_ci u64 temp = 0; 213662306a36Sopenharmony_ci int i; 213762306a36Sopenharmony_ci 213862306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 213962306a36Sopenharmony_ci if (!wqe) 214062306a36Sopenharmony_ci return -ENOMEM; 214162306a36Sopenharmony_ci 214262306a36Sopenharmony_ci for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) 214362306a36Sopenharmony_ci temp |= (u64)info->map[i] << (i * 8); 214462306a36Sopenharmony_ci 214562306a36Sopenharmony_ci set_64bit_val(wqe, 0, temp); 214662306a36Sopenharmony_ci set_64bit_val(wqe, 40, 214762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UP_CNPOVERRIDE, info->cnp_up_override) | 214862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UP_HMCFCNIDX, info->hmc_fcn_idx)); 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPSQ_UP_WQEVALID, cqp->polarity) | 215162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UP_USEVLAN, info->use_vlan) | 215262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UP_USEOVERRIDE, 215362306a36Sopenharmony_ci info->use_cnp_up_override) | 215462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UP_OP, IRDMA_CQP_OP_UP_MAP); 215562306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 215662306a36Sopenharmony_ci 215762306a36Sopenharmony_ci set_64bit_val(wqe, 24, temp); 215862306a36Sopenharmony_ci 215962306a36Sopenharmony_ci print_hex_dump_debug("WQE: UPMAP WQE", DUMP_PREFIX_OFFSET, 16, 8, wqe, 216062306a36Sopenharmony_ci IRDMA_CQP_WQE_SIZE * 8, false); 216162306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 216262306a36Sopenharmony_ci 216362306a36Sopenharmony_ci return 0; 216462306a36Sopenharmony_ci} 216562306a36Sopenharmony_ci 216662306a36Sopenharmony_ci/** 216762306a36Sopenharmony_ci * irdma_sc_manage_ws_node - create/modify/destroy WS node 216862306a36Sopenharmony_ci * @cqp: struct for cqp hw 216962306a36Sopenharmony_ci * @info: node info structure 217062306a36Sopenharmony_ci * @node_op: 0 for add 1 for modify, 2 for delete 217162306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 217262306a36Sopenharmony_ci */ 217362306a36Sopenharmony_cistatic int irdma_sc_manage_ws_node(struct irdma_sc_cqp *cqp, 217462306a36Sopenharmony_ci struct irdma_ws_node_info *info, 217562306a36Sopenharmony_ci enum irdma_ws_node_op node_op, u64 scratch) 217662306a36Sopenharmony_ci{ 217762306a36Sopenharmony_ci __le64 *wqe; 217862306a36Sopenharmony_ci u64 temp = 0; 217962306a36Sopenharmony_ci 218062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 218162306a36Sopenharmony_ci if (!wqe) 218262306a36Sopenharmony_ci return -ENOMEM; 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_ci set_64bit_val(wqe, 32, 218562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_VSI, info->vsi) | 218662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_WEIGHT, info->weight)); 218762306a36Sopenharmony_ci 218862306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPSQ_WS_WQEVALID, cqp->polarity) | 218962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_NODEOP, node_op) | 219062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_ENABLENODE, info->enable) | 219162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_NODETYPE, info->type_leaf) | 219262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_PRIOTYPE, info->prio_type) | 219362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_TC, info->tc) | 219462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_OP, IRDMA_CQP_OP_WORK_SCHED_NODE) | 219562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_PARENTID, info->parent_id) | 219662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WS_NODEID, info->id); 219762306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 219862306a36Sopenharmony_ci 219962306a36Sopenharmony_ci set_64bit_val(wqe, 24, temp); 220062306a36Sopenharmony_ci 220162306a36Sopenharmony_ci print_hex_dump_debug("WQE: MANAGE_WS WQE", DUMP_PREFIX_OFFSET, 16, 8, 220262306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 220362306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 220462306a36Sopenharmony_ci 220562306a36Sopenharmony_ci return 0; 220662306a36Sopenharmony_ci} 220762306a36Sopenharmony_ci 220862306a36Sopenharmony_ci/** 220962306a36Sopenharmony_ci * irdma_sc_qp_flush_wqes - flush qp's wqe 221062306a36Sopenharmony_ci * @qp: sc qp 221162306a36Sopenharmony_ci * @info: dlush information 221262306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 221362306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 221462306a36Sopenharmony_ci */ 221562306a36Sopenharmony_ciint irdma_sc_qp_flush_wqes(struct irdma_sc_qp *qp, 221662306a36Sopenharmony_ci struct irdma_qp_flush_info *info, u64 scratch, 221762306a36Sopenharmony_ci bool post_sq) 221862306a36Sopenharmony_ci{ 221962306a36Sopenharmony_ci u64 temp = 0; 222062306a36Sopenharmony_ci __le64 *wqe; 222162306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 222262306a36Sopenharmony_ci u64 hdr; 222362306a36Sopenharmony_ci bool flush_sq = false, flush_rq = false; 222462306a36Sopenharmony_ci 222562306a36Sopenharmony_ci if (info->rq && !qp->flush_rq) 222662306a36Sopenharmony_ci flush_rq = true; 222762306a36Sopenharmony_ci if (info->sq && !qp->flush_sq) 222862306a36Sopenharmony_ci flush_sq = true; 222962306a36Sopenharmony_ci qp->flush_sq |= flush_sq; 223062306a36Sopenharmony_ci qp->flush_rq |= flush_rq; 223162306a36Sopenharmony_ci 223262306a36Sopenharmony_ci if (!flush_sq && !flush_rq) { 223362306a36Sopenharmony_ci ibdev_dbg(to_ibdev(qp->dev), 223462306a36Sopenharmony_ci "CQP: Additional flush request ignored for qp %x\n", 223562306a36Sopenharmony_ci qp->qp_uk.qp_id); 223662306a36Sopenharmony_ci return -EALREADY; 223762306a36Sopenharmony_ci } 223862306a36Sopenharmony_ci 223962306a36Sopenharmony_ci cqp = qp->pd->dev->cqp; 224062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 224162306a36Sopenharmony_ci if (!wqe) 224262306a36Sopenharmony_ci return -ENOMEM; 224362306a36Sopenharmony_ci 224462306a36Sopenharmony_ci if (info->userflushcode) { 224562306a36Sopenharmony_ci if (flush_rq) 224662306a36Sopenharmony_ci temp |= FIELD_PREP(IRDMA_CQPSQ_FWQE_RQMNERR, 224762306a36Sopenharmony_ci info->rq_minor_code) | 224862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_FWQE_RQMJERR, 224962306a36Sopenharmony_ci info->rq_major_code); 225062306a36Sopenharmony_ci if (flush_sq) 225162306a36Sopenharmony_ci temp |= FIELD_PREP(IRDMA_CQPSQ_FWQE_SQMNERR, 225262306a36Sopenharmony_ci info->sq_minor_code) | 225362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_FWQE_SQMJERR, 225462306a36Sopenharmony_ci info->sq_major_code); 225562306a36Sopenharmony_ci } 225662306a36Sopenharmony_ci set_64bit_val(wqe, 16, temp); 225762306a36Sopenharmony_ci 225862306a36Sopenharmony_ci temp = (info->generate_ae) ? 225962306a36Sopenharmony_ci info->ae_code | FIELD_PREP(IRDMA_CQPSQ_FWQE_AESOURCE, 226062306a36Sopenharmony_ci info->ae_src) : 0; 226162306a36Sopenharmony_ci set_64bit_val(wqe, 8, temp); 226262306a36Sopenharmony_ci 226362306a36Sopenharmony_ci hdr = qp->qp_uk.qp_id | 226462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_FLUSH_WQES) | 226562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_FWQE_GENERATE_AE, info->generate_ae) | 226662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_FWQE_USERFLCODE, info->userflushcode) | 226762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_FWQE_FLUSHSQ, flush_sq) | 226862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_FWQE_FLUSHRQ, flush_rq) | 226962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 227062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 227162306a36Sopenharmony_ci 227262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 227362306a36Sopenharmony_ci 227462306a36Sopenharmony_ci print_hex_dump_debug("WQE: QP_FLUSH WQE", DUMP_PREFIX_OFFSET, 16, 8, 227562306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 227662306a36Sopenharmony_ci if (post_sq) 227762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 227862306a36Sopenharmony_ci 227962306a36Sopenharmony_ci return 0; 228062306a36Sopenharmony_ci} 228162306a36Sopenharmony_ci 228262306a36Sopenharmony_ci/** 228362306a36Sopenharmony_ci * irdma_sc_gen_ae - generate AE, uses flush WQE CQP OP 228462306a36Sopenharmony_ci * @qp: sc qp 228562306a36Sopenharmony_ci * @info: gen ae information 228662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 228762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 228862306a36Sopenharmony_ci */ 228962306a36Sopenharmony_cistatic int irdma_sc_gen_ae(struct irdma_sc_qp *qp, 229062306a36Sopenharmony_ci struct irdma_gen_ae_info *info, u64 scratch, 229162306a36Sopenharmony_ci bool post_sq) 229262306a36Sopenharmony_ci{ 229362306a36Sopenharmony_ci u64 temp; 229462306a36Sopenharmony_ci __le64 *wqe; 229562306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 229662306a36Sopenharmony_ci u64 hdr; 229762306a36Sopenharmony_ci 229862306a36Sopenharmony_ci cqp = qp->pd->dev->cqp; 229962306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 230062306a36Sopenharmony_ci if (!wqe) 230162306a36Sopenharmony_ci return -ENOMEM; 230262306a36Sopenharmony_ci 230362306a36Sopenharmony_ci temp = info->ae_code | FIELD_PREP(IRDMA_CQPSQ_FWQE_AESOURCE, 230462306a36Sopenharmony_ci info->ae_src); 230562306a36Sopenharmony_ci set_64bit_val(wqe, 8, temp); 230662306a36Sopenharmony_ci 230762306a36Sopenharmony_ci hdr = qp->qp_uk.qp_id | FIELD_PREP(IRDMA_CQPSQ_OPCODE, 230862306a36Sopenharmony_ci IRDMA_CQP_OP_GEN_AE) | 230962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_FWQE_GENERATE_AE, 1) | 231062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 231162306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 231262306a36Sopenharmony_ci 231362306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 231462306a36Sopenharmony_ci 231562306a36Sopenharmony_ci print_hex_dump_debug("WQE: GEN_AE WQE", DUMP_PREFIX_OFFSET, 16, 8, 231662306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 231762306a36Sopenharmony_ci if (post_sq) 231862306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 231962306a36Sopenharmony_ci 232062306a36Sopenharmony_ci return 0; 232162306a36Sopenharmony_ci} 232262306a36Sopenharmony_ci 232362306a36Sopenharmony_ci/*** irdma_sc_qp_upload_context - upload qp's context 232462306a36Sopenharmony_ci * @dev: sc device struct 232562306a36Sopenharmony_ci * @info: upload context info ptr for return 232662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 232762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 232862306a36Sopenharmony_ci */ 232962306a36Sopenharmony_cistatic int irdma_sc_qp_upload_context(struct irdma_sc_dev *dev, 233062306a36Sopenharmony_ci struct irdma_upload_context_info *info, 233162306a36Sopenharmony_ci u64 scratch, bool post_sq) 233262306a36Sopenharmony_ci{ 233362306a36Sopenharmony_ci __le64 *wqe; 233462306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 233562306a36Sopenharmony_ci u64 hdr; 233662306a36Sopenharmony_ci 233762306a36Sopenharmony_ci cqp = dev->cqp; 233862306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 233962306a36Sopenharmony_ci if (!wqe) 234062306a36Sopenharmony_ci return -ENOMEM; 234162306a36Sopenharmony_ci 234262306a36Sopenharmony_ci set_64bit_val(wqe, 16, info->buf_pa); 234362306a36Sopenharmony_ci 234462306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_UCTX_QPID, info->qp_id) | 234562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_UPLOAD_CONTEXT) | 234662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UCTX_QPTYPE, info->qp_type) | 234762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UCTX_RAWFORMAT, info->raw_format) | 234862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UCTX_FREEZEQP, info->freeze_qp) | 234962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 235062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 235162306a36Sopenharmony_ci 235262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 235362306a36Sopenharmony_ci 235462306a36Sopenharmony_ci print_hex_dump_debug("WQE: QP_UPLOAD_CTX WQE", DUMP_PREFIX_OFFSET, 16, 235562306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 235662306a36Sopenharmony_ci if (post_sq) 235762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 235862306a36Sopenharmony_ci 235962306a36Sopenharmony_ci return 0; 236062306a36Sopenharmony_ci} 236162306a36Sopenharmony_ci 236262306a36Sopenharmony_ci/** 236362306a36Sopenharmony_ci * irdma_sc_manage_push_page - Handle push page 236462306a36Sopenharmony_ci * @cqp: struct for cqp hw 236562306a36Sopenharmony_ci * @info: push page info 236662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 236762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 236862306a36Sopenharmony_ci */ 236962306a36Sopenharmony_cistatic int irdma_sc_manage_push_page(struct irdma_sc_cqp *cqp, 237062306a36Sopenharmony_ci struct irdma_cqp_manage_push_page_info *info, 237162306a36Sopenharmony_ci u64 scratch, bool post_sq) 237262306a36Sopenharmony_ci{ 237362306a36Sopenharmony_ci __le64 *wqe; 237462306a36Sopenharmony_ci u64 hdr; 237562306a36Sopenharmony_ci 237662306a36Sopenharmony_ci if (info->free_page && 237762306a36Sopenharmony_ci info->push_idx >= cqp->dev->hw_attrs.max_hw_device_pages) 237862306a36Sopenharmony_ci return -EINVAL; 237962306a36Sopenharmony_ci 238062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 238162306a36Sopenharmony_ci if (!wqe) 238262306a36Sopenharmony_ci return -ENOMEM; 238362306a36Sopenharmony_ci 238462306a36Sopenharmony_ci set_64bit_val(wqe, 16, info->qs_handle); 238562306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_MPP_PPIDX, info->push_idx) | 238662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_MPP_PPTYPE, info->push_page_type) | 238762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MANAGE_PUSH_PAGES) | 238862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity) | 238962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_MPP_FREE_PAGE, info->free_page); 239062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 239162306a36Sopenharmony_ci 239262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 239362306a36Sopenharmony_ci 239462306a36Sopenharmony_ci print_hex_dump_debug("WQE: MANAGE_PUSH_PAGES WQE", DUMP_PREFIX_OFFSET, 239562306a36Sopenharmony_ci 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 239662306a36Sopenharmony_ci if (post_sq) 239762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 239862306a36Sopenharmony_ci 239962306a36Sopenharmony_ci return 0; 240062306a36Sopenharmony_ci} 240162306a36Sopenharmony_ci 240262306a36Sopenharmony_ci/** 240362306a36Sopenharmony_ci * irdma_sc_suspend_qp - suspend qp for param change 240462306a36Sopenharmony_ci * @cqp: struct for cqp hw 240562306a36Sopenharmony_ci * @qp: sc qp struct 240662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 240762306a36Sopenharmony_ci */ 240862306a36Sopenharmony_cistatic int irdma_sc_suspend_qp(struct irdma_sc_cqp *cqp, struct irdma_sc_qp *qp, 240962306a36Sopenharmony_ci u64 scratch) 241062306a36Sopenharmony_ci{ 241162306a36Sopenharmony_ci u64 hdr; 241262306a36Sopenharmony_ci __le64 *wqe; 241362306a36Sopenharmony_ci 241462306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 241562306a36Sopenharmony_ci if (!wqe) 241662306a36Sopenharmony_ci return -ENOMEM; 241762306a36Sopenharmony_ci 241862306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_SUSPENDQP_QPID, qp->qp_uk.qp_id) | 241962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_SUSPEND_QP) | 242062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 242162306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 242262306a36Sopenharmony_ci 242362306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 242462306a36Sopenharmony_ci 242562306a36Sopenharmony_ci print_hex_dump_debug("WQE: SUSPEND_QP WQE", DUMP_PREFIX_OFFSET, 16, 8, 242662306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 242762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 242862306a36Sopenharmony_ci 242962306a36Sopenharmony_ci return 0; 243062306a36Sopenharmony_ci} 243162306a36Sopenharmony_ci 243262306a36Sopenharmony_ci/** 243362306a36Sopenharmony_ci * irdma_sc_resume_qp - resume qp after suspend 243462306a36Sopenharmony_ci * @cqp: struct for cqp hw 243562306a36Sopenharmony_ci * @qp: sc qp struct 243662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 243762306a36Sopenharmony_ci */ 243862306a36Sopenharmony_cistatic int irdma_sc_resume_qp(struct irdma_sc_cqp *cqp, struct irdma_sc_qp *qp, 243962306a36Sopenharmony_ci u64 scratch) 244062306a36Sopenharmony_ci{ 244162306a36Sopenharmony_ci u64 hdr; 244262306a36Sopenharmony_ci __le64 *wqe; 244362306a36Sopenharmony_ci 244462306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 244562306a36Sopenharmony_ci if (!wqe) 244662306a36Sopenharmony_ci return -ENOMEM; 244762306a36Sopenharmony_ci 244862306a36Sopenharmony_ci set_64bit_val(wqe, 16, 244962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_RESUMEQP_QSHANDLE, qp->qs_handle)); 245062306a36Sopenharmony_ci 245162306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_RESUMEQP_QPID, qp->qp_uk.qp_id) | 245262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_RESUME_QP) | 245362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 245462306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 245562306a36Sopenharmony_ci 245662306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 245762306a36Sopenharmony_ci 245862306a36Sopenharmony_ci print_hex_dump_debug("WQE: RESUME_QP WQE", DUMP_PREFIX_OFFSET, 16, 8, 245962306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 246062306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 246162306a36Sopenharmony_ci 246262306a36Sopenharmony_ci return 0; 246362306a36Sopenharmony_ci} 246462306a36Sopenharmony_ci 246562306a36Sopenharmony_ci/** 246662306a36Sopenharmony_ci * irdma_sc_cq_ack - acknowledge completion q 246762306a36Sopenharmony_ci * @cq: cq struct 246862306a36Sopenharmony_ci */ 246962306a36Sopenharmony_cistatic inline void irdma_sc_cq_ack(struct irdma_sc_cq *cq) 247062306a36Sopenharmony_ci{ 247162306a36Sopenharmony_ci writel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db); 247262306a36Sopenharmony_ci} 247362306a36Sopenharmony_ci 247462306a36Sopenharmony_ci/** 247562306a36Sopenharmony_ci * irdma_sc_cq_init - initialize completion q 247662306a36Sopenharmony_ci * @cq: cq struct 247762306a36Sopenharmony_ci * @info: cq initialization info 247862306a36Sopenharmony_ci */ 247962306a36Sopenharmony_ciint irdma_sc_cq_init(struct irdma_sc_cq *cq, struct irdma_cq_init_info *info) 248062306a36Sopenharmony_ci{ 248162306a36Sopenharmony_ci u32 pble_obj_cnt; 248262306a36Sopenharmony_ci 248362306a36Sopenharmony_ci pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt; 248462306a36Sopenharmony_ci if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt) 248562306a36Sopenharmony_ci return -EINVAL; 248662306a36Sopenharmony_ci 248762306a36Sopenharmony_ci cq->cq_pa = info->cq_base_pa; 248862306a36Sopenharmony_ci cq->dev = info->dev; 248962306a36Sopenharmony_ci cq->ceq_id = info->ceq_id; 249062306a36Sopenharmony_ci info->cq_uk_init_info.cqe_alloc_db = cq->dev->cq_arm_db; 249162306a36Sopenharmony_ci info->cq_uk_init_info.cq_ack_db = cq->dev->cq_ack_db; 249262306a36Sopenharmony_ci irdma_uk_cq_init(&cq->cq_uk, &info->cq_uk_init_info); 249362306a36Sopenharmony_ci 249462306a36Sopenharmony_ci cq->virtual_map = info->virtual_map; 249562306a36Sopenharmony_ci cq->pbl_chunk_size = info->pbl_chunk_size; 249662306a36Sopenharmony_ci cq->ceqe_mask = info->ceqe_mask; 249762306a36Sopenharmony_ci cq->cq_type = (info->type) ? info->type : IRDMA_CQ_TYPE_IWARP; 249862306a36Sopenharmony_ci cq->shadow_area_pa = info->shadow_area_pa; 249962306a36Sopenharmony_ci cq->shadow_read_threshold = info->shadow_read_threshold; 250062306a36Sopenharmony_ci cq->ceq_id_valid = info->ceq_id_valid; 250162306a36Sopenharmony_ci cq->tph_en = info->tph_en; 250262306a36Sopenharmony_ci cq->tph_val = info->tph_val; 250362306a36Sopenharmony_ci cq->first_pm_pbl_idx = info->first_pm_pbl_idx; 250462306a36Sopenharmony_ci cq->vsi = info->vsi; 250562306a36Sopenharmony_ci 250662306a36Sopenharmony_ci return 0; 250762306a36Sopenharmony_ci} 250862306a36Sopenharmony_ci 250962306a36Sopenharmony_ci/** 251062306a36Sopenharmony_ci * irdma_sc_cq_create - create completion q 251162306a36Sopenharmony_ci * @cq: cq struct 251262306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 251362306a36Sopenharmony_ci * @check_overflow: flag for overflow check 251462306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 251562306a36Sopenharmony_ci */ 251662306a36Sopenharmony_cistatic int irdma_sc_cq_create(struct irdma_sc_cq *cq, u64 scratch, 251762306a36Sopenharmony_ci bool check_overflow, bool post_sq) 251862306a36Sopenharmony_ci{ 251962306a36Sopenharmony_ci __le64 *wqe; 252062306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 252162306a36Sopenharmony_ci u64 hdr; 252262306a36Sopenharmony_ci struct irdma_sc_ceq *ceq; 252362306a36Sopenharmony_ci int ret_code = 0; 252462306a36Sopenharmony_ci 252562306a36Sopenharmony_ci cqp = cq->dev->cqp; 252662306a36Sopenharmony_ci if (cq->cq_uk.cq_id >= cqp->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].max_cnt) 252762306a36Sopenharmony_ci return -EINVAL; 252862306a36Sopenharmony_ci 252962306a36Sopenharmony_ci if (cq->ceq_id >= cq->dev->hmc_fpm_misc.max_ceqs) 253062306a36Sopenharmony_ci return -EINVAL; 253162306a36Sopenharmony_ci 253262306a36Sopenharmony_ci ceq = cq->dev->ceq[cq->ceq_id]; 253362306a36Sopenharmony_ci if (ceq && ceq->reg_cq) 253462306a36Sopenharmony_ci ret_code = irdma_sc_add_cq_ctx(ceq, cq); 253562306a36Sopenharmony_ci 253662306a36Sopenharmony_ci if (ret_code) 253762306a36Sopenharmony_ci return ret_code; 253862306a36Sopenharmony_ci 253962306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 254062306a36Sopenharmony_ci if (!wqe) { 254162306a36Sopenharmony_ci if (ceq && ceq->reg_cq) 254262306a36Sopenharmony_ci irdma_sc_remove_cq_ctx(ceq, cq); 254362306a36Sopenharmony_ci return -ENOMEM; 254462306a36Sopenharmony_ci } 254562306a36Sopenharmony_ci 254662306a36Sopenharmony_ci set_64bit_val(wqe, 0, cq->cq_uk.cq_size); 254762306a36Sopenharmony_ci set_64bit_val(wqe, 8, (uintptr_t)cq >> 1); 254862306a36Sopenharmony_ci set_64bit_val(wqe, 16, 254962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD, cq->shadow_read_threshold)); 255062306a36Sopenharmony_ci set_64bit_val(wqe, 32, (cq->virtual_map ? 0 : cq->cq_pa)); 255162306a36Sopenharmony_ci set_64bit_val(wqe, 40, cq->shadow_area_pa); 255262306a36Sopenharmony_ci set_64bit_val(wqe, 48, 255362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_FIRSTPMPBLIDX, (cq->virtual_map ? cq->first_pm_pbl_idx : 0))); 255462306a36Sopenharmony_ci set_64bit_val(wqe, 56, 255562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHVAL, cq->tph_val) | 255662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_VSIIDX, cq->vsi->vsi_idx)); 255762306a36Sopenharmony_ci 255862306a36Sopenharmony_ci hdr = FLD_LS_64(cq->dev, cq->cq_uk.cq_id, IRDMA_CQPSQ_CQ_CQID) | 255962306a36Sopenharmony_ci FLD_LS_64(cq->dev, (cq->ceq_id_valid ? cq->ceq_id : 0), 256062306a36Sopenharmony_ci IRDMA_CQPSQ_CQ_CEQID) | 256162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_CQ) | 256262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_LPBLSIZE, cq->pbl_chunk_size) | 256362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_CHKOVERFLOW, check_overflow) | 256462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_VIRTMAP, cq->virtual_map) | 256562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, cq->ceqe_mask) | 256662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_CEQIDVALID, cq->ceq_id_valid) | 256762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHEN, cq->tph_en) | 256862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT, 256962306a36Sopenharmony_ci cq->cq_uk.avoid_mem_cflct) | 257062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 257162306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 257262306a36Sopenharmony_ci 257362306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 257462306a36Sopenharmony_ci 257562306a36Sopenharmony_ci print_hex_dump_debug("WQE: CQ_CREATE WQE", DUMP_PREFIX_OFFSET, 16, 8, 257662306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 257762306a36Sopenharmony_ci if (post_sq) 257862306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 257962306a36Sopenharmony_ci 258062306a36Sopenharmony_ci return 0; 258162306a36Sopenharmony_ci} 258262306a36Sopenharmony_ci 258362306a36Sopenharmony_ci/** 258462306a36Sopenharmony_ci * irdma_sc_cq_destroy - destroy completion q 258562306a36Sopenharmony_ci * @cq: cq struct 258662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 258762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 258862306a36Sopenharmony_ci */ 258962306a36Sopenharmony_ciint irdma_sc_cq_destroy(struct irdma_sc_cq *cq, u64 scratch, bool post_sq) 259062306a36Sopenharmony_ci{ 259162306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 259262306a36Sopenharmony_ci __le64 *wqe; 259362306a36Sopenharmony_ci u64 hdr; 259462306a36Sopenharmony_ci struct irdma_sc_ceq *ceq; 259562306a36Sopenharmony_ci 259662306a36Sopenharmony_ci cqp = cq->dev->cqp; 259762306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 259862306a36Sopenharmony_ci if (!wqe) 259962306a36Sopenharmony_ci return -ENOMEM; 260062306a36Sopenharmony_ci 260162306a36Sopenharmony_ci ceq = cq->dev->ceq[cq->ceq_id]; 260262306a36Sopenharmony_ci if (ceq && ceq->reg_cq) 260362306a36Sopenharmony_ci irdma_sc_remove_cq_ctx(ceq, cq); 260462306a36Sopenharmony_ci 260562306a36Sopenharmony_ci set_64bit_val(wqe, 0, cq->cq_uk.cq_size); 260662306a36Sopenharmony_ci set_64bit_val(wqe, 8, (uintptr_t)cq >> 1); 260762306a36Sopenharmony_ci set_64bit_val(wqe, 40, cq->shadow_area_pa); 260862306a36Sopenharmony_ci set_64bit_val(wqe, 48, 260962306a36Sopenharmony_ci (cq->virtual_map ? cq->first_pm_pbl_idx : 0)); 261062306a36Sopenharmony_ci 261162306a36Sopenharmony_ci hdr = cq->cq_uk.cq_id | 261262306a36Sopenharmony_ci FLD_LS_64(cq->dev, (cq->ceq_id_valid ? cq->ceq_id : 0), 261362306a36Sopenharmony_ci IRDMA_CQPSQ_CQ_CEQID) | 261462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_CQ) | 261562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_LPBLSIZE, cq->pbl_chunk_size) | 261662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_VIRTMAP, cq->virtual_map) | 261762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, cq->ceqe_mask) | 261862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_CEQIDVALID, cq->ceq_id_valid) | 261962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHEN, cq->tph_en) | 262062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT, cq->cq_uk.avoid_mem_cflct) | 262162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 262262306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 262362306a36Sopenharmony_ci 262462306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 262562306a36Sopenharmony_ci 262662306a36Sopenharmony_ci print_hex_dump_debug("WQE: CQ_DESTROY WQE", DUMP_PREFIX_OFFSET, 16, 8, 262762306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 262862306a36Sopenharmony_ci if (post_sq) 262962306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 263062306a36Sopenharmony_ci 263162306a36Sopenharmony_ci return 0; 263262306a36Sopenharmony_ci} 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci/** 263562306a36Sopenharmony_ci * irdma_sc_cq_resize - set resized cq buffer info 263662306a36Sopenharmony_ci * @cq: resized cq 263762306a36Sopenharmony_ci * @info: resized cq buffer info 263862306a36Sopenharmony_ci */ 263962306a36Sopenharmony_civoid irdma_sc_cq_resize(struct irdma_sc_cq *cq, struct irdma_modify_cq_info *info) 264062306a36Sopenharmony_ci{ 264162306a36Sopenharmony_ci cq->virtual_map = info->virtual_map; 264262306a36Sopenharmony_ci cq->cq_pa = info->cq_pa; 264362306a36Sopenharmony_ci cq->first_pm_pbl_idx = info->first_pm_pbl_idx; 264462306a36Sopenharmony_ci cq->pbl_chunk_size = info->pbl_chunk_size; 264562306a36Sopenharmony_ci irdma_uk_cq_resize(&cq->cq_uk, info->cq_base, info->cq_size); 264662306a36Sopenharmony_ci} 264762306a36Sopenharmony_ci 264862306a36Sopenharmony_ci/** 264962306a36Sopenharmony_ci * irdma_sc_cq_modify - modify a Completion Queue 265062306a36Sopenharmony_ci * @cq: cq struct 265162306a36Sopenharmony_ci * @info: modification info struct 265262306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 265362306a36Sopenharmony_ci * @post_sq: flag to post to sq 265462306a36Sopenharmony_ci */ 265562306a36Sopenharmony_cistatic int irdma_sc_cq_modify(struct irdma_sc_cq *cq, 265662306a36Sopenharmony_ci struct irdma_modify_cq_info *info, u64 scratch, 265762306a36Sopenharmony_ci bool post_sq) 265862306a36Sopenharmony_ci{ 265962306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 266062306a36Sopenharmony_ci __le64 *wqe; 266162306a36Sopenharmony_ci u64 hdr; 266262306a36Sopenharmony_ci u32 pble_obj_cnt; 266362306a36Sopenharmony_ci 266462306a36Sopenharmony_ci pble_obj_cnt = cq->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt; 266562306a36Sopenharmony_ci if (info->cq_resize && info->virtual_map && 266662306a36Sopenharmony_ci info->first_pm_pbl_idx >= pble_obj_cnt) 266762306a36Sopenharmony_ci return -EINVAL; 266862306a36Sopenharmony_ci 266962306a36Sopenharmony_ci cqp = cq->dev->cqp; 267062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 267162306a36Sopenharmony_ci if (!wqe) 267262306a36Sopenharmony_ci return -ENOMEM; 267362306a36Sopenharmony_ci 267462306a36Sopenharmony_ci set_64bit_val(wqe, 0, info->cq_size); 267562306a36Sopenharmony_ci set_64bit_val(wqe, 8, (uintptr_t)cq >> 1); 267662306a36Sopenharmony_ci set_64bit_val(wqe, 16, 267762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD, info->shadow_read_threshold)); 267862306a36Sopenharmony_ci set_64bit_val(wqe, 32, info->cq_pa); 267962306a36Sopenharmony_ci set_64bit_val(wqe, 40, cq->shadow_area_pa); 268062306a36Sopenharmony_ci set_64bit_val(wqe, 48, info->first_pm_pbl_idx); 268162306a36Sopenharmony_ci set_64bit_val(wqe, 56, 268262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHVAL, cq->tph_val) | 268362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_VSIIDX, cq->vsi->vsi_idx)); 268462306a36Sopenharmony_ci 268562306a36Sopenharmony_ci hdr = cq->cq_uk.cq_id | 268662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_MODIFY_CQ) | 268762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_CQRESIZE, info->cq_resize) | 268862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_LPBLSIZE, info->pbl_chunk_size) | 268962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_CHKOVERFLOW, info->check_overflow) | 269062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_VIRTMAP, info->virtual_map) | 269162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, cq->ceqe_mask) | 269262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHEN, cq->tph_en) | 269362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT, 269462306a36Sopenharmony_ci cq->cq_uk.avoid_mem_cflct) | 269562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 269662306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 269762306a36Sopenharmony_ci 269862306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 269962306a36Sopenharmony_ci 270062306a36Sopenharmony_ci print_hex_dump_debug("WQE: CQ_MODIFY WQE", DUMP_PREFIX_OFFSET, 16, 8, 270162306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 270262306a36Sopenharmony_ci if (post_sq) 270362306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 270462306a36Sopenharmony_ci 270562306a36Sopenharmony_ci return 0; 270662306a36Sopenharmony_ci} 270762306a36Sopenharmony_ci 270862306a36Sopenharmony_ci/** 270962306a36Sopenharmony_ci * irdma_check_cqp_progress - check cqp processing progress 271062306a36Sopenharmony_ci * @timeout: timeout info struct 271162306a36Sopenharmony_ci * @dev: sc device struct 271262306a36Sopenharmony_ci */ 271362306a36Sopenharmony_civoid irdma_check_cqp_progress(struct irdma_cqp_timeout *timeout, struct irdma_sc_dev *dev) 271462306a36Sopenharmony_ci{ 271562306a36Sopenharmony_ci u64 completed_ops = atomic64_read(&dev->cqp->completed_ops); 271662306a36Sopenharmony_ci 271762306a36Sopenharmony_ci if (timeout->compl_cqp_cmds != completed_ops) { 271862306a36Sopenharmony_ci timeout->compl_cqp_cmds = completed_ops; 271962306a36Sopenharmony_ci timeout->count = 0; 272062306a36Sopenharmony_ci } else if (timeout->compl_cqp_cmds != dev->cqp->requested_ops) { 272162306a36Sopenharmony_ci timeout->count++; 272262306a36Sopenharmony_ci } 272362306a36Sopenharmony_ci} 272462306a36Sopenharmony_ci 272562306a36Sopenharmony_ci/** 272662306a36Sopenharmony_ci * irdma_get_cqp_reg_info - get head and tail for cqp using registers 272762306a36Sopenharmony_ci * @cqp: struct for cqp hw 272862306a36Sopenharmony_ci * @val: cqp tail register value 272962306a36Sopenharmony_ci * @tail: wqtail register value 273062306a36Sopenharmony_ci * @error: cqp processing err 273162306a36Sopenharmony_ci */ 273262306a36Sopenharmony_cistatic inline void irdma_get_cqp_reg_info(struct irdma_sc_cqp *cqp, u32 *val, 273362306a36Sopenharmony_ci u32 *tail, u32 *error) 273462306a36Sopenharmony_ci{ 273562306a36Sopenharmony_ci *val = readl(cqp->dev->hw_regs[IRDMA_CQPTAIL]); 273662306a36Sopenharmony_ci *tail = FIELD_GET(IRDMA_CQPTAIL_WQTAIL, *val); 273762306a36Sopenharmony_ci *error = FIELD_GET(IRDMA_CQPTAIL_CQP_OP_ERR, *val); 273862306a36Sopenharmony_ci} 273962306a36Sopenharmony_ci 274062306a36Sopenharmony_ci/** 274162306a36Sopenharmony_ci * irdma_cqp_poll_registers - poll cqp registers 274262306a36Sopenharmony_ci * @cqp: struct for cqp hw 274362306a36Sopenharmony_ci * @tail: wqtail register value 274462306a36Sopenharmony_ci * @count: how many times to try for completion 274562306a36Sopenharmony_ci */ 274662306a36Sopenharmony_cistatic int irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp, u32 tail, 274762306a36Sopenharmony_ci u32 count) 274862306a36Sopenharmony_ci{ 274962306a36Sopenharmony_ci u32 i = 0; 275062306a36Sopenharmony_ci u32 newtail, error, val; 275162306a36Sopenharmony_ci 275262306a36Sopenharmony_ci while (i++ < count) { 275362306a36Sopenharmony_ci irdma_get_cqp_reg_info(cqp, &val, &newtail, &error); 275462306a36Sopenharmony_ci if (error) { 275562306a36Sopenharmony_ci error = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]); 275662306a36Sopenharmony_ci ibdev_dbg(to_ibdev(cqp->dev), 275762306a36Sopenharmony_ci "CQP: CQPERRCODES error_code[x%08X]\n", 275862306a36Sopenharmony_ci error); 275962306a36Sopenharmony_ci return -EIO; 276062306a36Sopenharmony_ci } 276162306a36Sopenharmony_ci if (newtail != tail) { 276262306a36Sopenharmony_ci /* SUCCESS */ 276362306a36Sopenharmony_ci IRDMA_RING_MOVE_TAIL(cqp->sq_ring); 276462306a36Sopenharmony_ci atomic64_inc(&cqp->completed_ops); 276562306a36Sopenharmony_ci return 0; 276662306a36Sopenharmony_ci } 276762306a36Sopenharmony_ci udelay(cqp->dev->hw_attrs.max_sleep_count); 276862306a36Sopenharmony_ci } 276962306a36Sopenharmony_ci 277062306a36Sopenharmony_ci return -ETIMEDOUT; 277162306a36Sopenharmony_ci} 277262306a36Sopenharmony_ci 277362306a36Sopenharmony_ci/** 277462306a36Sopenharmony_ci * irdma_sc_decode_fpm_commit - decode a 64 bit value into count and base 277562306a36Sopenharmony_ci * @dev: sc device struct 277662306a36Sopenharmony_ci * @buf: pointer to commit buffer 277762306a36Sopenharmony_ci * @buf_idx: buffer index 277862306a36Sopenharmony_ci * @obj_info: object info pointer 277962306a36Sopenharmony_ci * @rsrc_idx: indexs of memory resource 278062306a36Sopenharmony_ci */ 278162306a36Sopenharmony_cistatic u64 irdma_sc_decode_fpm_commit(struct irdma_sc_dev *dev, __le64 *buf, 278262306a36Sopenharmony_ci u32 buf_idx, struct irdma_hmc_obj_info *obj_info, 278362306a36Sopenharmony_ci u32 rsrc_idx) 278462306a36Sopenharmony_ci{ 278562306a36Sopenharmony_ci u64 temp; 278662306a36Sopenharmony_ci 278762306a36Sopenharmony_ci get_64bit_val(buf, buf_idx, &temp); 278862306a36Sopenharmony_ci 278962306a36Sopenharmony_ci switch (rsrc_idx) { 279062306a36Sopenharmony_ci case IRDMA_HMC_IW_QP: 279162306a36Sopenharmony_ci obj_info[rsrc_idx].cnt = (u32)FIELD_GET(IRDMA_COMMIT_FPM_QPCNT, temp); 279262306a36Sopenharmony_ci break; 279362306a36Sopenharmony_ci case IRDMA_HMC_IW_CQ: 279462306a36Sopenharmony_ci obj_info[rsrc_idx].cnt = (u32)FLD_RS_64(dev, temp, IRDMA_COMMIT_FPM_CQCNT); 279562306a36Sopenharmony_ci break; 279662306a36Sopenharmony_ci case IRDMA_HMC_IW_APBVT_ENTRY: 279762306a36Sopenharmony_ci obj_info[rsrc_idx].cnt = 1; 279862306a36Sopenharmony_ci break; 279962306a36Sopenharmony_ci default: 280062306a36Sopenharmony_ci obj_info[rsrc_idx].cnt = (u32)temp; 280162306a36Sopenharmony_ci break; 280262306a36Sopenharmony_ci } 280362306a36Sopenharmony_ci 280462306a36Sopenharmony_ci obj_info[rsrc_idx].base = (temp >> IRDMA_COMMIT_FPM_BASE_S) * 512; 280562306a36Sopenharmony_ci 280662306a36Sopenharmony_ci return temp; 280762306a36Sopenharmony_ci} 280862306a36Sopenharmony_ci 280962306a36Sopenharmony_ci/** 281062306a36Sopenharmony_ci * irdma_sc_parse_fpm_commit_buf - parse fpm commit buffer 281162306a36Sopenharmony_ci * @dev: pointer to dev struct 281262306a36Sopenharmony_ci * @buf: ptr to fpm commit buffer 281362306a36Sopenharmony_ci * @info: ptr to irdma_hmc_obj_info struct 281462306a36Sopenharmony_ci * @sd: number of SDs for HMC objects 281562306a36Sopenharmony_ci * 281662306a36Sopenharmony_ci * parses fpm commit info and copy base value 281762306a36Sopenharmony_ci * of hmc objects in hmc_info 281862306a36Sopenharmony_ci */ 281962306a36Sopenharmony_cistatic void 282062306a36Sopenharmony_ciirdma_sc_parse_fpm_commit_buf(struct irdma_sc_dev *dev, __le64 *buf, 282162306a36Sopenharmony_ci struct irdma_hmc_obj_info *info, u32 *sd) 282262306a36Sopenharmony_ci{ 282362306a36Sopenharmony_ci u64 size; 282462306a36Sopenharmony_ci u32 i; 282562306a36Sopenharmony_ci u64 max_base = 0; 282662306a36Sopenharmony_ci u32 last_hmc_obj = 0; 282762306a36Sopenharmony_ci 282862306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 0, info, 282962306a36Sopenharmony_ci IRDMA_HMC_IW_QP); 283062306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 8, info, 283162306a36Sopenharmony_ci IRDMA_HMC_IW_CQ); 283262306a36Sopenharmony_ci /* skiping RSRVD */ 283362306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 24, info, 283462306a36Sopenharmony_ci IRDMA_HMC_IW_HTE); 283562306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 32, info, 283662306a36Sopenharmony_ci IRDMA_HMC_IW_ARP); 283762306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 40, info, 283862306a36Sopenharmony_ci IRDMA_HMC_IW_APBVT_ENTRY); 283962306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 48, info, 284062306a36Sopenharmony_ci IRDMA_HMC_IW_MR); 284162306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 56, info, 284262306a36Sopenharmony_ci IRDMA_HMC_IW_XF); 284362306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 64, info, 284462306a36Sopenharmony_ci IRDMA_HMC_IW_XFFL); 284562306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 72, info, 284662306a36Sopenharmony_ci IRDMA_HMC_IW_Q1); 284762306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 80, info, 284862306a36Sopenharmony_ci IRDMA_HMC_IW_Q1FL); 284962306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 88, info, 285062306a36Sopenharmony_ci IRDMA_HMC_IW_TIMER); 285162306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 112, info, 285262306a36Sopenharmony_ci IRDMA_HMC_IW_PBLE); 285362306a36Sopenharmony_ci /* skipping RSVD. */ 285462306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1) { 285562306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 96, info, 285662306a36Sopenharmony_ci IRDMA_HMC_IW_FSIMC); 285762306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 104, info, 285862306a36Sopenharmony_ci IRDMA_HMC_IW_FSIAV); 285962306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 128, info, 286062306a36Sopenharmony_ci IRDMA_HMC_IW_RRF); 286162306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 136, info, 286262306a36Sopenharmony_ci IRDMA_HMC_IW_RRFFL); 286362306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 144, info, 286462306a36Sopenharmony_ci IRDMA_HMC_IW_HDR); 286562306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 152, info, 286662306a36Sopenharmony_ci IRDMA_HMC_IW_MD); 286762306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 160, info, 286862306a36Sopenharmony_ci IRDMA_HMC_IW_OOISC); 286962306a36Sopenharmony_ci irdma_sc_decode_fpm_commit(dev, buf, 168, info, 287062306a36Sopenharmony_ci IRDMA_HMC_IW_OOISCFFL); 287162306a36Sopenharmony_ci } 287262306a36Sopenharmony_ci 287362306a36Sopenharmony_ci /* searching for the last object in HMC to find the size of the HMC area. */ 287462306a36Sopenharmony_ci for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) { 287562306a36Sopenharmony_ci if (info[i].base > max_base) { 287662306a36Sopenharmony_ci max_base = info[i].base; 287762306a36Sopenharmony_ci last_hmc_obj = i; 287862306a36Sopenharmony_ci } 287962306a36Sopenharmony_ci } 288062306a36Sopenharmony_ci 288162306a36Sopenharmony_ci size = info[last_hmc_obj].cnt * info[last_hmc_obj].size + 288262306a36Sopenharmony_ci info[last_hmc_obj].base; 288362306a36Sopenharmony_ci 288462306a36Sopenharmony_ci if (size & 0x1FFFFF) 288562306a36Sopenharmony_ci *sd = (u32)((size >> 21) + 1); /* add 1 for remainder */ 288662306a36Sopenharmony_ci else 288762306a36Sopenharmony_ci *sd = (u32)(size >> 21); 288862306a36Sopenharmony_ci 288962306a36Sopenharmony_ci} 289062306a36Sopenharmony_ci 289162306a36Sopenharmony_ci/** 289262306a36Sopenharmony_ci * irdma_sc_decode_fpm_query() - Decode a 64 bit value into max count and size 289362306a36Sopenharmony_ci * @buf: ptr to fpm query buffer 289462306a36Sopenharmony_ci * @buf_idx: index into buf 289562306a36Sopenharmony_ci * @obj_info: ptr to irdma_hmc_obj_info struct 289662306a36Sopenharmony_ci * @rsrc_idx: resource index into info 289762306a36Sopenharmony_ci * 289862306a36Sopenharmony_ci * Decode a 64 bit value from fpm query buffer into max count and size 289962306a36Sopenharmony_ci */ 290062306a36Sopenharmony_cistatic u64 irdma_sc_decode_fpm_query(__le64 *buf, u32 buf_idx, 290162306a36Sopenharmony_ci struct irdma_hmc_obj_info *obj_info, 290262306a36Sopenharmony_ci u32 rsrc_idx) 290362306a36Sopenharmony_ci{ 290462306a36Sopenharmony_ci u64 temp; 290562306a36Sopenharmony_ci u32 size; 290662306a36Sopenharmony_ci 290762306a36Sopenharmony_ci get_64bit_val(buf, buf_idx, &temp); 290862306a36Sopenharmony_ci obj_info[rsrc_idx].max_cnt = (u32)temp; 290962306a36Sopenharmony_ci size = (u32)(temp >> 32); 291062306a36Sopenharmony_ci obj_info[rsrc_idx].size = BIT_ULL(size); 291162306a36Sopenharmony_ci 291262306a36Sopenharmony_ci return temp; 291362306a36Sopenharmony_ci} 291462306a36Sopenharmony_ci 291562306a36Sopenharmony_ci/** 291662306a36Sopenharmony_ci * irdma_sc_parse_fpm_query_buf() - parses fpm query buffer 291762306a36Sopenharmony_ci * @dev: ptr to shared code device 291862306a36Sopenharmony_ci * @buf: ptr to fpm query buffer 291962306a36Sopenharmony_ci * @hmc_info: ptr to irdma_hmc_obj_info struct 292062306a36Sopenharmony_ci * @hmc_fpm_misc: ptr to fpm data 292162306a36Sopenharmony_ci * 292262306a36Sopenharmony_ci * parses fpm query buffer and copy max_cnt and 292362306a36Sopenharmony_ci * size value of hmc objects in hmc_info 292462306a36Sopenharmony_ci */ 292562306a36Sopenharmony_cistatic int irdma_sc_parse_fpm_query_buf(struct irdma_sc_dev *dev, __le64 *buf, 292662306a36Sopenharmony_ci struct irdma_hmc_info *hmc_info, 292762306a36Sopenharmony_ci struct irdma_hmc_fpm_misc *hmc_fpm_misc) 292862306a36Sopenharmony_ci{ 292962306a36Sopenharmony_ci struct irdma_hmc_obj_info *obj_info; 293062306a36Sopenharmony_ci u64 temp; 293162306a36Sopenharmony_ci u32 size; 293262306a36Sopenharmony_ci u16 max_pe_sds; 293362306a36Sopenharmony_ci 293462306a36Sopenharmony_ci obj_info = hmc_info->hmc_obj; 293562306a36Sopenharmony_ci 293662306a36Sopenharmony_ci get_64bit_val(buf, 0, &temp); 293762306a36Sopenharmony_ci hmc_info->first_sd_index = (u16)FIELD_GET(IRDMA_QUERY_FPM_FIRST_PE_SD_INDEX, temp); 293862306a36Sopenharmony_ci max_pe_sds = (u16)FIELD_GET(IRDMA_QUERY_FPM_MAX_PE_SDS, temp); 293962306a36Sopenharmony_ci 294062306a36Sopenharmony_ci hmc_fpm_misc->max_sds = max_pe_sds; 294162306a36Sopenharmony_ci hmc_info->sd_table.sd_cnt = max_pe_sds + hmc_info->first_sd_index; 294262306a36Sopenharmony_ci get_64bit_val(buf, 8, &temp); 294362306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_QP].max_cnt = (u32)FIELD_GET(IRDMA_QUERY_FPM_MAX_QPS, temp); 294462306a36Sopenharmony_ci size = (u32)(temp >> 32); 294562306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_QP].size = BIT_ULL(size); 294662306a36Sopenharmony_ci 294762306a36Sopenharmony_ci get_64bit_val(buf, 16, &temp); 294862306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_CQ].max_cnt = (u32)FIELD_GET(IRDMA_QUERY_FPM_MAX_CQS, temp); 294962306a36Sopenharmony_ci size = (u32)(temp >> 32); 295062306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_CQ].size = BIT_ULL(size); 295162306a36Sopenharmony_ci 295262306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 32, obj_info, IRDMA_HMC_IW_HTE); 295362306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 40, obj_info, IRDMA_HMC_IW_ARP); 295462306a36Sopenharmony_ci 295562306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_APBVT_ENTRY].size = 8192; 295662306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_APBVT_ENTRY].max_cnt = 1; 295762306a36Sopenharmony_ci 295862306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 48, obj_info, IRDMA_HMC_IW_MR); 295962306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 56, obj_info, IRDMA_HMC_IW_XF); 296062306a36Sopenharmony_ci 296162306a36Sopenharmony_ci get_64bit_val(buf, 64, &temp); 296262306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_XFFL].max_cnt = (u32)temp; 296362306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_XFFL].size = 4; 296462306a36Sopenharmony_ci hmc_fpm_misc->xf_block_size = FIELD_GET(IRDMA_QUERY_FPM_XFBLOCKSIZE, temp); 296562306a36Sopenharmony_ci if (!hmc_fpm_misc->xf_block_size) 296662306a36Sopenharmony_ci return -EINVAL; 296762306a36Sopenharmony_ci 296862306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 72, obj_info, IRDMA_HMC_IW_Q1); 296962306a36Sopenharmony_ci get_64bit_val(buf, 80, &temp); 297062306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_Q1FL].max_cnt = (u32)temp; 297162306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_Q1FL].size = 4; 297262306a36Sopenharmony_ci 297362306a36Sopenharmony_ci hmc_fpm_misc->q1_block_size = FIELD_GET(IRDMA_QUERY_FPM_Q1BLOCKSIZE, temp); 297462306a36Sopenharmony_ci if (!hmc_fpm_misc->q1_block_size) 297562306a36Sopenharmony_ci return -EINVAL; 297662306a36Sopenharmony_ci 297762306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 88, obj_info, IRDMA_HMC_IW_TIMER); 297862306a36Sopenharmony_ci 297962306a36Sopenharmony_ci get_64bit_val(buf, 112, &temp); 298062306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_PBLE].max_cnt = (u32)temp; 298162306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_PBLE].size = 8; 298262306a36Sopenharmony_ci 298362306a36Sopenharmony_ci get_64bit_val(buf, 120, &temp); 298462306a36Sopenharmony_ci hmc_fpm_misc->max_ceqs = FIELD_GET(IRDMA_QUERY_FPM_MAX_CEQS, temp); 298562306a36Sopenharmony_ci hmc_fpm_misc->ht_multiplier = FIELD_GET(IRDMA_QUERY_FPM_HTMULTIPLIER, temp); 298662306a36Sopenharmony_ci hmc_fpm_misc->timer_bucket = FIELD_GET(IRDMA_QUERY_FPM_TIMERBUCKET, temp); 298762306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) 298862306a36Sopenharmony_ci return 0; 298962306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 96, obj_info, IRDMA_HMC_IW_FSIMC); 299062306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 104, obj_info, IRDMA_HMC_IW_FSIAV); 299162306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 128, obj_info, IRDMA_HMC_IW_RRF); 299262306a36Sopenharmony_ci 299362306a36Sopenharmony_ci get_64bit_val(buf, 136, &temp); 299462306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_RRFFL].max_cnt = (u32)temp; 299562306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_RRFFL].size = 4; 299662306a36Sopenharmony_ci hmc_fpm_misc->rrf_block_size = FIELD_GET(IRDMA_QUERY_FPM_RRFBLOCKSIZE, temp); 299762306a36Sopenharmony_ci if (!hmc_fpm_misc->rrf_block_size && 299862306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_RRFFL].max_cnt) 299962306a36Sopenharmony_ci return -EINVAL; 300062306a36Sopenharmony_ci 300162306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 144, obj_info, IRDMA_HMC_IW_HDR); 300262306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 152, obj_info, IRDMA_HMC_IW_MD); 300362306a36Sopenharmony_ci irdma_sc_decode_fpm_query(buf, 160, obj_info, IRDMA_HMC_IW_OOISC); 300462306a36Sopenharmony_ci 300562306a36Sopenharmony_ci get_64bit_val(buf, 168, &temp); 300662306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt = (u32)temp; 300762306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_OOISCFFL].size = 4; 300862306a36Sopenharmony_ci hmc_fpm_misc->ooiscf_block_size = FIELD_GET(IRDMA_QUERY_FPM_OOISCFBLOCKSIZE, temp); 300962306a36Sopenharmony_ci if (!hmc_fpm_misc->ooiscf_block_size && 301062306a36Sopenharmony_ci obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt) 301162306a36Sopenharmony_ci return -EINVAL; 301262306a36Sopenharmony_ci 301362306a36Sopenharmony_ci return 0; 301462306a36Sopenharmony_ci} 301562306a36Sopenharmony_ci 301662306a36Sopenharmony_ci/** 301762306a36Sopenharmony_ci * irdma_sc_find_reg_cq - find cq ctx index 301862306a36Sopenharmony_ci * @ceq: ceq sc structure 301962306a36Sopenharmony_ci * @cq: cq sc structure 302062306a36Sopenharmony_ci */ 302162306a36Sopenharmony_cistatic u32 irdma_sc_find_reg_cq(struct irdma_sc_ceq *ceq, 302262306a36Sopenharmony_ci struct irdma_sc_cq *cq) 302362306a36Sopenharmony_ci{ 302462306a36Sopenharmony_ci u32 i; 302562306a36Sopenharmony_ci 302662306a36Sopenharmony_ci for (i = 0; i < ceq->reg_cq_size; i++) { 302762306a36Sopenharmony_ci if (cq == ceq->reg_cq[i]) 302862306a36Sopenharmony_ci return i; 302962306a36Sopenharmony_ci } 303062306a36Sopenharmony_ci 303162306a36Sopenharmony_ci return IRDMA_INVALID_CQ_IDX; 303262306a36Sopenharmony_ci} 303362306a36Sopenharmony_ci 303462306a36Sopenharmony_ci/** 303562306a36Sopenharmony_ci * irdma_sc_add_cq_ctx - add cq ctx tracking for ceq 303662306a36Sopenharmony_ci * @ceq: ceq sc structure 303762306a36Sopenharmony_ci * @cq: cq sc structure 303862306a36Sopenharmony_ci */ 303962306a36Sopenharmony_ciint irdma_sc_add_cq_ctx(struct irdma_sc_ceq *ceq, struct irdma_sc_cq *cq) 304062306a36Sopenharmony_ci{ 304162306a36Sopenharmony_ci unsigned long flags; 304262306a36Sopenharmony_ci 304362306a36Sopenharmony_ci spin_lock_irqsave(&ceq->req_cq_lock, flags); 304462306a36Sopenharmony_ci 304562306a36Sopenharmony_ci if (ceq->reg_cq_size == ceq->elem_cnt) { 304662306a36Sopenharmony_ci spin_unlock_irqrestore(&ceq->req_cq_lock, flags); 304762306a36Sopenharmony_ci return -ENOMEM; 304862306a36Sopenharmony_ci } 304962306a36Sopenharmony_ci 305062306a36Sopenharmony_ci ceq->reg_cq[ceq->reg_cq_size++] = cq; 305162306a36Sopenharmony_ci 305262306a36Sopenharmony_ci spin_unlock_irqrestore(&ceq->req_cq_lock, flags); 305362306a36Sopenharmony_ci 305462306a36Sopenharmony_ci return 0; 305562306a36Sopenharmony_ci} 305662306a36Sopenharmony_ci 305762306a36Sopenharmony_ci/** 305862306a36Sopenharmony_ci * irdma_sc_remove_cq_ctx - remove cq ctx tracking for ceq 305962306a36Sopenharmony_ci * @ceq: ceq sc structure 306062306a36Sopenharmony_ci * @cq: cq sc structure 306162306a36Sopenharmony_ci */ 306262306a36Sopenharmony_civoid irdma_sc_remove_cq_ctx(struct irdma_sc_ceq *ceq, struct irdma_sc_cq *cq) 306362306a36Sopenharmony_ci{ 306462306a36Sopenharmony_ci unsigned long flags; 306562306a36Sopenharmony_ci u32 cq_ctx_idx; 306662306a36Sopenharmony_ci 306762306a36Sopenharmony_ci spin_lock_irqsave(&ceq->req_cq_lock, flags); 306862306a36Sopenharmony_ci cq_ctx_idx = irdma_sc_find_reg_cq(ceq, cq); 306962306a36Sopenharmony_ci if (cq_ctx_idx == IRDMA_INVALID_CQ_IDX) 307062306a36Sopenharmony_ci goto exit; 307162306a36Sopenharmony_ci 307262306a36Sopenharmony_ci ceq->reg_cq_size--; 307362306a36Sopenharmony_ci if (cq_ctx_idx != ceq->reg_cq_size) 307462306a36Sopenharmony_ci ceq->reg_cq[cq_ctx_idx] = ceq->reg_cq[ceq->reg_cq_size]; 307562306a36Sopenharmony_ci ceq->reg_cq[ceq->reg_cq_size] = NULL; 307662306a36Sopenharmony_ci 307762306a36Sopenharmony_ciexit: 307862306a36Sopenharmony_ci spin_unlock_irqrestore(&ceq->req_cq_lock, flags); 307962306a36Sopenharmony_ci} 308062306a36Sopenharmony_ci 308162306a36Sopenharmony_ci/** 308262306a36Sopenharmony_ci * irdma_sc_cqp_init - Initialize buffers for a control Queue Pair 308362306a36Sopenharmony_ci * @cqp: IWARP control queue pair pointer 308462306a36Sopenharmony_ci * @info: IWARP control queue pair init info pointer 308562306a36Sopenharmony_ci * 308662306a36Sopenharmony_ci * Initializes the object and context buffers for a control Queue Pair. 308762306a36Sopenharmony_ci */ 308862306a36Sopenharmony_ciint irdma_sc_cqp_init(struct irdma_sc_cqp *cqp, 308962306a36Sopenharmony_ci struct irdma_cqp_init_info *info) 309062306a36Sopenharmony_ci{ 309162306a36Sopenharmony_ci u8 hw_sq_size; 309262306a36Sopenharmony_ci 309362306a36Sopenharmony_ci if (info->sq_size > IRDMA_CQP_SW_SQSIZE_2048 || 309462306a36Sopenharmony_ci info->sq_size < IRDMA_CQP_SW_SQSIZE_4 || 309562306a36Sopenharmony_ci ((info->sq_size & (info->sq_size - 1)))) 309662306a36Sopenharmony_ci return -EINVAL; 309762306a36Sopenharmony_ci 309862306a36Sopenharmony_ci hw_sq_size = irdma_get_encoded_wqe_size(info->sq_size, 309962306a36Sopenharmony_ci IRDMA_QUEUE_TYPE_CQP); 310062306a36Sopenharmony_ci cqp->size = sizeof(*cqp); 310162306a36Sopenharmony_ci cqp->sq_size = info->sq_size; 310262306a36Sopenharmony_ci cqp->hw_sq_size = hw_sq_size; 310362306a36Sopenharmony_ci cqp->sq_base = info->sq; 310462306a36Sopenharmony_ci cqp->host_ctx = info->host_ctx; 310562306a36Sopenharmony_ci cqp->sq_pa = info->sq_pa; 310662306a36Sopenharmony_ci cqp->host_ctx_pa = info->host_ctx_pa; 310762306a36Sopenharmony_ci cqp->dev = info->dev; 310862306a36Sopenharmony_ci cqp->struct_ver = info->struct_ver; 310962306a36Sopenharmony_ci cqp->hw_maj_ver = info->hw_maj_ver; 311062306a36Sopenharmony_ci cqp->hw_min_ver = info->hw_min_ver; 311162306a36Sopenharmony_ci cqp->scratch_array = info->scratch_array; 311262306a36Sopenharmony_ci cqp->polarity = 0; 311362306a36Sopenharmony_ci cqp->en_datacenter_tcp = info->en_datacenter_tcp; 311462306a36Sopenharmony_ci cqp->ena_vf_count = info->ena_vf_count; 311562306a36Sopenharmony_ci cqp->hmc_profile = info->hmc_profile; 311662306a36Sopenharmony_ci cqp->ceqs_per_vf = info->ceqs_per_vf; 311762306a36Sopenharmony_ci cqp->disable_packed = info->disable_packed; 311862306a36Sopenharmony_ci cqp->rocev2_rto_policy = info->rocev2_rto_policy; 311962306a36Sopenharmony_ci cqp->protocol_used = info->protocol_used; 312062306a36Sopenharmony_ci memcpy(&cqp->dcqcn_params, &info->dcqcn_params, sizeof(cqp->dcqcn_params)); 312162306a36Sopenharmony_ci info->dev->cqp = cqp; 312262306a36Sopenharmony_ci 312362306a36Sopenharmony_ci IRDMA_RING_INIT(cqp->sq_ring, cqp->sq_size); 312462306a36Sopenharmony_ci cqp->requested_ops = 0; 312562306a36Sopenharmony_ci atomic64_set(&cqp->completed_ops, 0); 312662306a36Sopenharmony_ci /* for the cqp commands backlog. */ 312762306a36Sopenharmony_ci INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head); 312862306a36Sopenharmony_ci 312962306a36Sopenharmony_ci writel(0, cqp->dev->hw_regs[IRDMA_CQPTAIL]); 313062306a36Sopenharmony_ci writel(0, cqp->dev->hw_regs[IRDMA_CQPDB]); 313162306a36Sopenharmony_ci writel(0, cqp->dev->hw_regs[IRDMA_CCQPSTATUS]); 313262306a36Sopenharmony_ci 313362306a36Sopenharmony_ci ibdev_dbg(to_ibdev(cqp->dev), 313462306a36Sopenharmony_ci "WQE: sq_size[%04d] hw_sq_size[%04d] sq_base[%p] sq_pa[%pK] cqp[%p] polarity[x%04x]\n", 313562306a36Sopenharmony_ci cqp->sq_size, cqp->hw_sq_size, cqp->sq_base, 313662306a36Sopenharmony_ci (u64 *)(uintptr_t)cqp->sq_pa, cqp, cqp->polarity); 313762306a36Sopenharmony_ci return 0; 313862306a36Sopenharmony_ci} 313962306a36Sopenharmony_ci 314062306a36Sopenharmony_ci/** 314162306a36Sopenharmony_ci * irdma_sc_cqp_create - create cqp during bringup 314262306a36Sopenharmony_ci * @cqp: struct for cqp hw 314362306a36Sopenharmony_ci * @maj_err: If error, major err number 314462306a36Sopenharmony_ci * @min_err: If error, minor err number 314562306a36Sopenharmony_ci */ 314662306a36Sopenharmony_ciint irdma_sc_cqp_create(struct irdma_sc_cqp *cqp, u16 *maj_err, u16 *min_err) 314762306a36Sopenharmony_ci{ 314862306a36Sopenharmony_ci u64 temp; 314962306a36Sopenharmony_ci u8 hw_rev; 315062306a36Sopenharmony_ci u32 cnt = 0, p1, p2, val = 0, err_code; 315162306a36Sopenharmony_ci int ret_code; 315262306a36Sopenharmony_ci 315362306a36Sopenharmony_ci hw_rev = cqp->dev->hw_attrs.uk_attrs.hw_rev; 315462306a36Sopenharmony_ci cqp->sdbuf.size = ALIGN(IRDMA_UPDATE_SD_BUFF_SIZE * cqp->sq_size, 315562306a36Sopenharmony_ci IRDMA_SD_BUF_ALIGNMENT); 315662306a36Sopenharmony_ci cqp->sdbuf.va = dma_alloc_coherent(cqp->dev->hw->device, 315762306a36Sopenharmony_ci cqp->sdbuf.size, &cqp->sdbuf.pa, 315862306a36Sopenharmony_ci GFP_KERNEL); 315962306a36Sopenharmony_ci if (!cqp->sdbuf.va) 316062306a36Sopenharmony_ci return -ENOMEM; 316162306a36Sopenharmony_ci 316262306a36Sopenharmony_ci spin_lock_init(&cqp->dev->cqp_lock); 316362306a36Sopenharmony_ci 316462306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPHC_SQSIZE, cqp->hw_sq_size) | 316562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_SVER, cqp->struct_ver) | 316662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_DISABLE_PFPDUS, cqp->disable_packed) | 316762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_CEQPERVF, cqp->ceqs_per_vf); 316862306a36Sopenharmony_ci if (hw_rev >= IRDMA_GEN_2) { 316962306a36Sopenharmony_ci temp |= FIELD_PREP(IRDMA_CQPHC_ROCEV2_RTO_POLICY, 317062306a36Sopenharmony_ci cqp->rocev2_rto_policy) | 317162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_PROTOCOL_USED, 317262306a36Sopenharmony_ci cqp->protocol_used); 317362306a36Sopenharmony_ci } 317462306a36Sopenharmony_ci 317562306a36Sopenharmony_ci set_64bit_val(cqp->host_ctx, 0, temp); 317662306a36Sopenharmony_ci set_64bit_val(cqp->host_ctx, 8, cqp->sq_pa); 317762306a36Sopenharmony_ci 317862306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPHC_ENABLED_VFS, cqp->ena_vf_count) | 317962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_HMC_PROFILE, cqp->hmc_profile); 318062306a36Sopenharmony_ci set_64bit_val(cqp->host_ctx, 16, temp); 318162306a36Sopenharmony_ci set_64bit_val(cqp->host_ctx, 24, (uintptr_t)cqp); 318262306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPHC_HW_MAJVER, cqp->hw_maj_ver) | 318362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_HW_MINVER, cqp->hw_min_ver); 318462306a36Sopenharmony_ci if (hw_rev >= IRDMA_GEN_2) { 318562306a36Sopenharmony_ci temp |= FIELD_PREP(IRDMA_CQPHC_MIN_RATE, cqp->dcqcn_params.min_rate) | 318662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_MIN_DEC_FACTOR, cqp->dcqcn_params.min_dec_factor); 318762306a36Sopenharmony_ci } 318862306a36Sopenharmony_ci set_64bit_val(cqp->host_ctx, 32, temp); 318962306a36Sopenharmony_ci set_64bit_val(cqp->host_ctx, 40, 0); 319062306a36Sopenharmony_ci temp = 0; 319162306a36Sopenharmony_ci if (hw_rev >= IRDMA_GEN_2) { 319262306a36Sopenharmony_ci temp |= FIELD_PREP(IRDMA_CQPHC_DCQCN_T, cqp->dcqcn_params.dcqcn_t) | 319362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_RAI_FACTOR, cqp->dcqcn_params.rai_factor) | 319462306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_HAI_FACTOR, cqp->dcqcn_params.hai_factor); 319562306a36Sopenharmony_ci } 319662306a36Sopenharmony_ci set_64bit_val(cqp->host_ctx, 48, temp); 319762306a36Sopenharmony_ci temp = 0; 319862306a36Sopenharmony_ci if (hw_rev >= IRDMA_GEN_2) { 319962306a36Sopenharmony_ci temp |= FIELD_PREP(IRDMA_CQPHC_DCQCN_B, cqp->dcqcn_params.dcqcn_b) | 320062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_DCQCN_F, cqp->dcqcn_params.dcqcn_f) | 320162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_CC_CFG_VALID, cqp->dcqcn_params.cc_cfg_valid) | 320262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPHC_RREDUCE_MPERIOD, cqp->dcqcn_params.rreduce_mperiod); 320362306a36Sopenharmony_ci } 320462306a36Sopenharmony_ci set_64bit_val(cqp->host_ctx, 56, temp); 320562306a36Sopenharmony_ci print_hex_dump_debug("WQE: CQP_HOST_CTX WQE", DUMP_PREFIX_OFFSET, 16, 320662306a36Sopenharmony_ci 8, cqp->host_ctx, IRDMA_CQP_CTX_SIZE * 8, false); 320762306a36Sopenharmony_ci p1 = cqp->host_ctx_pa >> 32; 320862306a36Sopenharmony_ci p2 = (u32)cqp->host_ctx_pa; 320962306a36Sopenharmony_ci 321062306a36Sopenharmony_ci writel(p1, cqp->dev->hw_regs[IRDMA_CCQPHIGH]); 321162306a36Sopenharmony_ci writel(p2, cqp->dev->hw_regs[IRDMA_CCQPLOW]); 321262306a36Sopenharmony_ci 321362306a36Sopenharmony_ci do { 321462306a36Sopenharmony_ci if (cnt++ > cqp->dev->hw_attrs.max_done_count) { 321562306a36Sopenharmony_ci ret_code = -ETIMEDOUT; 321662306a36Sopenharmony_ci goto err; 321762306a36Sopenharmony_ci } 321862306a36Sopenharmony_ci udelay(cqp->dev->hw_attrs.max_sleep_count); 321962306a36Sopenharmony_ci val = readl(cqp->dev->hw_regs[IRDMA_CCQPSTATUS]); 322062306a36Sopenharmony_ci } while (!val); 322162306a36Sopenharmony_ci 322262306a36Sopenharmony_ci if (FLD_RS_32(cqp->dev, val, IRDMA_CCQPSTATUS_CCQP_ERR)) { 322362306a36Sopenharmony_ci ret_code = -EOPNOTSUPP; 322462306a36Sopenharmony_ci goto err; 322562306a36Sopenharmony_ci } 322662306a36Sopenharmony_ci 322762306a36Sopenharmony_ci cqp->process_cqp_sds = irdma_update_sds_noccq; 322862306a36Sopenharmony_ci return 0; 322962306a36Sopenharmony_ci 323062306a36Sopenharmony_cierr: 323162306a36Sopenharmony_ci dma_free_coherent(cqp->dev->hw->device, cqp->sdbuf.size, 323262306a36Sopenharmony_ci cqp->sdbuf.va, cqp->sdbuf.pa); 323362306a36Sopenharmony_ci cqp->sdbuf.va = NULL; 323462306a36Sopenharmony_ci err_code = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]); 323562306a36Sopenharmony_ci *min_err = FIELD_GET(IRDMA_CQPERRCODES_CQP_MINOR_CODE, err_code); 323662306a36Sopenharmony_ci *maj_err = FIELD_GET(IRDMA_CQPERRCODES_CQP_MAJOR_CODE, err_code); 323762306a36Sopenharmony_ci return ret_code; 323862306a36Sopenharmony_ci} 323962306a36Sopenharmony_ci 324062306a36Sopenharmony_ci/** 324162306a36Sopenharmony_ci * irdma_sc_cqp_post_sq - post of cqp's sq 324262306a36Sopenharmony_ci * @cqp: struct for cqp hw 324362306a36Sopenharmony_ci */ 324462306a36Sopenharmony_civoid irdma_sc_cqp_post_sq(struct irdma_sc_cqp *cqp) 324562306a36Sopenharmony_ci{ 324662306a36Sopenharmony_ci writel(IRDMA_RING_CURRENT_HEAD(cqp->sq_ring), cqp->dev->cqp_db); 324762306a36Sopenharmony_ci 324862306a36Sopenharmony_ci ibdev_dbg(to_ibdev(cqp->dev), 324962306a36Sopenharmony_ci "WQE: CQP SQ head 0x%x tail 0x%x size 0x%x\n", 325062306a36Sopenharmony_ci cqp->sq_ring.head, cqp->sq_ring.tail, cqp->sq_ring.size); 325162306a36Sopenharmony_ci} 325262306a36Sopenharmony_ci 325362306a36Sopenharmony_ci/** 325462306a36Sopenharmony_ci * irdma_sc_cqp_get_next_send_wqe_idx - get next wqe on cqp sq 325562306a36Sopenharmony_ci * and pass back index 325662306a36Sopenharmony_ci * @cqp: CQP HW structure 325762306a36Sopenharmony_ci * @scratch: private data for CQP WQE 325862306a36Sopenharmony_ci * @wqe_idx: WQE index of CQP SQ 325962306a36Sopenharmony_ci */ 326062306a36Sopenharmony_ci__le64 *irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratch, 326162306a36Sopenharmony_ci u32 *wqe_idx) 326262306a36Sopenharmony_ci{ 326362306a36Sopenharmony_ci __le64 *wqe = NULL; 326462306a36Sopenharmony_ci int ret_code; 326562306a36Sopenharmony_ci 326662306a36Sopenharmony_ci if (IRDMA_RING_FULL_ERR(cqp->sq_ring)) { 326762306a36Sopenharmony_ci ibdev_dbg(to_ibdev(cqp->dev), 326862306a36Sopenharmony_ci "WQE: CQP SQ is full, head 0x%x tail 0x%x size 0x%x\n", 326962306a36Sopenharmony_ci cqp->sq_ring.head, cqp->sq_ring.tail, 327062306a36Sopenharmony_ci cqp->sq_ring.size); 327162306a36Sopenharmony_ci return NULL; 327262306a36Sopenharmony_ci } 327362306a36Sopenharmony_ci IRDMA_ATOMIC_RING_MOVE_HEAD(cqp->sq_ring, *wqe_idx, ret_code); 327462306a36Sopenharmony_ci if (ret_code) 327562306a36Sopenharmony_ci return NULL; 327662306a36Sopenharmony_ci 327762306a36Sopenharmony_ci cqp->requested_ops++; 327862306a36Sopenharmony_ci if (!*wqe_idx) 327962306a36Sopenharmony_ci cqp->polarity = !cqp->polarity; 328062306a36Sopenharmony_ci wqe = cqp->sq_base[*wqe_idx].elem; 328162306a36Sopenharmony_ci cqp->scratch_array[*wqe_idx] = scratch; 328262306a36Sopenharmony_ci IRDMA_CQP_INIT_WQE(wqe); 328362306a36Sopenharmony_ci 328462306a36Sopenharmony_ci return wqe; 328562306a36Sopenharmony_ci} 328662306a36Sopenharmony_ci 328762306a36Sopenharmony_ci/** 328862306a36Sopenharmony_ci * irdma_sc_cqp_destroy - destroy cqp during close 328962306a36Sopenharmony_ci * @cqp: struct for cqp hw 329062306a36Sopenharmony_ci */ 329162306a36Sopenharmony_ciint irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp) 329262306a36Sopenharmony_ci{ 329362306a36Sopenharmony_ci u32 cnt = 0, val; 329462306a36Sopenharmony_ci int ret_code = 0; 329562306a36Sopenharmony_ci 329662306a36Sopenharmony_ci writel(0, cqp->dev->hw_regs[IRDMA_CCQPHIGH]); 329762306a36Sopenharmony_ci writel(0, cqp->dev->hw_regs[IRDMA_CCQPLOW]); 329862306a36Sopenharmony_ci do { 329962306a36Sopenharmony_ci if (cnt++ > cqp->dev->hw_attrs.max_done_count) { 330062306a36Sopenharmony_ci ret_code = -ETIMEDOUT; 330162306a36Sopenharmony_ci break; 330262306a36Sopenharmony_ci } 330362306a36Sopenharmony_ci udelay(cqp->dev->hw_attrs.max_sleep_count); 330462306a36Sopenharmony_ci val = readl(cqp->dev->hw_regs[IRDMA_CCQPSTATUS]); 330562306a36Sopenharmony_ci } while (FLD_RS_32(cqp->dev, val, IRDMA_CCQPSTATUS_CCQP_DONE)); 330662306a36Sopenharmony_ci 330762306a36Sopenharmony_ci dma_free_coherent(cqp->dev->hw->device, cqp->sdbuf.size, 330862306a36Sopenharmony_ci cqp->sdbuf.va, cqp->sdbuf.pa); 330962306a36Sopenharmony_ci cqp->sdbuf.va = NULL; 331062306a36Sopenharmony_ci return ret_code; 331162306a36Sopenharmony_ci} 331262306a36Sopenharmony_ci 331362306a36Sopenharmony_ci/** 331462306a36Sopenharmony_ci * irdma_sc_ccq_arm - enable intr for control cq 331562306a36Sopenharmony_ci * @ccq: ccq sc struct 331662306a36Sopenharmony_ci */ 331762306a36Sopenharmony_civoid irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) 331862306a36Sopenharmony_ci{ 331962306a36Sopenharmony_ci u64 temp_val; 332062306a36Sopenharmony_ci u16 sw_cq_sel; 332162306a36Sopenharmony_ci u8 arm_next_se; 332262306a36Sopenharmony_ci u8 arm_seq_num; 332362306a36Sopenharmony_ci 332462306a36Sopenharmony_ci get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val); 332562306a36Sopenharmony_ci sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); 332662306a36Sopenharmony_ci arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); 332762306a36Sopenharmony_ci arm_seq_num = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_SEQ_NUM, temp_val); 332862306a36Sopenharmony_ci arm_seq_num++; 332962306a36Sopenharmony_ci temp_val = FIELD_PREP(IRDMA_CQ_DBSA_ARM_SEQ_NUM, arm_seq_num) | 333062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQ_DBSA_SW_CQ_SELECT, sw_cq_sel) | 333162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | 333262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1); 333362306a36Sopenharmony_ci set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val); 333462306a36Sopenharmony_ci 333562306a36Sopenharmony_ci dma_wmb(); /* make sure shadow area is updated before arming */ 333662306a36Sopenharmony_ci 333762306a36Sopenharmony_ci writel(ccq->cq_uk.cq_id, ccq->dev->cq_arm_db); 333862306a36Sopenharmony_ci} 333962306a36Sopenharmony_ci 334062306a36Sopenharmony_ci/** 334162306a36Sopenharmony_ci * irdma_sc_ccq_get_cqe_info - get ccq's cq entry 334262306a36Sopenharmony_ci * @ccq: ccq sc struct 334362306a36Sopenharmony_ci * @info: completion q entry to return 334462306a36Sopenharmony_ci */ 334562306a36Sopenharmony_ciint irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq, 334662306a36Sopenharmony_ci struct irdma_ccq_cqe_info *info) 334762306a36Sopenharmony_ci{ 334862306a36Sopenharmony_ci u64 qp_ctx, temp, temp1; 334962306a36Sopenharmony_ci __le64 *cqe; 335062306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 335162306a36Sopenharmony_ci u32 wqe_idx; 335262306a36Sopenharmony_ci u32 error; 335362306a36Sopenharmony_ci u8 polarity; 335462306a36Sopenharmony_ci int ret_code = 0; 335562306a36Sopenharmony_ci 335662306a36Sopenharmony_ci if (ccq->cq_uk.avoid_mem_cflct) 335762306a36Sopenharmony_ci cqe = IRDMA_GET_CURRENT_EXTENDED_CQ_ELEM(&ccq->cq_uk); 335862306a36Sopenharmony_ci else 335962306a36Sopenharmony_ci cqe = IRDMA_GET_CURRENT_CQ_ELEM(&ccq->cq_uk); 336062306a36Sopenharmony_ci 336162306a36Sopenharmony_ci get_64bit_val(cqe, 24, &temp); 336262306a36Sopenharmony_ci polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, temp); 336362306a36Sopenharmony_ci if (polarity != ccq->cq_uk.polarity) 336462306a36Sopenharmony_ci return -ENOENT; 336562306a36Sopenharmony_ci 336662306a36Sopenharmony_ci /* Ensure CEQE contents are read after valid bit is checked */ 336762306a36Sopenharmony_ci dma_rmb(); 336862306a36Sopenharmony_ci 336962306a36Sopenharmony_ci get_64bit_val(cqe, 8, &qp_ctx); 337062306a36Sopenharmony_ci cqp = (struct irdma_sc_cqp *)(unsigned long)qp_ctx; 337162306a36Sopenharmony_ci info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, temp); 337262306a36Sopenharmony_ci info->maj_err_code = IRDMA_CQPSQ_MAJ_NO_ERROR; 337362306a36Sopenharmony_ci info->min_err_code = (u16)FIELD_GET(IRDMA_CQ_MINERR, temp); 337462306a36Sopenharmony_ci if (info->error) { 337562306a36Sopenharmony_ci info->maj_err_code = (u16)FIELD_GET(IRDMA_CQ_MAJERR, temp); 337662306a36Sopenharmony_ci error = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]); 337762306a36Sopenharmony_ci ibdev_dbg(to_ibdev(cqp->dev), 337862306a36Sopenharmony_ci "CQP: CQPERRCODES error_code[x%08X]\n", error); 337962306a36Sopenharmony_ci } 338062306a36Sopenharmony_ci 338162306a36Sopenharmony_ci wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, temp); 338262306a36Sopenharmony_ci info->scratch = cqp->scratch_array[wqe_idx]; 338362306a36Sopenharmony_ci 338462306a36Sopenharmony_ci get_64bit_val(cqe, 16, &temp1); 338562306a36Sopenharmony_ci info->op_ret_val = (u32)FIELD_GET(IRDMA_CCQ_OPRETVAL, temp1); 338662306a36Sopenharmony_ci get_64bit_val(cqp->sq_base[wqe_idx].elem, 24, &temp1); 338762306a36Sopenharmony_ci info->op_code = (u8)FIELD_GET(IRDMA_CQPSQ_OPCODE, temp1); 338862306a36Sopenharmony_ci info->cqp = cqp; 338962306a36Sopenharmony_ci 339062306a36Sopenharmony_ci /* move the head for cq */ 339162306a36Sopenharmony_ci IRDMA_RING_MOVE_HEAD(ccq->cq_uk.cq_ring, ret_code); 339262306a36Sopenharmony_ci if (!IRDMA_RING_CURRENT_HEAD(ccq->cq_uk.cq_ring)) 339362306a36Sopenharmony_ci ccq->cq_uk.polarity ^= 1; 339462306a36Sopenharmony_ci 339562306a36Sopenharmony_ci /* update cq tail in cq shadow memory also */ 339662306a36Sopenharmony_ci IRDMA_RING_MOVE_TAIL(ccq->cq_uk.cq_ring); 339762306a36Sopenharmony_ci set_64bit_val(ccq->cq_uk.shadow_area, 0, 339862306a36Sopenharmony_ci IRDMA_RING_CURRENT_HEAD(ccq->cq_uk.cq_ring)); 339962306a36Sopenharmony_ci 340062306a36Sopenharmony_ci dma_wmb(); /* make sure shadow area is updated before moving tail */ 340162306a36Sopenharmony_ci 340262306a36Sopenharmony_ci IRDMA_RING_MOVE_TAIL(cqp->sq_ring); 340362306a36Sopenharmony_ci atomic64_inc(&cqp->completed_ops); 340462306a36Sopenharmony_ci 340562306a36Sopenharmony_ci return ret_code; 340662306a36Sopenharmony_ci} 340762306a36Sopenharmony_ci 340862306a36Sopenharmony_ci/** 340962306a36Sopenharmony_ci * irdma_sc_poll_for_cqp_op_done - Waits for last write to complete in CQP SQ 341062306a36Sopenharmony_ci * @cqp: struct for cqp hw 341162306a36Sopenharmony_ci * @op_code: cqp opcode for completion 341262306a36Sopenharmony_ci * @compl_info: completion q entry to return 341362306a36Sopenharmony_ci */ 341462306a36Sopenharmony_ciint irdma_sc_poll_for_cqp_op_done(struct irdma_sc_cqp *cqp, u8 op_code, 341562306a36Sopenharmony_ci struct irdma_ccq_cqe_info *compl_info) 341662306a36Sopenharmony_ci{ 341762306a36Sopenharmony_ci struct irdma_ccq_cqe_info info = {}; 341862306a36Sopenharmony_ci struct irdma_sc_cq *ccq; 341962306a36Sopenharmony_ci int ret_code = 0; 342062306a36Sopenharmony_ci u32 cnt = 0; 342162306a36Sopenharmony_ci 342262306a36Sopenharmony_ci ccq = cqp->dev->ccq; 342362306a36Sopenharmony_ci while (1) { 342462306a36Sopenharmony_ci if (cnt++ > 100 * cqp->dev->hw_attrs.max_done_count) 342562306a36Sopenharmony_ci return -ETIMEDOUT; 342662306a36Sopenharmony_ci 342762306a36Sopenharmony_ci if (irdma_sc_ccq_get_cqe_info(ccq, &info)) { 342862306a36Sopenharmony_ci udelay(cqp->dev->hw_attrs.max_sleep_count); 342962306a36Sopenharmony_ci continue; 343062306a36Sopenharmony_ci } 343162306a36Sopenharmony_ci if (info.error && info.op_code != IRDMA_CQP_OP_QUERY_STAG) { 343262306a36Sopenharmony_ci ret_code = -EIO; 343362306a36Sopenharmony_ci break; 343462306a36Sopenharmony_ci } 343562306a36Sopenharmony_ci /* make sure op code matches*/ 343662306a36Sopenharmony_ci if (op_code == info.op_code) 343762306a36Sopenharmony_ci break; 343862306a36Sopenharmony_ci ibdev_dbg(to_ibdev(cqp->dev), 343962306a36Sopenharmony_ci "WQE: opcode mismatch for my op code 0x%x, returned opcode %x\n", 344062306a36Sopenharmony_ci op_code, info.op_code); 344162306a36Sopenharmony_ci } 344262306a36Sopenharmony_ci 344362306a36Sopenharmony_ci if (compl_info) 344462306a36Sopenharmony_ci memcpy(compl_info, &info, sizeof(*compl_info)); 344562306a36Sopenharmony_ci 344662306a36Sopenharmony_ci return ret_code; 344762306a36Sopenharmony_ci} 344862306a36Sopenharmony_ci 344962306a36Sopenharmony_ci/** 345062306a36Sopenharmony_ci * irdma_sc_manage_hmc_pm_func_table - manage of function table 345162306a36Sopenharmony_ci * @cqp: struct for cqp hw 345262306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 345362306a36Sopenharmony_ci * @info: info for the manage function table operation 345462306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 345562306a36Sopenharmony_ci */ 345662306a36Sopenharmony_cistatic int irdma_sc_manage_hmc_pm_func_table(struct irdma_sc_cqp *cqp, 345762306a36Sopenharmony_ci struct irdma_hmc_fcn_info *info, 345862306a36Sopenharmony_ci u64 scratch, bool post_sq) 345962306a36Sopenharmony_ci{ 346062306a36Sopenharmony_ci __le64 *wqe; 346162306a36Sopenharmony_ci u64 hdr; 346262306a36Sopenharmony_ci 346362306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 346462306a36Sopenharmony_ci if (!wqe) 346562306a36Sopenharmony_ci return -ENOMEM; 346662306a36Sopenharmony_ci 346762306a36Sopenharmony_ci set_64bit_val(wqe, 0, 0); 346862306a36Sopenharmony_ci set_64bit_val(wqe, 8, 0); 346962306a36Sopenharmony_ci set_64bit_val(wqe, 16, 0); 347062306a36Sopenharmony_ci set_64bit_val(wqe, 32, 0); 347162306a36Sopenharmony_ci set_64bit_val(wqe, 40, 0); 347262306a36Sopenharmony_ci set_64bit_val(wqe, 48, 0); 347362306a36Sopenharmony_ci set_64bit_val(wqe, 56, 0); 347462306a36Sopenharmony_ci 347562306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_MHMC_VFIDX, info->vf_id) | 347662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, 347762306a36Sopenharmony_ci IRDMA_CQP_OP_MANAGE_HMC_PM_FUNC_TABLE) | 347862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_MHMC_FREEPMFN, info->free_fcn) | 347962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 348062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 348162306a36Sopenharmony_ci 348262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 348362306a36Sopenharmony_ci 348462306a36Sopenharmony_ci print_hex_dump_debug("WQE: MANAGE_HMC_PM_FUNC_TABLE WQE", 348562306a36Sopenharmony_ci DUMP_PREFIX_OFFSET, 16, 8, wqe, 348662306a36Sopenharmony_ci IRDMA_CQP_WQE_SIZE * 8, false); 348762306a36Sopenharmony_ci if (post_sq) 348862306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 348962306a36Sopenharmony_ci 349062306a36Sopenharmony_ci return 0; 349162306a36Sopenharmony_ci} 349262306a36Sopenharmony_ci 349362306a36Sopenharmony_ci/** 349462306a36Sopenharmony_ci * irdma_sc_commit_fpm_val_done - wait for cqp eqe completion 349562306a36Sopenharmony_ci * for fpm commit 349662306a36Sopenharmony_ci * @cqp: struct for cqp hw 349762306a36Sopenharmony_ci */ 349862306a36Sopenharmony_cistatic int irdma_sc_commit_fpm_val_done(struct irdma_sc_cqp *cqp) 349962306a36Sopenharmony_ci{ 350062306a36Sopenharmony_ci return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_COMMIT_FPM_VAL, 350162306a36Sopenharmony_ci NULL); 350262306a36Sopenharmony_ci} 350362306a36Sopenharmony_ci 350462306a36Sopenharmony_ci/** 350562306a36Sopenharmony_ci * irdma_sc_commit_fpm_val - cqp wqe for commit fpm values 350662306a36Sopenharmony_ci * @cqp: struct for cqp hw 350762306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 350862306a36Sopenharmony_ci * @hmc_fn_id: hmc function id 350962306a36Sopenharmony_ci * @commit_fpm_mem: Memory for fpm values 351062306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 351162306a36Sopenharmony_ci * @wait_type: poll ccq or cqp registers for cqp completion 351262306a36Sopenharmony_ci */ 351362306a36Sopenharmony_cistatic int irdma_sc_commit_fpm_val(struct irdma_sc_cqp *cqp, u64 scratch, 351462306a36Sopenharmony_ci u8 hmc_fn_id, 351562306a36Sopenharmony_ci struct irdma_dma_mem *commit_fpm_mem, 351662306a36Sopenharmony_ci bool post_sq, u8 wait_type) 351762306a36Sopenharmony_ci{ 351862306a36Sopenharmony_ci __le64 *wqe; 351962306a36Sopenharmony_ci u64 hdr; 352062306a36Sopenharmony_ci u32 tail, val, error; 352162306a36Sopenharmony_ci int ret_code = 0; 352262306a36Sopenharmony_ci 352362306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 352462306a36Sopenharmony_ci if (!wqe) 352562306a36Sopenharmony_ci return -ENOMEM; 352662306a36Sopenharmony_ci 352762306a36Sopenharmony_ci set_64bit_val(wqe, 16, hmc_fn_id); 352862306a36Sopenharmony_ci set_64bit_val(wqe, 32, commit_fpm_mem->pa); 352962306a36Sopenharmony_ci 353062306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_BUFSIZE, IRDMA_COMMIT_FPM_BUF_SIZE) | 353162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_COMMIT_FPM_VAL) | 353262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 353362306a36Sopenharmony_ci 353462306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 353562306a36Sopenharmony_ci 353662306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 353762306a36Sopenharmony_ci 353862306a36Sopenharmony_ci print_hex_dump_debug("WQE: COMMIT_FPM_VAL WQE", DUMP_PREFIX_OFFSET, 353962306a36Sopenharmony_ci 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 354062306a36Sopenharmony_ci irdma_get_cqp_reg_info(cqp, &val, &tail, &error); 354162306a36Sopenharmony_ci 354262306a36Sopenharmony_ci if (post_sq) { 354362306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 354462306a36Sopenharmony_ci if (wait_type == IRDMA_CQP_WAIT_POLL_REGS) 354562306a36Sopenharmony_ci ret_code = irdma_cqp_poll_registers(cqp, tail, 354662306a36Sopenharmony_ci cqp->dev->hw_attrs.max_done_count); 354762306a36Sopenharmony_ci else if (wait_type == IRDMA_CQP_WAIT_POLL_CQ) 354862306a36Sopenharmony_ci ret_code = irdma_sc_commit_fpm_val_done(cqp); 354962306a36Sopenharmony_ci } 355062306a36Sopenharmony_ci 355162306a36Sopenharmony_ci return ret_code; 355262306a36Sopenharmony_ci} 355362306a36Sopenharmony_ci 355462306a36Sopenharmony_ci/** 355562306a36Sopenharmony_ci * irdma_sc_query_fpm_val_done - poll for cqp wqe completion for 355662306a36Sopenharmony_ci * query fpm 355762306a36Sopenharmony_ci * @cqp: struct for cqp hw 355862306a36Sopenharmony_ci */ 355962306a36Sopenharmony_cistatic int irdma_sc_query_fpm_val_done(struct irdma_sc_cqp *cqp) 356062306a36Sopenharmony_ci{ 356162306a36Sopenharmony_ci return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_QUERY_FPM_VAL, 356262306a36Sopenharmony_ci NULL); 356362306a36Sopenharmony_ci} 356462306a36Sopenharmony_ci 356562306a36Sopenharmony_ci/** 356662306a36Sopenharmony_ci * irdma_sc_query_fpm_val - cqp wqe query fpm values 356762306a36Sopenharmony_ci * @cqp: struct for cqp hw 356862306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 356962306a36Sopenharmony_ci * @hmc_fn_id: hmc function id 357062306a36Sopenharmony_ci * @query_fpm_mem: memory for return fpm values 357162306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 357262306a36Sopenharmony_ci * @wait_type: poll ccq or cqp registers for cqp completion 357362306a36Sopenharmony_ci */ 357462306a36Sopenharmony_cistatic int irdma_sc_query_fpm_val(struct irdma_sc_cqp *cqp, u64 scratch, 357562306a36Sopenharmony_ci u8 hmc_fn_id, 357662306a36Sopenharmony_ci struct irdma_dma_mem *query_fpm_mem, 357762306a36Sopenharmony_ci bool post_sq, u8 wait_type) 357862306a36Sopenharmony_ci{ 357962306a36Sopenharmony_ci __le64 *wqe; 358062306a36Sopenharmony_ci u64 hdr; 358162306a36Sopenharmony_ci u32 tail, val, error; 358262306a36Sopenharmony_ci int ret_code = 0; 358362306a36Sopenharmony_ci 358462306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 358562306a36Sopenharmony_ci if (!wqe) 358662306a36Sopenharmony_ci return -ENOMEM; 358762306a36Sopenharmony_ci 358862306a36Sopenharmony_ci set_64bit_val(wqe, 16, hmc_fn_id); 358962306a36Sopenharmony_ci set_64bit_val(wqe, 32, query_fpm_mem->pa); 359062306a36Sopenharmony_ci 359162306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_QUERY_FPM_VAL) | 359262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 359362306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 359462306a36Sopenharmony_ci 359562306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 359662306a36Sopenharmony_ci 359762306a36Sopenharmony_ci print_hex_dump_debug("WQE: QUERY_FPM WQE", DUMP_PREFIX_OFFSET, 16, 8, 359862306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 359962306a36Sopenharmony_ci irdma_get_cqp_reg_info(cqp, &val, &tail, &error); 360062306a36Sopenharmony_ci 360162306a36Sopenharmony_ci if (post_sq) { 360262306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 360362306a36Sopenharmony_ci if (wait_type == IRDMA_CQP_WAIT_POLL_REGS) 360462306a36Sopenharmony_ci ret_code = irdma_cqp_poll_registers(cqp, tail, 360562306a36Sopenharmony_ci cqp->dev->hw_attrs.max_done_count); 360662306a36Sopenharmony_ci else if (wait_type == IRDMA_CQP_WAIT_POLL_CQ) 360762306a36Sopenharmony_ci ret_code = irdma_sc_query_fpm_val_done(cqp); 360862306a36Sopenharmony_ci } 360962306a36Sopenharmony_ci 361062306a36Sopenharmony_ci return ret_code; 361162306a36Sopenharmony_ci} 361262306a36Sopenharmony_ci 361362306a36Sopenharmony_ci/** 361462306a36Sopenharmony_ci * irdma_sc_ceq_init - initialize ceq 361562306a36Sopenharmony_ci * @ceq: ceq sc structure 361662306a36Sopenharmony_ci * @info: ceq initialization info 361762306a36Sopenharmony_ci */ 361862306a36Sopenharmony_ciint irdma_sc_ceq_init(struct irdma_sc_ceq *ceq, 361962306a36Sopenharmony_ci struct irdma_ceq_init_info *info) 362062306a36Sopenharmony_ci{ 362162306a36Sopenharmony_ci u32 pble_obj_cnt; 362262306a36Sopenharmony_ci 362362306a36Sopenharmony_ci if (info->elem_cnt < info->dev->hw_attrs.min_hw_ceq_size || 362462306a36Sopenharmony_ci info->elem_cnt > info->dev->hw_attrs.max_hw_ceq_size) 362562306a36Sopenharmony_ci return -EINVAL; 362662306a36Sopenharmony_ci 362762306a36Sopenharmony_ci if (info->ceq_id >= info->dev->hmc_fpm_misc.max_ceqs) 362862306a36Sopenharmony_ci return -EINVAL; 362962306a36Sopenharmony_ci pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt; 363062306a36Sopenharmony_ci 363162306a36Sopenharmony_ci if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt) 363262306a36Sopenharmony_ci return -EINVAL; 363362306a36Sopenharmony_ci 363462306a36Sopenharmony_ci ceq->size = sizeof(*ceq); 363562306a36Sopenharmony_ci ceq->ceqe_base = (struct irdma_ceqe *)info->ceqe_base; 363662306a36Sopenharmony_ci ceq->ceq_id = info->ceq_id; 363762306a36Sopenharmony_ci ceq->dev = info->dev; 363862306a36Sopenharmony_ci ceq->elem_cnt = info->elem_cnt; 363962306a36Sopenharmony_ci ceq->ceq_elem_pa = info->ceqe_pa; 364062306a36Sopenharmony_ci ceq->virtual_map = info->virtual_map; 364162306a36Sopenharmony_ci ceq->itr_no_expire = info->itr_no_expire; 364262306a36Sopenharmony_ci ceq->reg_cq = info->reg_cq; 364362306a36Sopenharmony_ci ceq->reg_cq_size = 0; 364462306a36Sopenharmony_ci spin_lock_init(&ceq->req_cq_lock); 364562306a36Sopenharmony_ci ceq->pbl_chunk_size = (ceq->virtual_map ? info->pbl_chunk_size : 0); 364662306a36Sopenharmony_ci ceq->first_pm_pbl_idx = (ceq->virtual_map ? info->first_pm_pbl_idx : 0); 364762306a36Sopenharmony_ci ceq->pbl_list = (ceq->virtual_map ? info->pbl_list : NULL); 364862306a36Sopenharmony_ci ceq->tph_en = info->tph_en; 364962306a36Sopenharmony_ci ceq->tph_val = info->tph_val; 365062306a36Sopenharmony_ci ceq->vsi = info->vsi; 365162306a36Sopenharmony_ci ceq->polarity = 1; 365262306a36Sopenharmony_ci IRDMA_RING_INIT(ceq->ceq_ring, ceq->elem_cnt); 365362306a36Sopenharmony_ci ceq->dev->ceq[info->ceq_id] = ceq; 365462306a36Sopenharmony_ci 365562306a36Sopenharmony_ci return 0; 365662306a36Sopenharmony_ci} 365762306a36Sopenharmony_ci 365862306a36Sopenharmony_ci/** 365962306a36Sopenharmony_ci * irdma_sc_ceq_create - create ceq wqe 366062306a36Sopenharmony_ci * @ceq: ceq sc structure 366162306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 366262306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 366362306a36Sopenharmony_ci */ 366462306a36Sopenharmony_ci 366562306a36Sopenharmony_cistatic int irdma_sc_ceq_create(struct irdma_sc_ceq *ceq, u64 scratch, 366662306a36Sopenharmony_ci bool post_sq) 366762306a36Sopenharmony_ci{ 366862306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 366962306a36Sopenharmony_ci __le64 *wqe; 367062306a36Sopenharmony_ci u64 hdr; 367162306a36Sopenharmony_ci 367262306a36Sopenharmony_ci cqp = ceq->dev->cqp; 367362306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 367462306a36Sopenharmony_ci if (!wqe) 367562306a36Sopenharmony_ci return -ENOMEM; 367662306a36Sopenharmony_ci set_64bit_val(wqe, 16, ceq->elem_cnt); 367762306a36Sopenharmony_ci set_64bit_val(wqe, 32, 367862306a36Sopenharmony_ci (ceq->virtual_map ? 0 : ceq->ceq_elem_pa)); 367962306a36Sopenharmony_ci set_64bit_val(wqe, 48, 368062306a36Sopenharmony_ci (ceq->virtual_map ? ceq->first_pm_pbl_idx : 0)); 368162306a36Sopenharmony_ci set_64bit_val(wqe, 56, 368262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHVAL, ceq->tph_val) | 368362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_VSIIDX, ceq->vsi->vsi_idx)); 368462306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_CEQ_CEQID, ceq->ceq_id) | 368562306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_CEQ) | 368662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CEQ_LPBLSIZE, ceq->pbl_chunk_size) | 368762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CEQ_VMAP, ceq->virtual_map) | 368862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CEQ_ITRNOEXPIRE, ceq->itr_no_expire) | 368962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHEN, ceq->tph_en) | 369062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 369162306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 369262306a36Sopenharmony_ci 369362306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 369462306a36Sopenharmony_ci 369562306a36Sopenharmony_ci print_hex_dump_debug("WQE: CEQ_CREATE WQE", DUMP_PREFIX_OFFSET, 16, 8, 369662306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 369762306a36Sopenharmony_ci if (post_sq) 369862306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 369962306a36Sopenharmony_ci 370062306a36Sopenharmony_ci return 0; 370162306a36Sopenharmony_ci} 370262306a36Sopenharmony_ci 370362306a36Sopenharmony_ci/** 370462306a36Sopenharmony_ci * irdma_sc_cceq_create_done - poll for control ceq wqe to complete 370562306a36Sopenharmony_ci * @ceq: ceq sc structure 370662306a36Sopenharmony_ci */ 370762306a36Sopenharmony_cistatic int irdma_sc_cceq_create_done(struct irdma_sc_ceq *ceq) 370862306a36Sopenharmony_ci{ 370962306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 371062306a36Sopenharmony_ci 371162306a36Sopenharmony_ci cqp = ceq->dev->cqp; 371262306a36Sopenharmony_ci return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_CREATE_CEQ, 371362306a36Sopenharmony_ci NULL); 371462306a36Sopenharmony_ci} 371562306a36Sopenharmony_ci 371662306a36Sopenharmony_ci/** 371762306a36Sopenharmony_ci * irdma_sc_cceq_destroy_done - poll for destroy cceq to complete 371862306a36Sopenharmony_ci * @ceq: ceq sc structure 371962306a36Sopenharmony_ci */ 372062306a36Sopenharmony_ciint irdma_sc_cceq_destroy_done(struct irdma_sc_ceq *ceq) 372162306a36Sopenharmony_ci{ 372262306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 372362306a36Sopenharmony_ci 372462306a36Sopenharmony_ci if (ceq->reg_cq) 372562306a36Sopenharmony_ci irdma_sc_remove_cq_ctx(ceq, ceq->dev->ccq); 372662306a36Sopenharmony_ci 372762306a36Sopenharmony_ci cqp = ceq->dev->cqp; 372862306a36Sopenharmony_ci cqp->process_cqp_sds = irdma_update_sds_noccq; 372962306a36Sopenharmony_ci 373062306a36Sopenharmony_ci return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_DESTROY_CEQ, 373162306a36Sopenharmony_ci NULL); 373262306a36Sopenharmony_ci} 373362306a36Sopenharmony_ci 373462306a36Sopenharmony_ci/** 373562306a36Sopenharmony_ci * irdma_sc_cceq_create - create cceq 373662306a36Sopenharmony_ci * @ceq: ceq sc structure 373762306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 373862306a36Sopenharmony_ci */ 373962306a36Sopenharmony_ciint irdma_sc_cceq_create(struct irdma_sc_ceq *ceq, u64 scratch) 374062306a36Sopenharmony_ci{ 374162306a36Sopenharmony_ci int ret_code; 374262306a36Sopenharmony_ci struct irdma_sc_dev *dev = ceq->dev; 374362306a36Sopenharmony_ci 374462306a36Sopenharmony_ci dev->ccq->vsi = ceq->vsi; 374562306a36Sopenharmony_ci if (ceq->reg_cq) { 374662306a36Sopenharmony_ci ret_code = irdma_sc_add_cq_ctx(ceq, ceq->dev->ccq); 374762306a36Sopenharmony_ci if (ret_code) 374862306a36Sopenharmony_ci return ret_code; 374962306a36Sopenharmony_ci } 375062306a36Sopenharmony_ci 375162306a36Sopenharmony_ci ret_code = irdma_sc_ceq_create(ceq, scratch, true); 375262306a36Sopenharmony_ci if (!ret_code) 375362306a36Sopenharmony_ci return irdma_sc_cceq_create_done(ceq); 375462306a36Sopenharmony_ci 375562306a36Sopenharmony_ci return ret_code; 375662306a36Sopenharmony_ci} 375762306a36Sopenharmony_ci 375862306a36Sopenharmony_ci/** 375962306a36Sopenharmony_ci * irdma_sc_ceq_destroy - destroy ceq 376062306a36Sopenharmony_ci * @ceq: ceq sc structure 376162306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 376262306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 376362306a36Sopenharmony_ci */ 376462306a36Sopenharmony_ciint irdma_sc_ceq_destroy(struct irdma_sc_ceq *ceq, u64 scratch, bool post_sq) 376562306a36Sopenharmony_ci{ 376662306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 376762306a36Sopenharmony_ci __le64 *wqe; 376862306a36Sopenharmony_ci u64 hdr; 376962306a36Sopenharmony_ci 377062306a36Sopenharmony_ci cqp = ceq->dev->cqp; 377162306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 377262306a36Sopenharmony_ci if (!wqe) 377362306a36Sopenharmony_ci return -ENOMEM; 377462306a36Sopenharmony_ci 377562306a36Sopenharmony_ci set_64bit_val(wqe, 16, ceq->elem_cnt); 377662306a36Sopenharmony_ci set_64bit_val(wqe, 48, ceq->first_pm_pbl_idx); 377762306a36Sopenharmony_ci hdr = ceq->ceq_id | 377862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_CEQ) | 377962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CEQ_LPBLSIZE, ceq->pbl_chunk_size) | 378062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CEQ_VMAP, ceq->virtual_map) | 378162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHEN, ceq->tph_en) | 378262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 378362306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 378462306a36Sopenharmony_ci 378562306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 378662306a36Sopenharmony_ci 378762306a36Sopenharmony_ci print_hex_dump_debug("WQE: CEQ_DESTROY WQE", DUMP_PREFIX_OFFSET, 16, 378862306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 378962306a36Sopenharmony_ci if (post_sq) 379062306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 379162306a36Sopenharmony_ci 379262306a36Sopenharmony_ci return 0; 379362306a36Sopenharmony_ci} 379462306a36Sopenharmony_ci 379562306a36Sopenharmony_ci/** 379662306a36Sopenharmony_ci * irdma_sc_process_ceq - process ceq 379762306a36Sopenharmony_ci * @dev: sc device struct 379862306a36Sopenharmony_ci * @ceq: ceq sc structure 379962306a36Sopenharmony_ci * 380062306a36Sopenharmony_ci * It is expected caller serializes this function with cleanup_ceqes() 380162306a36Sopenharmony_ci * because these functions manipulate the same ceq 380262306a36Sopenharmony_ci */ 380362306a36Sopenharmony_civoid *irdma_sc_process_ceq(struct irdma_sc_dev *dev, struct irdma_sc_ceq *ceq) 380462306a36Sopenharmony_ci{ 380562306a36Sopenharmony_ci u64 temp; 380662306a36Sopenharmony_ci __le64 *ceqe; 380762306a36Sopenharmony_ci struct irdma_sc_cq *cq = NULL; 380862306a36Sopenharmony_ci struct irdma_sc_cq *temp_cq; 380962306a36Sopenharmony_ci u8 polarity; 381062306a36Sopenharmony_ci u32 cq_idx; 381162306a36Sopenharmony_ci unsigned long flags; 381262306a36Sopenharmony_ci 381362306a36Sopenharmony_ci do { 381462306a36Sopenharmony_ci cq_idx = 0; 381562306a36Sopenharmony_ci ceqe = IRDMA_GET_CURRENT_CEQ_ELEM(ceq); 381662306a36Sopenharmony_ci get_64bit_val(ceqe, 0, &temp); 381762306a36Sopenharmony_ci polarity = (u8)FIELD_GET(IRDMA_CEQE_VALID, temp); 381862306a36Sopenharmony_ci if (polarity != ceq->polarity) 381962306a36Sopenharmony_ci return NULL; 382062306a36Sopenharmony_ci 382162306a36Sopenharmony_ci temp_cq = (struct irdma_sc_cq *)(unsigned long)(temp << 1); 382262306a36Sopenharmony_ci if (!temp_cq) { 382362306a36Sopenharmony_ci cq_idx = IRDMA_INVALID_CQ_IDX; 382462306a36Sopenharmony_ci IRDMA_RING_MOVE_TAIL(ceq->ceq_ring); 382562306a36Sopenharmony_ci 382662306a36Sopenharmony_ci if (!IRDMA_RING_CURRENT_TAIL(ceq->ceq_ring)) 382762306a36Sopenharmony_ci ceq->polarity ^= 1; 382862306a36Sopenharmony_ci continue; 382962306a36Sopenharmony_ci } 383062306a36Sopenharmony_ci 383162306a36Sopenharmony_ci cq = temp_cq; 383262306a36Sopenharmony_ci if (ceq->reg_cq) { 383362306a36Sopenharmony_ci spin_lock_irqsave(&ceq->req_cq_lock, flags); 383462306a36Sopenharmony_ci cq_idx = irdma_sc_find_reg_cq(ceq, cq); 383562306a36Sopenharmony_ci spin_unlock_irqrestore(&ceq->req_cq_lock, flags); 383662306a36Sopenharmony_ci } 383762306a36Sopenharmony_ci 383862306a36Sopenharmony_ci IRDMA_RING_MOVE_TAIL(ceq->ceq_ring); 383962306a36Sopenharmony_ci if (!IRDMA_RING_CURRENT_TAIL(ceq->ceq_ring)) 384062306a36Sopenharmony_ci ceq->polarity ^= 1; 384162306a36Sopenharmony_ci } while (cq_idx == IRDMA_INVALID_CQ_IDX); 384262306a36Sopenharmony_ci 384362306a36Sopenharmony_ci if (cq) 384462306a36Sopenharmony_ci irdma_sc_cq_ack(cq); 384562306a36Sopenharmony_ci return cq; 384662306a36Sopenharmony_ci} 384762306a36Sopenharmony_ci 384862306a36Sopenharmony_ci/** 384962306a36Sopenharmony_ci * irdma_sc_cleanup_ceqes - clear the valid ceqes ctx matching the cq 385062306a36Sopenharmony_ci * @cq: cq for which the ceqes need to be cleaned up 385162306a36Sopenharmony_ci * @ceq: ceq ptr 385262306a36Sopenharmony_ci * 385362306a36Sopenharmony_ci * The function is called after the cq is destroyed to cleanup 385462306a36Sopenharmony_ci * its pending ceqe entries. It is expected caller serializes this 385562306a36Sopenharmony_ci * function with process_ceq() in interrupt context. 385662306a36Sopenharmony_ci */ 385762306a36Sopenharmony_civoid irdma_sc_cleanup_ceqes(struct irdma_sc_cq *cq, struct irdma_sc_ceq *ceq) 385862306a36Sopenharmony_ci{ 385962306a36Sopenharmony_ci struct irdma_sc_cq *next_cq; 386062306a36Sopenharmony_ci u8 ceq_polarity = ceq->polarity; 386162306a36Sopenharmony_ci __le64 *ceqe; 386262306a36Sopenharmony_ci u8 polarity; 386362306a36Sopenharmony_ci u64 temp; 386462306a36Sopenharmony_ci int next; 386562306a36Sopenharmony_ci u32 i; 386662306a36Sopenharmony_ci 386762306a36Sopenharmony_ci next = IRDMA_RING_GET_NEXT_TAIL(ceq->ceq_ring, 0); 386862306a36Sopenharmony_ci 386962306a36Sopenharmony_ci for (i = 1; i <= IRDMA_RING_SIZE(*ceq); i++) { 387062306a36Sopenharmony_ci ceqe = IRDMA_GET_CEQ_ELEM_AT_POS(ceq, next); 387162306a36Sopenharmony_ci 387262306a36Sopenharmony_ci get_64bit_val(ceqe, 0, &temp); 387362306a36Sopenharmony_ci polarity = (u8)FIELD_GET(IRDMA_CEQE_VALID, temp); 387462306a36Sopenharmony_ci if (polarity != ceq_polarity) 387562306a36Sopenharmony_ci return; 387662306a36Sopenharmony_ci 387762306a36Sopenharmony_ci next_cq = (struct irdma_sc_cq *)(unsigned long)(temp << 1); 387862306a36Sopenharmony_ci if (cq == next_cq) 387962306a36Sopenharmony_ci set_64bit_val(ceqe, 0, temp & IRDMA_CEQE_VALID); 388062306a36Sopenharmony_ci 388162306a36Sopenharmony_ci next = IRDMA_RING_GET_NEXT_TAIL(ceq->ceq_ring, i); 388262306a36Sopenharmony_ci if (!next) 388362306a36Sopenharmony_ci ceq_polarity ^= 1; 388462306a36Sopenharmony_ci } 388562306a36Sopenharmony_ci} 388662306a36Sopenharmony_ci 388762306a36Sopenharmony_ci/** 388862306a36Sopenharmony_ci * irdma_sc_aeq_init - initialize aeq 388962306a36Sopenharmony_ci * @aeq: aeq structure ptr 389062306a36Sopenharmony_ci * @info: aeq initialization info 389162306a36Sopenharmony_ci */ 389262306a36Sopenharmony_ciint irdma_sc_aeq_init(struct irdma_sc_aeq *aeq, 389362306a36Sopenharmony_ci struct irdma_aeq_init_info *info) 389462306a36Sopenharmony_ci{ 389562306a36Sopenharmony_ci u32 pble_obj_cnt; 389662306a36Sopenharmony_ci 389762306a36Sopenharmony_ci if (info->elem_cnt < info->dev->hw_attrs.min_hw_aeq_size || 389862306a36Sopenharmony_ci info->elem_cnt > info->dev->hw_attrs.max_hw_aeq_size) 389962306a36Sopenharmony_ci return -EINVAL; 390062306a36Sopenharmony_ci 390162306a36Sopenharmony_ci pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt; 390262306a36Sopenharmony_ci 390362306a36Sopenharmony_ci if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt) 390462306a36Sopenharmony_ci return -EINVAL; 390562306a36Sopenharmony_ci 390662306a36Sopenharmony_ci aeq->size = sizeof(*aeq); 390762306a36Sopenharmony_ci aeq->polarity = 1; 390862306a36Sopenharmony_ci aeq->aeqe_base = (struct irdma_sc_aeqe *)info->aeqe_base; 390962306a36Sopenharmony_ci aeq->dev = info->dev; 391062306a36Sopenharmony_ci aeq->elem_cnt = info->elem_cnt; 391162306a36Sopenharmony_ci aeq->aeq_elem_pa = info->aeq_elem_pa; 391262306a36Sopenharmony_ci IRDMA_RING_INIT(aeq->aeq_ring, aeq->elem_cnt); 391362306a36Sopenharmony_ci aeq->virtual_map = info->virtual_map; 391462306a36Sopenharmony_ci aeq->pbl_list = (aeq->virtual_map ? info->pbl_list : NULL); 391562306a36Sopenharmony_ci aeq->pbl_chunk_size = (aeq->virtual_map ? info->pbl_chunk_size : 0); 391662306a36Sopenharmony_ci aeq->first_pm_pbl_idx = (aeq->virtual_map ? info->first_pm_pbl_idx : 0); 391762306a36Sopenharmony_ci aeq->msix_idx = info->msix_idx; 391862306a36Sopenharmony_ci info->dev->aeq = aeq; 391962306a36Sopenharmony_ci 392062306a36Sopenharmony_ci return 0; 392162306a36Sopenharmony_ci} 392262306a36Sopenharmony_ci 392362306a36Sopenharmony_ci/** 392462306a36Sopenharmony_ci * irdma_sc_aeq_create - create aeq 392562306a36Sopenharmony_ci * @aeq: aeq structure ptr 392662306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 392762306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 392862306a36Sopenharmony_ci */ 392962306a36Sopenharmony_cistatic int irdma_sc_aeq_create(struct irdma_sc_aeq *aeq, u64 scratch, 393062306a36Sopenharmony_ci bool post_sq) 393162306a36Sopenharmony_ci{ 393262306a36Sopenharmony_ci __le64 *wqe; 393362306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 393462306a36Sopenharmony_ci u64 hdr; 393562306a36Sopenharmony_ci 393662306a36Sopenharmony_ci cqp = aeq->dev->cqp; 393762306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 393862306a36Sopenharmony_ci if (!wqe) 393962306a36Sopenharmony_ci return -ENOMEM; 394062306a36Sopenharmony_ci set_64bit_val(wqe, 16, aeq->elem_cnt); 394162306a36Sopenharmony_ci set_64bit_val(wqe, 32, 394262306a36Sopenharmony_ci (aeq->virtual_map ? 0 : aeq->aeq_elem_pa)); 394362306a36Sopenharmony_ci set_64bit_val(wqe, 48, 394462306a36Sopenharmony_ci (aeq->virtual_map ? aeq->first_pm_pbl_idx : 0)); 394562306a36Sopenharmony_ci 394662306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_CREATE_AEQ) | 394762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_AEQ_LPBLSIZE, aeq->pbl_chunk_size) | 394862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_AEQ_VMAP, aeq->virtual_map) | 394962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 395062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 395162306a36Sopenharmony_ci 395262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 395362306a36Sopenharmony_ci 395462306a36Sopenharmony_ci print_hex_dump_debug("WQE: AEQ_CREATE WQE", DUMP_PREFIX_OFFSET, 16, 8, 395562306a36Sopenharmony_ci wqe, IRDMA_CQP_WQE_SIZE * 8, false); 395662306a36Sopenharmony_ci if (post_sq) 395762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 395862306a36Sopenharmony_ci 395962306a36Sopenharmony_ci return 0; 396062306a36Sopenharmony_ci} 396162306a36Sopenharmony_ci 396262306a36Sopenharmony_ci/** 396362306a36Sopenharmony_ci * irdma_sc_aeq_destroy - destroy aeq during close 396462306a36Sopenharmony_ci * @aeq: aeq structure ptr 396562306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 396662306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 396762306a36Sopenharmony_ci */ 396862306a36Sopenharmony_cistatic int irdma_sc_aeq_destroy(struct irdma_sc_aeq *aeq, u64 scratch, 396962306a36Sopenharmony_ci bool post_sq) 397062306a36Sopenharmony_ci{ 397162306a36Sopenharmony_ci __le64 *wqe; 397262306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 397362306a36Sopenharmony_ci struct irdma_sc_dev *dev; 397462306a36Sopenharmony_ci u64 hdr; 397562306a36Sopenharmony_ci 397662306a36Sopenharmony_ci dev = aeq->dev; 397762306a36Sopenharmony_ci writel(0, dev->hw_regs[IRDMA_PFINT_AEQCTL]); 397862306a36Sopenharmony_ci 397962306a36Sopenharmony_ci cqp = dev->cqp; 398062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 398162306a36Sopenharmony_ci if (!wqe) 398262306a36Sopenharmony_ci return -ENOMEM; 398362306a36Sopenharmony_ci set_64bit_val(wqe, 16, aeq->elem_cnt); 398462306a36Sopenharmony_ci set_64bit_val(wqe, 48, aeq->first_pm_pbl_idx); 398562306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_AEQ) | 398662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_AEQ_LPBLSIZE, aeq->pbl_chunk_size) | 398762306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_AEQ_VMAP, aeq->virtual_map) | 398862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 398962306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 399062306a36Sopenharmony_ci 399162306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 399262306a36Sopenharmony_ci 399362306a36Sopenharmony_ci print_hex_dump_debug("WQE: AEQ_DESTROY WQE", DUMP_PREFIX_OFFSET, 16, 399462306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 399562306a36Sopenharmony_ci if (post_sq) 399662306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 399762306a36Sopenharmony_ci return 0; 399862306a36Sopenharmony_ci} 399962306a36Sopenharmony_ci 400062306a36Sopenharmony_ci/** 400162306a36Sopenharmony_ci * irdma_sc_get_next_aeqe - get next aeq entry 400262306a36Sopenharmony_ci * @aeq: aeq structure ptr 400362306a36Sopenharmony_ci * @info: aeqe info to be returned 400462306a36Sopenharmony_ci */ 400562306a36Sopenharmony_ciint irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq, 400662306a36Sopenharmony_ci struct irdma_aeqe_info *info) 400762306a36Sopenharmony_ci{ 400862306a36Sopenharmony_ci u64 temp, compl_ctx; 400962306a36Sopenharmony_ci __le64 *aeqe; 401062306a36Sopenharmony_ci u8 ae_src; 401162306a36Sopenharmony_ci u8 polarity; 401262306a36Sopenharmony_ci 401362306a36Sopenharmony_ci aeqe = IRDMA_GET_CURRENT_AEQ_ELEM(aeq); 401462306a36Sopenharmony_ci get_64bit_val(aeqe, 8, &temp); 401562306a36Sopenharmony_ci polarity = (u8)FIELD_GET(IRDMA_AEQE_VALID, temp); 401662306a36Sopenharmony_ci 401762306a36Sopenharmony_ci if (aeq->polarity != polarity) 401862306a36Sopenharmony_ci return -ENOENT; 401962306a36Sopenharmony_ci 402062306a36Sopenharmony_ci /* Ensure AEQE contents are read after valid bit is checked */ 402162306a36Sopenharmony_ci dma_rmb(); 402262306a36Sopenharmony_ci 402362306a36Sopenharmony_ci get_64bit_val(aeqe, 0, &compl_ctx); 402462306a36Sopenharmony_ci 402562306a36Sopenharmony_ci print_hex_dump_debug("WQE: AEQ_ENTRY WQE", DUMP_PREFIX_OFFSET, 16, 8, 402662306a36Sopenharmony_ci aeqe, 16, false); 402762306a36Sopenharmony_ci 402862306a36Sopenharmony_ci ae_src = (u8)FIELD_GET(IRDMA_AEQE_AESRC, temp); 402962306a36Sopenharmony_ci info->wqe_idx = (u16)FIELD_GET(IRDMA_AEQE_WQDESCIDX, temp); 403062306a36Sopenharmony_ci info->qp_cq_id = (u32)FIELD_GET(IRDMA_AEQE_QPCQID_LOW, temp) | 403162306a36Sopenharmony_ci ((u32)FIELD_GET(IRDMA_AEQE_QPCQID_HI, temp) << 18); 403262306a36Sopenharmony_ci info->ae_id = (u16)FIELD_GET(IRDMA_AEQE_AECODE, temp); 403362306a36Sopenharmony_ci info->tcp_state = (u8)FIELD_GET(IRDMA_AEQE_TCPSTATE, temp); 403462306a36Sopenharmony_ci info->iwarp_state = (u8)FIELD_GET(IRDMA_AEQE_IWSTATE, temp); 403562306a36Sopenharmony_ci info->q2_data_written = (u8)FIELD_GET(IRDMA_AEQE_Q2DATA, temp); 403662306a36Sopenharmony_ci info->aeqe_overflow = (bool)FIELD_GET(IRDMA_AEQE_OVERFLOW, temp); 403762306a36Sopenharmony_ci 403862306a36Sopenharmony_ci info->ae_src = ae_src; 403962306a36Sopenharmony_ci switch (info->ae_id) { 404062306a36Sopenharmony_ci case IRDMA_AE_PRIV_OPERATION_DENIED: 404162306a36Sopenharmony_ci case IRDMA_AE_AMP_INVALIDATE_TYPE1_MW: 404262306a36Sopenharmony_ci case IRDMA_AE_AMP_MWBIND_ZERO_BASED_TYPE1_MW: 404362306a36Sopenharmony_ci case IRDMA_AE_AMP_FASTREG_INVALID_PBL_HPS_CFG: 404462306a36Sopenharmony_ci case IRDMA_AE_AMP_FASTREG_PBLE_MISMATCH: 404562306a36Sopenharmony_ci case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG: 404662306a36Sopenharmony_ci case IRDMA_AE_UDA_XMIT_BAD_PD: 404762306a36Sopenharmony_ci case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT: 404862306a36Sopenharmony_ci case IRDMA_AE_BAD_CLOSE: 404962306a36Sopenharmony_ci case IRDMA_AE_RDMA_READ_WHILE_ORD_ZERO: 405062306a36Sopenharmony_ci case IRDMA_AE_STAG_ZERO_INVALID: 405162306a36Sopenharmony_ci case IRDMA_AE_IB_RREQ_AND_Q1_FULL: 405262306a36Sopenharmony_ci case IRDMA_AE_IB_INVALID_REQUEST: 405362306a36Sopenharmony_ci case IRDMA_AE_WQE_UNEXPECTED_OPCODE: 405462306a36Sopenharmony_ci case IRDMA_AE_IB_REMOTE_ACCESS_ERROR: 405562306a36Sopenharmony_ci case IRDMA_AE_IB_REMOTE_OP_ERROR: 405662306a36Sopenharmony_ci case IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION: 405762306a36Sopenharmony_ci case IRDMA_AE_DDP_UBE_INVALID_MO: 405862306a36Sopenharmony_ci case IRDMA_AE_DDP_UBE_INVALID_QN: 405962306a36Sopenharmony_ci case IRDMA_AE_DDP_NO_L_BIT: 406062306a36Sopenharmony_ci case IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION: 406162306a36Sopenharmony_ci case IRDMA_AE_RDMAP_ROE_UNEXPECTED_OPCODE: 406262306a36Sopenharmony_ci case IRDMA_AE_ROE_INVALID_RDMA_READ_REQUEST: 406362306a36Sopenharmony_ci case IRDMA_AE_ROE_INVALID_RDMA_WRITE_OR_READ_RESP: 406462306a36Sopenharmony_ci case IRDMA_AE_ROCE_RSP_LENGTH_ERROR: 406562306a36Sopenharmony_ci case IRDMA_AE_INVALID_ARP_ENTRY: 406662306a36Sopenharmony_ci case IRDMA_AE_INVALID_TCP_OPTION_RCVD: 406762306a36Sopenharmony_ci case IRDMA_AE_STALE_ARP_ENTRY: 406862306a36Sopenharmony_ci case IRDMA_AE_INVALID_AH_ENTRY: 406962306a36Sopenharmony_ci case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR: 407062306a36Sopenharmony_ci case IRDMA_AE_LLP_SEGMENT_TOO_SMALL: 407162306a36Sopenharmony_ci case IRDMA_AE_LLP_TOO_MANY_RETRIES: 407262306a36Sopenharmony_ci case IRDMA_AE_LLP_DOUBT_REACHABILITY: 407362306a36Sopenharmony_ci case IRDMA_AE_LLP_CONNECTION_ESTABLISHED: 407462306a36Sopenharmony_ci case IRDMA_AE_RESET_SENT: 407562306a36Sopenharmony_ci case IRDMA_AE_TERMINATE_SENT: 407662306a36Sopenharmony_ci case IRDMA_AE_RESET_NOT_SENT: 407762306a36Sopenharmony_ci case IRDMA_AE_LCE_QP_CATASTROPHIC: 407862306a36Sopenharmony_ci case IRDMA_AE_QP_SUSPEND_COMPLETE: 407962306a36Sopenharmony_ci case IRDMA_AE_UDA_L4LEN_INVALID: 408062306a36Sopenharmony_ci info->qp = true; 408162306a36Sopenharmony_ci info->compl_ctx = compl_ctx; 408262306a36Sopenharmony_ci break; 408362306a36Sopenharmony_ci case IRDMA_AE_LCE_CQ_CATASTROPHIC: 408462306a36Sopenharmony_ci info->cq = true; 408562306a36Sopenharmony_ci info->compl_ctx = compl_ctx << 1; 408662306a36Sopenharmony_ci ae_src = IRDMA_AE_SOURCE_RSVD; 408762306a36Sopenharmony_ci break; 408862306a36Sopenharmony_ci case IRDMA_AE_ROCE_EMPTY_MCG: 408962306a36Sopenharmony_ci case IRDMA_AE_ROCE_BAD_MC_IP_ADDR: 409062306a36Sopenharmony_ci case IRDMA_AE_ROCE_BAD_MC_QPID: 409162306a36Sopenharmony_ci case IRDMA_AE_MCG_QP_PROTOCOL_MISMATCH: 409262306a36Sopenharmony_ci fallthrough; 409362306a36Sopenharmony_ci case IRDMA_AE_LLP_CONNECTION_RESET: 409462306a36Sopenharmony_ci case IRDMA_AE_LLP_SYN_RECEIVED: 409562306a36Sopenharmony_ci case IRDMA_AE_LLP_FIN_RECEIVED: 409662306a36Sopenharmony_ci case IRDMA_AE_LLP_CLOSE_COMPLETE: 409762306a36Sopenharmony_ci case IRDMA_AE_LLP_TERMINATE_RECEIVED: 409862306a36Sopenharmony_ci case IRDMA_AE_RDMAP_ROE_BAD_LLP_CLOSE: 409962306a36Sopenharmony_ci ae_src = IRDMA_AE_SOURCE_RSVD; 410062306a36Sopenharmony_ci info->qp = true; 410162306a36Sopenharmony_ci info->compl_ctx = compl_ctx; 410262306a36Sopenharmony_ci break; 410362306a36Sopenharmony_ci default: 410462306a36Sopenharmony_ci break; 410562306a36Sopenharmony_ci } 410662306a36Sopenharmony_ci 410762306a36Sopenharmony_ci switch (ae_src) { 410862306a36Sopenharmony_ci case IRDMA_AE_SOURCE_RQ: 410962306a36Sopenharmony_ci case IRDMA_AE_SOURCE_RQ_0011: 411062306a36Sopenharmony_ci info->qp = true; 411162306a36Sopenharmony_ci info->rq = true; 411262306a36Sopenharmony_ci info->compl_ctx = compl_ctx; 411362306a36Sopenharmony_ci break; 411462306a36Sopenharmony_ci case IRDMA_AE_SOURCE_CQ: 411562306a36Sopenharmony_ci case IRDMA_AE_SOURCE_CQ_0110: 411662306a36Sopenharmony_ci case IRDMA_AE_SOURCE_CQ_1010: 411762306a36Sopenharmony_ci case IRDMA_AE_SOURCE_CQ_1110: 411862306a36Sopenharmony_ci info->cq = true; 411962306a36Sopenharmony_ci info->compl_ctx = compl_ctx << 1; 412062306a36Sopenharmony_ci break; 412162306a36Sopenharmony_ci case IRDMA_AE_SOURCE_SQ: 412262306a36Sopenharmony_ci case IRDMA_AE_SOURCE_SQ_0111: 412362306a36Sopenharmony_ci info->qp = true; 412462306a36Sopenharmony_ci info->sq = true; 412562306a36Sopenharmony_ci info->compl_ctx = compl_ctx; 412662306a36Sopenharmony_ci break; 412762306a36Sopenharmony_ci case IRDMA_AE_SOURCE_IN_RR_WR: 412862306a36Sopenharmony_ci case IRDMA_AE_SOURCE_IN_RR_WR_1011: 412962306a36Sopenharmony_ci info->qp = true; 413062306a36Sopenharmony_ci info->compl_ctx = compl_ctx; 413162306a36Sopenharmony_ci info->in_rdrsp_wr = true; 413262306a36Sopenharmony_ci break; 413362306a36Sopenharmony_ci case IRDMA_AE_SOURCE_OUT_RR: 413462306a36Sopenharmony_ci case IRDMA_AE_SOURCE_OUT_RR_1111: 413562306a36Sopenharmony_ci info->qp = true; 413662306a36Sopenharmony_ci info->compl_ctx = compl_ctx; 413762306a36Sopenharmony_ci info->out_rdrsp = true; 413862306a36Sopenharmony_ci break; 413962306a36Sopenharmony_ci case IRDMA_AE_SOURCE_RSVD: 414062306a36Sopenharmony_ci default: 414162306a36Sopenharmony_ci break; 414262306a36Sopenharmony_ci } 414362306a36Sopenharmony_ci 414462306a36Sopenharmony_ci IRDMA_RING_MOVE_TAIL(aeq->aeq_ring); 414562306a36Sopenharmony_ci if (!IRDMA_RING_CURRENT_TAIL(aeq->aeq_ring)) 414662306a36Sopenharmony_ci aeq->polarity ^= 1; 414762306a36Sopenharmony_ci 414862306a36Sopenharmony_ci return 0; 414962306a36Sopenharmony_ci} 415062306a36Sopenharmony_ci 415162306a36Sopenharmony_ci/** 415262306a36Sopenharmony_ci * irdma_sc_repost_aeq_entries - repost completed aeq entries 415362306a36Sopenharmony_ci * @dev: sc device struct 415462306a36Sopenharmony_ci * @count: allocate count 415562306a36Sopenharmony_ci */ 415662306a36Sopenharmony_civoid irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, u32 count) 415762306a36Sopenharmony_ci{ 415862306a36Sopenharmony_ci writel(count, dev->hw_regs[IRDMA_AEQALLOC]); 415962306a36Sopenharmony_ci} 416062306a36Sopenharmony_ci 416162306a36Sopenharmony_ci/** 416262306a36Sopenharmony_ci * irdma_sc_ccq_init - initialize control cq 416362306a36Sopenharmony_ci * @cq: sc's cq ctruct 416462306a36Sopenharmony_ci * @info: info for control cq initialization 416562306a36Sopenharmony_ci */ 416662306a36Sopenharmony_ciint irdma_sc_ccq_init(struct irdma_sc_cq *cq, struct irdma_ccq_init_info *info) 416762306a36Sopenharmony_ci{ 416862306a36Sopenharmony_ci u32 pble_obj_cnt; 416962306a36Sopenharmony_ci 417062306a36Sopenharmony_ci if (info->num_elem < info->dev->hw_attrs.uk_attrs.min_hw_cq_size || 417162306a36Sopenharmony_ci info->num_elem > info->dev->hw_attrs.uk_attrs.max_hw_cq_size) 417262306a36Sopenharmony_ci return -EINVAL; 417362306a36Sopenharmony_ci 417462306a36Sopenharmony_ci if (info->ceq_id >= info->dev->hmc_fpm_misc.max_ceqs) 417562306a36Sopenharmony_ci return -EINVAL; 417662306a36Sopenharmony_ci 417762306a36Sopenharmony_ci pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt; 417862306a36Sopenharmony_ci 417962306a36Sopenharmony_ci if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt) 418062306a36Sopenharmony_ci return -EINVAL; 418162306a36Sopenharmony_ci 418262306a36Sopenharmony_ci cq->cq_pa = info->cq_pa; 418362306a36Sopenharmony_ci cq->cq_uk.cq_base = info->cq_base; 418462306a36Sopenharmony_ci cq->shadow_area_pa = info->shadow_area_pa; 418562306a36Sopenharmony_ci cq->cq_uk.shadow_area = info->shadow_area; 418662306a36Sopenharmony_ci cq->shadow_read_threshold = info->shadow_read_threshold; 418762306a36Sopenharmony_ci cq->dev = info->dev; 418862306a36Sopenharmony_ci cq->ceq_id = info->ceq_id; 418962306a36Sopenharmony_ci cq->cq_uk.cq_size = info->num_elem; 419062306a36Sopenharmony_ci cq->cq_type = IRDMA_CQ_TYPE_CQP; 419162306a36Sopenharmony_ci cq->ceqe_mask = info->ceqe_mask; 419262306a36Sopenharmony_ci IRDMA_RING_INIT(cq->cq_uk.cq_ring, info->num_elem); 419362306a36Sopenharmony_ci cq->cq_uk.cq_id = 0; /* control cq is id 0 always */ 419462306a36Sopenharmony_ci cq->ceq_id_valid = info->ceq_id_valid; 419562306a36Sopenharmony_ci cq->tph_en = info->tph_en; 419662306a36Sopenharmony_ci cq->tph_val = info->tph_val; 419762306a36Sopenharmony_ci cq->cq_uk.avoid_mem_cflct = info->avoid_mem_cflct; 419862306a36Sopenharmony_ci cq->pbl_list = info->pbl_list; 419962306a36Sopenharmony_ci cq->virtual_map = info->virtual_map; 420062306a36Sopenharmony_ci cq->pbl_chunk_size = info->pbl_chunk_size; 420162306a36Sopenharmony_ci cq->first_pm_pbl_idx = info->first_pm_pbl_idx; 420262306a36Sopenharmony_ci cq->cq_uk.polarity = true; 420362306a36Sopenharmony_ci cq->vsi = info->vsi; 420462306a36Sopenharmony_ci cq->cq_uk.cq_ack_db = cq->dev->cq_ack_db; 420562306a36Sopenharmony_ci 420662306a36Sopenharmony_ci /* Only applicable to CQs other than CCQ so initialize to zero */ 420762306a36Sopenharmony_ci cq->cq_uk.cqe_alloc_db = NULL; 420862306a36Sopenharmony_ci 420962306a36Sopenharmony_ci info->dev->ccq = cq; 421062306a36Sopenharmony_ci return 0; 421162306a36Sopenharmony_ci} 421262306a36Sopenharmony_ci 421362306a36Sopenharmony_ci/** 421462306a36Sopenharmony_ci * irdma_sc_ccq_create_done - poll cqp for ccq create 421562306a36Sopenharmony_ci * @ccq: ccq sc struct 421662306a36Sopenharmony_ci */ 421762306a36Sopenharmony_cistatic inline int irdma_sc_ccq_create_done(struct irdma_sc_cq *ccq) 421862306a36Sopenharmony_ci{ 421962306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 422062306a36Sopenharmony_ci 422162306a36Sopenharmony_ci cqp = ccq->dev->cqp; 422262306a36Sopenharmony_ci 422362306a36Sopenharmony_ci return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_CREATE_CQ, NULL); 422462306a36Sopenharmony_ci} 422562306a36Sopenharmony_ci 422662306a36Sopenharmony_ci/** 422762306a36Sopenharmony_ci * irdma_sc_ccq_create - create control cq 422862306a36Sopenharmony_ci * @ccq: ccq sc struct 422962306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 423062306a36Sopenharmony_ci * @check_overflow: overlow flag for ccq 423162306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 423262306a36Sopenharmony_ci */ 423362306a36Sopenharmony_ciint irdma_sc_ccq_create(struct irdma_sc_cq *ccq, u64 scratch, 423462306a36Sopenharmony_ci bool check_overflow, bool post_sq) 423562306a36Sopenharmony_ci{ 423662306a36Sopenharmony_ci int ret_code; 423762306a36Sopenharmony_ci 423862306a36Sopenharmony_ci ret_code = irdma_sc_cq_create(ccq, scratch, check_overflow, post_sq); 423962306a36Sopenharmony_ci if (ret_code) 424062306a36Sopenharmony_ci return ret_code; 424162306a36Sopenharmony_ci 424262306a36Sopenharmony_ci if (post_sq) { 424362306a36Sopenharmony_ci ret_code = irdma_sc_ccq_create_done(ccq); 424462306a36Sopenharmony_ci if (ret_code) 424562306a36Sopenharmony_ci return ret_code; 424662306a36Sopenharmony_ci } 424762306a36Sopenharmony_ci ccq->dev->cqp->process_cqp_sds = irdma_cqp_sds_cmd; 424862306a36Sopenharmony_ci 424962306a36Sopenharmony_ci return 0; 425062306a36Sopenharmony_ci} 425162306a36Sopenharmony_ci 425262306a36Sopenharmony_ci/** 425362306a36Sopenharmony_ci * irdma_sc_ccq_destroy - destroy ccq during close 425462306a36Sopenharmony_ci * @ccq: ccq sc struct 425562306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 425662306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 425762306a36Sopenharmony_ci */ 425862306a36Sopenharmony_ciint irdma_sc_ccq_destroy(struct irdma_sc_cq *ccq, u64 scratch, bool post_sq) 425962306a36Sopenharmony_ci{ 426062306a36Sopenharmony_ci struct irdma_sc_cqp *cqp; 426162306a36Sopenharmony_ci __le64 *wqe; 426262306a36Sopenharmony_ci u64 hdr; 426362306a36Sopenharmony_ci int ret_code = 0; 426462306a36Sopenharmony_ci u32 tail, val, error; 426562306a36Sopenharmony_ci 426662306a36Sopenharmony_ci cqp = ccq->dev->cqp; 426762306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 426862306a36Sopenharmony_ci if (!wqe) 426962306a36Sopenharmony_ci return -ENOMEM; 427062306a36Sopenharmony_ci 427162306a36Sopenharmony_ci set_64bit_val(wqe, 0, ccq->cq_uk.cq_size); 427262306a36Sopenharmony_ci set_64bit_val(wqe, 8, (uintptr_t)ccq >> 1); 427362306a36Sopenharmony_ci set_64bit_val(wqe, 40, ccq->shadow_area_pa); 427462306a36Sopenharmony_ci 427562306a36Sopenharmony_ci hdr = ccq->cq_uk.cq_id | 427662306a36Sopenharmony_ci FLD_LS_64(ccq->dev, (ccq->ceq_id_valid ? ccq->ceq_id : 0), 427762306a36Sopenharmony_ci IRDMA_CQPSQ_CQ_CEQID) | 427862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DESTROY_CQ) | 427962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_ENCEQEMASK, ccq->ceqe_mask) | 428062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_CEQIDVALID, ccq->ceq_id_valid) | 428162306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_TPHEN, ccq->tph_en) | 428262306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT, ccq->cq_uk.avoid_mem_cflct) | 428362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 428462306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 428562306a36Sopenharmony_ci 428662306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 428762306a36Sopenharmony_ci 428862306a36Sopenharmony_ci print_hex_dump_debug("WQE: CCQ_DESTROY WQE", DUMP_PREFIX_OFFSET, 16, 428962306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 429062306a36Sopenharmony_ci irdma_get_cqp_reg_info(cqp, &val, &tail, &error); 429162306a36Sopenharmony_ci 429262306a36Sopenharmony_ci if (post_sq) { 429362306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 429462306a36Sopenharmony_ci ret_code = irdma_cqp_poll_registers(cqp, tail, 429562306a36Sopenharmony_ci cqp->dev->hw_attrs.max_done_count); 429662306a36Sopenharmony_ci } 429762306a36Sopenharmony_ci 429862306a36Sopenharmony_ci cqp->process_cqp_sds = irdma_update_sds_noccq; 429962306a36Sopenharmony_ci 430062306a36Sopenharmony_ci return ret_code; 430162306a36Sopenharmony_ci} 430262306a36Sopenharmony_ci 430362306a36Sopenharmony_ci/** 430462306a36Sopenharmony_ci * irdma_sc_init_iw_hmc() - queries fpm values using cqp and populates hmc_info 430562306a36Sopenharmony_ci * @dev : ptr to irdma_dev struct 430662306a36Sopenharmony_ci * @hmc_fn_id: hmc function id 430762306a36Sopenharmony_ci */ 430862306a36Sopenharmony_ciint irdma_sc_init_iw_hmc(struct irdma_sc_dev *dev, u8 hmc_fn_id) 430962306a36Sopenharmony_ci{ 431062306a36Sopenharmony_ci struct irdma_hmc_info *hmc_info; 431162306a36Sopenharmony_ci struct irdma_hmc_fpm_misc *hmc_fpm_misc; 431262306a36Sopenharmony_ci struct irdma_dma_mem query_fpm_mem; 431362306a36Sopenharmony_ci int ret_code = 0; 431462306a36Sopenharmony_ci u8 wait_type; 431562306a36Sopenharmony_ci 431662306a36Sopenharmony_ci hmc_info = dev->hmc_info; 431762306a36Sopenharmony_ci hmc_fpm_misc = &dev->hmc_fpm_misc; 431862306a36Sopenharmony_ci query_fpm_mem.pa = dev->fpm_query_buf_pa; 431962306a36Sopenharmony_ci query_fpm_mem.va = dev->fpm_query_buf; 432062306a36Sopenharmony_ci hmc_info->hmc_fn_id = hmc_fn_id; 432162306a36Sopenharmony_ci wait_type = (u8)IRDMA_CQP_WAIT_POLL_REGS; 432262306a36Sopenharmony_ci 432362306a36Sopenharmony_ci ret_code = irdma_sc_query_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id, 432462306a36Sopenharmony_ci &query_fpm_mem, true, wait_type); 432562306a36Sopenharmony_ci if (ret_code) 432662306a36Sopenharmony_ci return ret_code; 432762306a36Sopenharmony_ci 432862306a36Sopenharmony_ci /* parse the fpm_query_buf and fill hmc obj info */ 432962306a36Sopenharmony_ci ret_code = irdma_sc_parse_fpm_query_buf(dev, query_fpm_mem.va, hmc_info, 433062306a36Sopenharmony_ci hmc_fpm_misc); 433162306a36Sopenharmony_ci 433262306a36Sopenharmony_ci print_hex_dump_debug("HMC: QUERY FPM BUFFER", DUMP_PREFIX_OFFSET, 16, 433362306a36Sopenharmony_ci 8, query_fpm_mem.va, IRDMA_QUERY_FPM_BUF_SIZE, 433462306a36Sopenharmony_ci false); 433562306a36Sopenharmony_ci return ret_code; 433662306a36Sopenharmony_ci} 433762306a36Sopenharmony_ci 433862306a36Sopenharmony_ci/** 433962306a36Sopenharmony_ci * irdma_sc_cfg_iw_fpm() - commits hmc obj cnt values using cqp 434062306a36Sopenharmony_ci * command and populates fpm base address in hmc_info 434162306a36Sopenharmony_ci * @dev : ptr to irdma_dev struct 434262306a36Sopenharmony_ci * @hmc_fn_id: hmc function id 434362306a36Sopenharmony_ci */ 434462306a36Sopenharmony_cistatic int irdma_sc_cfg_iw_fpm(struct irdma_sc_dev *dev, u8 hmc_fn_id) 434562306a36Sopenharmony_ci{ 434662306a36Sopenharmony_ci struct irdma_hmc_info *hmc_info; 434762306a36Sopenharmony_ci struct irdma_hmc_obj_info *obj_info; 434862306a36Sopenharmony_ci __le64 *buf; 434962306a36Sopenharmony_ci struct irdma_dma_mem commit_fpm_mem; 435062306a36Sopenharmony_ci int ret_code = 0; 435162306a36Sopenharmony_ci u8 wait_type; 435262306a36Sopenharmony_ci 435362306a36Sopenharmony_ci hmc_info = dev->hmc_info; 435462306a36Sopenharmony_ci obj_info = hmc_info->hmc_obj; 435562306a36Sopenharmony_ci buf = dev->fpm_commit_buf; 435662306a36Sopenharmony_ci 435762306a36Sopenharmony_ci set_64bit_val(buf, 0, (u64)obj_info[IRDMA_HMC_IW_QP].cnt); 435862306a36Sopenharmony_ci set_64bit_val(buf, 8, (u64)obj_info[IRDMA_HMC_IW_CQ].cnt); 435962306a36Sopenharmony_ci set_64bit_val(buf, 16, (u64)0); /* RSRVD */ 436062306a36Sopenharmony_ci set_64bit_val(buf, 24, (u64)obj_info[IRDMA_HMC_IW_HTE].cnt); 436162306a36Sopenharmony_ci set_64bit_val(buf, 32, (u64)obj_info[IRDMA_HMC_IW_ARP].cnt); 436262306a36Sopenharmony_ci set_64bit_val(buf, 40, (u64)0); /* RSVD */ 436362306a36Sopenharmony_ci set_64bit_val(buf, 48, (u64)obj_info[IRDMA_HMC_IW_MR].cnt); 436462306a36Sopenharmony_ci set_64bit_val(buf, 56, (u64)obj_info[IRDMA_HMC_IW_XF].cnt); 436562306a36Sopenharmony_ci set_64bit_val(buf, 64, (u64)obj_info[IRDMA_HMC_IW_XFFL].cnt); 436662306a36Sopenharmony_ci set_64bit_val(buf, 72, (u64)obj_info[IRDMA_HMC_IW_Q1].cnt); 436762306a36Sopenharmony_ci set_64bit_val(buf, 80, (u64)obj_info[IRDMA_HMC_IW_Q1FL].cnt); 436862306a36Sopenharmony_ci set_64bit_val(buf, 88, 436962306a36Sopenharmony_ci (u64)obj_info[IRDMA_HMC_IW_TIMER].cnt); 437062306a36Sopenharmony_ci set_64bit_val(buf, 96, 437162306a36Sopenharmony_ci (u64)obj_info[IRDMA_HMC_IW_FSIMC].cnt); 437262306a36Sopenharmony_ci set_64bit_val(buf, 104, 437362306a36Sopenharmony_ci (u64)obj_info[IRDMA_HMC_IW_FSIAV].cnt); 437462306a36Sopenharmony_ci set_64bit_val(buf, 112, 437562306a36Sopenharmony_ci (u64)obj_info[IRDMA_HMC_IW_PBLE].cnt); 437662306a36Sopenharmony_ci set_64bit_val(buf, 120, (u64)0); /* RSVD */ 437762306a36Sopenharmony_ci set_64bit_val(buf, 128, (u64)obj_info[IRDMA_HMC_IW_RRF].cnt); 437862306a36Sopenharmony_ci set_64bit_val(buf, 136, 437962306a36Sopenharmony_ci (u64)obj_info[IRDMA_HMC_IW_RRFFL].cnt); 438062306a36Sopenharmony_ci set_64bit_val(buf, 144, (u64)obj_info[IRDMA_HMC_IW_HDR].cnt); 438162306a36Sopenharmony_ci set_64bit_val(buf, 152, (u64)obj_info[IRDMA_HMC_IW_MD].cnt); 438262306a36Sopenharmony_ci set_64bit_val(buf, 160, 438362306a36Sopenharmony_ci (u64)obj_info[IRDMA_HMC_IW_OOISC].cnt); 438462306a36Sopenharmony_ci set_64bit_val(buf, 168, 438562306a36Sopenharmony_ci (u64)obj_info[IRDMA_HMC_IW_OOISCFFL].cnt); 438662306a36Sopenharmony_ci 438762306a36Sopenharmony_ci commit_fpm_mem.pa = dev->fpm_commit_buf_pa; 438862306a36Sopenharmony_ci commit_fpm_mem.va = dev->fpm_commit_buf; 438962306a36Sopenharmony_ci 439062306a36Sopenharmony_ci wait_type = (u8)IRDMA_CQP_WAIT_POLL_REGS; 439162306a36Sopenharmony_ci print_hex_dump_debug("HMC: COMMIT FPM BUFFER", DUMP_PREFIX_OFFSET, 16, 439262306a36Sopenharmony_ci 8, commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE, 439362306a36Sopenharmony_ci false); 439462306a36Sopenharmony_ci ret_code = irdma_sc_commit_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id, 439562306a36Sopenharmony_ci &commit_fpm_mem, true, wait_type); 439662306a36Sopenharmony_ci if (!ret_code) 439762306a36Sopenharmony_ci irdma_sc_parse_fpm_commit_buf(dev, dev->fpm_commit_buf, 439862306a36Sopenharmony_ci hmc_info->hmc_obj, 439962306a36Sopenharmony_ci &hmc_info->sd_table.sd_cnt); 440062306a36Sopenharmony_ci print_hex_dump_debug("HMC: COMMIT FPM BUFFER", DUMP_PREFIX_OFFSET, 16, 440162306a36Sopenharmony_ci 8, commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE, 440262306a36Sopenharmony_ci false); 440362306a36Sopenharmony_ci 440462306a36Sopenharmony_ci return ret_code; 440562306a36Sopenharmony_ci} 440662306a36Sopenharmony_ci 440762306a36Sopenharmony_ci/** 440862306a36Sopenharmony_ci * cqp_sds_wqe_fill - fill cqp wqe doe sd 440962306a36Sopenharmony_ci * @cqp: struct for cqp hw 441062306a36Sopenharmony_ci * @info: sd info for wqe 441162306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 441262306a36Sopenharmony_ci */ 441362306a36Sopenharmony_cistatic int cqp_sds_wqe_fill(struct irdma_sc_cqp *cqp, 441462306a36Sopenharmony_ci struct irdma_update_sds_info *info, u64 scratch) 441562306a36Sopenharmony_ci{ 441662306a36Sopenharmony_ci u64 data; 441762306a36Sopenharmony_ci u64 hdr; 441862306a36Sopenharmony_ci __le64 *wqe; 441962306a36Sopenharmony_ci int mem_entries, wqe_entries; 442062306a36Sopenharmony_ci struct irdma_dma_mem *sdbuf = &cqp->sdbuf; 442162306a36Sopenharmony_ci u64 offset = 0; 442262306a36Sopenharmony_ci u32 wqe_idx; 442362306a36Sopenharmony_ci 442462306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe_idx(cqp, scratch, &wqe_idx); 442562306a36Sopenharmony_ci if (!wqe) 442662306a36Sopenharmony_ci return -ENOMEM; 442762306a36Sopenharmony_ci 442862306a36Sopenharmony_ci wqe_entries = (info->cnt > 3) ? 3 : info->cnt; 442962306a36Sopenharmony_ci mem_entries = info->cnt - wqe_entries; 443062306a36Sopenharmony_ci 443162306a36Sopenharmony_ci if (mem_entries) { 443262306a36Sopenharmony_ci offset = wqe_idx * IRDMA_UPDATE_SD_BUFF_SIZE; 443362306a36Sopenharmony_ci memcpy(((char *)sdbuf->va + offset), &info->entry[3], mem_entries << 4); 443462306a36Sopenharmony_ci 443562306a36Sopenharmony_ci data = (u64)sdbuf->pa + offset; 443662306a36Sopenharmony_ci } else { 443762306a36Sopenharmony_ci data = 0; 443862306a36Sopenharmony_ci } 443962306a36Sopenharmony_ci data |= FIELD_PREP(IRDMA_CQPSQ_UPESD_HMCFNID, info->hmc_fn_id); 444062306a36Sopenharmony_ci set_64bit_val(wqe, 16, data); 444162306a36Sopenharmony_ci 444262306a36Sopenharmony_ci switch (wqe_entries) { 444362306a36Sopenharmony_ci case 3: 444462306a36Sopenharmony_ci set_64bit_val(wqe, 48, 444562306a36Sopenharmony_ci (FIELD_PREP(IRDMA_CQPSQ_UPESD_SDCMD, info->entry[2].cmd) | 444662306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UPESD_ENTRY_VALID, 1))); 444762306a36Sopenharmony_ci 444862306a36Sopenharmony_ci set_64bit_val(wqe, 56, info->entry[2].data); 444962306a36Sopenharmony_ci fallthrough; 445062306a36Sopenharmony_ci case 2: 445162306a36Sopenharmony_ci set_64bit_val(wqe, 32, 445262306a36Sopenharmony_ci (FIELD_PREP(IRDMA_CQPSQ_UPESD_SDCMD, info->entry[1].cmd) | 445362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UPESD_ENTRY_VALID, 1))); 445462306a36Sopenharmony_ci 445562306a36Sopenharmony_ci set_64bit_val(wqe, 40, info->entry[1].data); 445662306a36Sopenharmony_ci fallthrough; 445762306a36Sopenharmony_ci case 1: 445862306a36Sopenharmony_ci set_64bit_val(wqe, 0, 445962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UPESD_SDCMD, info->entry[0].cmd)); 446062306a36Sopenharmony_ci 446162306a36Sopenharmony_ci set_64bit_val(wqe, 8, info->entry[0].data); 446262306a36Sopenharmony_ci break; 446362306a36Sopenharmony_ci default: 446462306a36Sopenharmony_ci break; 446562306a36Sopenharmony_ci } 446662306a36Sopenharmony_ci 446762306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_UPDATE_PE_SDS) | 446862306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity) | 446962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UPESD_ENTRY_COUNT, mem_entries); 447062306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 447162306a36Sopenharmony_ci 447262306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 447362306a36Sopenharmony_ci 447462306a36Sopenharmony_ci if (mem_entries) 447562306a36Sopenharmony_ci print_hex_dump_debug("WQE: UPDATE_PE_SDS WQE Buffer", 447662306a36Sopenharmony_ci DUMP_PREFIX_OFFSET, 16, 8, 447762306a36Sopenharmony_ci (char *)sdbuf->va + offset, 447862306a36Sopenharmony_ci mem_entries << 4, false); 447962306a36Sopenharmony_ci 448062306a36Sopenharmony_ci print_hex_dump_debug("WQE: UPDATE_PE_SDS WQE", DUMP_PREFIX_OFFSET, 16, 448162306a36Sopenharmony_ci 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 448262306a36Sopenharmony_ci 448362306a36Sopenharmony_ci return 0; 448462306a36Sopenharmony_ci} 448562306a36Sopenharmony_ci 448662306a36Sopenharmony_ci/** 448762306a36Sopenharmony_ci * irdma_update_pe_sds - cqp wqe for sd 448862306a36Sopenharmony_ci * @dev: ptr to irdma_dev struct 448962306a36Sopenharmony_ci * @info: sd info for sd's 449062306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 449162306a36Sopenharmony_ci */ 449262306a36Sopenharmony_cistatic int irdma_update_pe_sds(struct irdma_sc_dev *dev, 449362306a36Sopenharmony_ci struct irdma_update_sds_info *info, u64 scratch) 449462306a36Sopenharmony_ci{ 449562306a36Sopenharmony_ci struct irdma_sc_cqp *cqp = dev->cqp; 449662306a36Sopenharmony_ci int ret_code; 449762306a36Sopenharmony_ci 449862306a36Sopenharmony_ci ret_code = cqp_sds_wqe_fill(cqp, info, scratch); 449962306a36Sopenharmony_ci if (!ret_code) 450062306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 450162306a36Sopenharmony_ci 450262306a36Sopenharmony_ci return ret_code; 450362306a36Sopenharmony_ci} 450462306a36Sopenharmony_ci 450562306a36Sopenharmony_ci/** 450662306a36Sopenharmony_ci * irdma_update_sds_noccq - update sd before ccq created 450762306a36Sopenharmony_ci * @dev: sc device struct 450862306a36Sopenharmony_ci * @info: sd info for sd's 450962306a36Sopenharmony_ci */ 451062306a36Sopenharmony_ciint irdma_update_sds_noccq(struct irdma_sc_dev *dev, 451162306a36Sopenharmony_ci struct irdma_update_sds_info *info) 451262306a36Sopenharmony_ci{ 451362306a36Sopenharmony_ci u32 error, val, tail; 451462306a36Sopenharmony_ci struct irdma_sc_cqp *cqp = dev->cqp; 451562306a36Sopenharmony_ci int ret_code; 451662306a36Sopenharmony_ci 451762306a36Sopenharmony_ci ret_code = cqp_sds_wqe_fill(cqp, info, 0); 451862306a36Sopenharmony_ci if (ret_code) 451962306a36Sopenharmony_ci return ret_code; 452062306a36Sopenharmony_ci 452162306a36Sopenharmony_ci irdma_get_cqp_reg_info(cqp, &val, &tail, &error); 452262306a36Sopenharmony_ci 452362306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 452462306a36Sopenharmony_ci return irdma_cqp_poll_registers(cqp, tail, 452562306a36Sopenharmony_ci cqp->dev->hw_attrs.max_done_count); 452662306a36Sopenharmony_ci} 452762306a36Sopenharmony_ci 452862306a36Sopenharmony_ci/** 452962306a36Sopenharmony_ci * irdma_sc_static_hmc_pages_allocated - cqp wqe to allocate hmc pages 453062306a36Sopenharmony_ci * @cqp: struct for cqp hw 453162306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 453262306a36Sopenharmony_ci * @hmc_fn_id: hmc function id 453362306a36Sopenharmony_ci * @post_sq: flag for cqp db to ring 453462306a36Sopenharmony_ci * @poll_registers: flag to poll register for cqp completion 453562306a36Sopenharmony_ci */ 453662306a36Sopenharmony_ciint irdma_sc_static_hmc_pages_allocated(struct irdma_sc_cqp *cqp, u64 scratch, 453762306a36Sopenharmony_ci u8 hmc_fn_id, bool post_sq, 453862306a36Sopenharmony_ci bool poll_registers) 453962306a36Sopenharmony_ci{ 454062306a36Sopenharmony_ci u64 hdr; 454162306a36Sopenharmony_ci __le64 *wqe; 454262306a36Sopenharmony_ci u32 tail, val, error; 454362306a36Sopenharmony_ci 454462306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 454562306a36Sopenharmony_ci if (!wqe) 454662306a36Sopenharmony_ci return -ENOMEM; 454762306a36Sopenharmony_ci 454862306a36Sopenharmony_ci set_64bit_val(wqe, 16, 454962306a36Sopenharmony_ci FIELD_PREP(IRDMA_SHMC_PAGE_ALLOCATED_HMC_FN_ID, hmc_fn_id)); 455062306a36Sopenharmony_ci 455162306a36Sopenharmony_ci hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, 455262306a36Sopenharmony_ci IRDMA_CQP_OP_SHMC_PAGES_ALLOCATED) | 455362306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity); 455462306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 455562306a36Sopenharmony_ci 455662306a36Sopenharmony_ci set_64bit_val(wqe, 24, hdr); 455762306a36Sopenharmony_ci 455862306a36Sopenharmony_ci print_hex_dump_debug("WQE: SHMC_PAGES_ALLOCATED WQE", 455962306a36Sopenharmony_ci DUMP_PREFIX_OFFSET, 16, 8, wqe, 456062306a36Sopenharmony_ci IRDMA_CQP_WQE_SIZE * 8, false); 456162306a36Sopenharmony_ci irdma_get_cqp_reg_info(cqp, &val, &tail, &error); 456262306a36Sopenharmony_ci 456362306a36Sopenharmony_ci if (post_sq) { 456462306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 456562306a36Sopenharmony_ci if (poll_registers) 456662306a36Sopenharmony_ci /* check for cqp sq tail update */ 456762306a36Sopenharmony_ci return irdma_cqp_poll_registers(cqp, tail, 456862306a36Sopenharmony_ci cqp->dev->hw_attrs.max_done_count); 456962306a36Sopenharmony_ci else 457062306a36Sopenharmony_ci return irdma_sc_poll_for_cqp_op_done(cqp, 457162306a36Sopenharmony_ci IRDMA_CQP_OP_SHMC_PAGES_ALLOCATED, 457262306a36Sopenharmony_ci NULL); 457362306a36Sopenharmony_ci } 457462306a36Sopenharmony_ci 457562306a36Sopenharmony_ci return 0; 457662306a36Sopenharmony_ci} 457762306a36Sopenharmony_ci 457862306a36Sopenharmony_ci/** 457962306a36Sopenharmony_ci * irdma_cqp_ring_full - check if cqp ring is full 458062306a36Sopenharmony_ci * @cqp: struct for cqp hw 458162306a36Sopenharmony_ci */ 458262306a36Sopenharmony_cistatic bool irdma_cqp_ring_full(struct irdma_sc_cqp *cqp) 458362306a36Sopenharmony_ci{ 458462306a36Sopenharmony_ci return IRDMA_RING_FULL_ERR(cqp->sq_ring); 458562306a36Sopenharmony_ci} 458662306a36Sopenharmony_ci 458762306a36Sopenharmony_ci/** 458862306a36Sopenharmony_ci * irdma_est_sd - returns approximate number of SDs for HMC 458962306a36Sopenharmony_ci * @dev: sc device struct 459062306a36Sopenharmony_ci * @hmc_info: hmc structure, size and count for HMC objects 459162306a36Sopenharmony_ci */ 459262306a36Sopenharmony_cistatic u32 irdma_est_sd(struct irdma_sc_dev *dev, 459362306a36Sopenharmony_ci struct irdma_hmc_info *hmc_info) 459462306a36Sopenharmony_ci{ 459562306a36Sopenharmony_ci int i; 459662306a36Sopenharmony_ci u64 size = 0; 459762306a36Sopenharmony_ci u64 sd; 459862306a36Sopenharmony_ci 459962306a36Sopenharmony_ci for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) 460062306a36Sopenharmony_ci if (i != IRDMA_HMC_IW_PBLE) 460162306a36Sopenharmony_ci size += round_up(hmc_info->hmc_obj[i].cnt * 460262306a36Sopenharmony_ci hmc_info->hmc_obj[i].size, 512); 460362306a36Sopenharmony_ci size += round_up(hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt * 460462306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].size, 512); 460562306a36Sopenharmony_ci if (size & 0x1FFFFF) 460662306a36Sopenharmony_ci sd = (size >> 21) + 1; /* add 1 for remainder */ 460762306a36Sopenharmony_ci else 460862306a36Sopenharmony_ci sd = size >> 21; 460962306a36Sopenharmony_ci if (sd > 0xFFFFFFFF) { 461062306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), "HMC: sd overflow[%lld]\n", sd); 461162306a36Sopenharmony_ci sd = 0xFFFFFFFF - 1; 461262306a36Sopenharmony_ci } 461362306a36Sopenharmony_ci 461462306a36Sopenharmony_ci return (u32)sd; 461562306a36Sopenharmony_ci} 461662306a36Sopenharmony_ci 461762306a36Sopenharmony_ci/** 461862306a36Sopenharmony_ci * irdma_sc_query_rdma_features_done - poll cqp for query features done 461962306a36Sopenharmony_ci * @cqp: struct for cqp hw 462062306a36Sopenharmony_ci */ 462162306a36Sopenharmony_cistatic int irdma_sc_query_rdma_features_done(struct irdma_sc_cqp *cqp) 462262306a36Sopenharmony_ci{ 462362306a36Sopenharmony_ci return irdma_sc_poll_for_cqp_op_done(cqp, 462462306a36Sopenharmony_ci IRDMA_CQP_OP_QUERY_RDMA_FEATURES, 462562306a36Sopenharmony_ci NULL); 462662306a36Sopenharmony_ci} 462762306a36Sopenharmony_ci 462862306a36Sopenharmony_ci/** 462962306a36Sopenharmony_ci * irdma_sc_query_rdma_features - query RDMA features and FW ver 463062306a36Sopenharmony_ci * @cqp: struct for cqp hw 463162306a36Sopenharmony_ci * @buf: buffer to hold query info 463262306a36Sopenharmony_ci * @scratch: u64 saved to be used during cqp completion 463362306a36Sopenharmony_ci */ 463462306a36Sopenharmony_cistatic int irdma_sc_query_rdma_features(struct irdma_sc_cqp *cqp, 463562306a36Sopenharmony_ci struct irdma_dma_mem *buf, u64 scratch) 463662306a36Sopenharmony_ci{ 463762306a36Sopenharmony_ci __le64 *wqe; 463862306a36Sopenharmony_ci u64 temp; 463962306a36Sopenharmony_ci 464062306a36Sopenharmony_ci wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 464162306a36Sopenharmony_ci if (!wqe) 464262306a36Sopenharmony_ci return -ENOMEM; 464362306a36Sopenharmony_ci 464462306a36Sopenharmony_ci temp = buf->pa; 464562306a36Sopenharmony_ci set_64bit_val(wqe, 32, temp); 464662306a36Sopenharmony_ci 464762306a36Sopenharmony_ci temp = FIELD_PREP(IRDMA_CQPSQ_QUERY_RDMA_FEATURES_WQEVALID, 464862306a36Sopenharmony_ci cqp->polarity) | 464962306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_QUERY_RDMA_FEATURES_BUF_LEN, buf->size) | 465062306a36Sopenharmony_ci FIELD_PREP(IRDMA_CQPSQ_UP_OP, IRDMA_CQP_OP_QUERY_RDMA_FEATURES); 465162306a36Sopenharmony_ci dma_wmb(); /* make sure WQE is written before valid bit is set */ 465262306a36Sopenharmony_ci 465362306a36Sopenharmony_ci set_64bit_val(wqe, 24, temp); 465462306a36Sopenharmony_ci 465562306a36Sopenharmony_ci print_hex_dump_debug("WQE: QUERY RDMA FEATURES", DUMP_PREFIX_OFFSET, 465662306a36Sopenharmony_ci 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 465762306a36Sopenharmony_ci irdma_sc_cqp_post_sq(cqp); 465862306a36Sopenharmony_ci 465962306a36Sopenharmony_ci return 0; 466062306a36Sopenharmony_ci} 466162306a36Sopenharmony_ci 466262306a36Sopenharmony_ci/** 466362306a36Sopenharmony_ci * irdma_get_rdma_features - get RDMA features 466462306a36Sopenharmony_ci * @dev: sc device struct 466562306a36Sopenharmony_ci */ 466662306a36Sopenharmony_ciint irdma_get_rdma_features(struct irdma_sc_dev *dev) 466762306a36Sopenharmony_ci{ 466862306a36Sopenharmony_ci int ret_code; 466962306a36Sopenharmony_ci struct irdma_dma_mem feat_buf; 467062306a36Sopenharmony_ci u64 temp; 467162306a36Sopenharmony_ci u16 byte_idx, feat_type, feat_cnt, feat_idx; 467262306a36Sopenharmony_ci 467362306a36Sopenharmony_ci feat_buf.size = ALIGN(IRDMA_FEATURE_BUF_SIZE, 467462306a36Sopenharmony_ci IRDMA_FEATURE_BUF_ALIGNMENT); 467562306a36Sopenharmony_ci feat_buf.va = dma_alloc_coherent(dev->hw->device, feat_buf.size, 467662306a36Sopenharmony_ci &feat_buf.pa, GFP_KERNEL); 467762306a36Sopenharmony_ci if (!feat_buf.va) 467862306a36Sopenharmony_ci return -ENOMEM; 467962306a36Sopenharmony_ci 468062306a36Sopenharmony_ci ret_code = irdma_sc_query_rdma_features(dev->cqp, &feat_buf, 0); 468162306a36Sopenharmony_ci if (!ret_code) 468262306a36Sopenharmony_ci ret_code = irdma_sc_query_rdma_features_done(dev->cqp); 468362306a36Sopenharmony_ci if (ret_code) 468462306a36Sopenharmony_ci goto exit; 468562306a36Sopenharmony_ci 468662306a36Sopenharmony_ci get_64bit_val(feat_buf.va, 0, &temp); 468762306a36Sopenharmony_ci feat_cnt = (u16)FIELD_GET(IRDMA_FEATURE_CNT, temp); 468862306a36Sopenharmony_ci if (feat_cnt < 2) { 468962306a36Sopenharmony_ci ret_code = -EINVAL; 469062306a36Sopenharmony_ci goto exit; 469162306a36Sopenharmony_ci } else if (feat_cnt > IRDMA_MAX_FEATURES) { 469262306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 469362306a36Sopenharmony_ci "DEV: feature buf size insufficient, retrying with larger buffer\n"); 469462306a36Sopenharmony_ci dma_free_coherent(dev->hw->device, feat_buf.size, feat_buf.va, 469562306a36Sopenharmony_ci feat_buf.pa); 469662306a36Sopenharmony_ci feat_buf.va = NULL; 469762306a36Sopenharmony_ci feat_buf.size = ALIGN(8 * feat_cnt, 469862306a36Sopenharmony_ci IRDMA_FEATURE_BUF_ALIGNMENT); 469962306a36Sopenharmony_ci feat_buf.va = dma_alloc_coherent(dev->hw->device, 470062306a36Sopenharmony_ci feat_buf.size, &feat_buf.pa, 470162306a36Sopenharmony_ci GFP_KERNEL); 470262306a36Sopenharmony_ci if (!feat_buf.va) 470362306a36Sopenharmony_ci return -ENOMEM; 470462306a36Sopenharmony_ci 470562306a36Sopenharmony_ci ret_code = irdma_sc_query_rdma_features(dev->cqp, &feat_buf, 0); 470662306a36Sopenharmony_ci if (!ret_code) 470762306a36Sopenharmony_ci ret_code = irdma_sc_query_rdma_features_done(dev->cqp); 470862306a36Sopenharmony_ci if (ret_code) 470962306a36Sopenharmony_ci goto exit; 471062306a36Sopenharmony_ci 471162306a36Sopenharmony_ci get_64bit_val(feat_buf.va, 0, &temp); 471262306a36Sopenharmony_ci feat_cnt = (u16)FIELD_GET(IRDMA_FEATURE_CNT, temp); 471362306a36Sopenharmony_ci if (feat_cnt < 2) { 471462306a36Sopenharmony_ci ret_code = -EINVAL; 471562306a36Sopenharmony_ci goto exit; 471662306a36Sopenharmony_ci } 471762306a36Sopenharmony_ci } 471862306a36Sopenharmony_ci 471962306a36Sopenharmony_ci print_hex_dump_debug("WQE: QUERY RDMA FEATURES", DUMP_PREFIX_OFFSET, 472062306a36Sopenharmony_ci 16, 8, feat_buf.va, feat_cnt * 8, false); 472162306a36Sopenharmony_ci 472262306a36Sopenharmony_ci for (byte_idx = 0, feat_idx = 0; feat_idx < min(feat_cnt, (u16)IRDMA_MAX_FEATURES); 472362306a36Sopenharmony_ci feat_idx++, byte_idx += 8) { 472462306a36Sopenharmony_ci get_64bit_val(feat_buf.va, byte_idx, &temp); 472562306a36Sopenharmony_ci feat_type = FIELD_GET(IRDMA_FEATURE_TYPE, temp); 472662306a36Sopenharmony_ci if (feat_type >= IRDMA_MAX_FEATURES) { 472762306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 472862306a36Sopenharmony_ci "DEV: found unrecognized feature type %d\n", 472962306a36Sopenharmony_ci feat_type); 473062306a36Sopenharmony_ci continue; 473162306a36Sopenharmony_ci } 473262306a36Sopenharmony_ci dev->feature_info[feat_type] = temp; 473362306a36Sopenharmony_ci } 473462306a36Sopenharmony_ciexit: 473562306a36Sopenharmony_ci dma_free_coherent(dev->hw->device, feat_buf.size, feat_buf.va, 473662306a36Sopenharmony_ci feat_buf.pa); 473762306a36Sopenharmony_ci feat_buf.va = NULL; 473862306a36Sopenharmony_ci return ret_code; 473962306a36Sopenharmony_ci} 474062306a36Sopenharmony_ci 474162306a36Sopenharmony_cistatic u32 irdma_q1_cnt(struct irdma_sc_dev *dev, 474262306a36Sopenharmony_ci struct irdma_hmc_info *hmc_info, u32 qpwanted) 474362306a36Sopenharmony_ci{ 474462306a36Sopenharmony_ci u32 q1_cnt; 474562306a36Sopenharmony_ci 474662306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) { 474762306a36Sopenharmony_ci q1_cnt = roundup_pow_of_two(dev->hw_attrs.max_hw_ird * 2 * qpwanted); 474862306a36Sopenharmony_ci } else { 474962306a36Sopenharmony_ci if (dev->cqp->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY) 475062306a36Sopenharmony_ci q1_cnt = roundup_pow_of_two(dev->hw_attrs.max_hw_ird * 2 * qpwanted + 512); 475162306a36Sopenharmony_ci else 475262306a36Sopenharmony_ci q1_cnt = dev->hw_attrs.max_hw_ird * 2 * qpwanted; 475362306a36Sopenharmony_ci } 475462306a36Sopenharmony_ci 475562306a36Sopenharmony_ci return q1_cnt; 475662306a36Sopenharmony_ci} 475762306a36Sopenharmony_ci 475862306a36Sopenharmony_cistatic void cfg_fpm_value_gen_1(struct irdma_sc_dev *dev, 475962306a36Sopenharmony_ci struct irdma_hmc_info *hmc_info, u32 qpwanted) 476062306a36Sopenharmony_ci{ 476162306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt = roundup_pow_of_two(qpwanted * dev->hw_attrs.max_hw_wqes); 476262306a36Sopenharmony_ci} 476362306a36Sopenharmony_ci 476462306a36Sopenharmony_cistatic void cfg_fpm_value_gen_2(struct irdma_sc_dev *dev, 476562306a36Sopenharmony_ci struct irdma_hmc_info *hmc_info, u32 qpwanted) 476662306a36Sopenharmony_ci{ 476762306a36Sopenharmony_ci struct irdma_hmc_fpm_misc *hmc_fpm_misc = &dev->hmc_fpm_misc; 476862306a36Sopenharmony_ci 476962306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt = 477062306a36Sopenharmony_ci 4 * hmc_fpm_misc->xf_block_size * qpwanted; 477162306a36Sopenharmony_ci 477262306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_HDR].cnt = qpwanted; 477362306a36Sopenharmony_ci 477462306a36Sopenharmony_ci if (hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].max_cnt) 477562306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].cnt = 32 * qpwanted; 477662306a36Sopenharmony_ci if (hmc_info->hmc_obj[IRDMA_HMC_IW_RRFFL].max_cnt) 477762306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_RRFFL].cnt = 477862306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].cnt / 477962306a36Sopenharmony_ci hmc_fpm_misc->rrf_block_size; 478062306a36Sopenharmony_ci if (hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].max_cnt) 478162306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].cnt = 32 * qpwanted; 478262306a36Sopenharmony_ci if (hmc_info->hmc_obj[IRDMA_HMC_IW_OOISCFFL].max_cnt) 478362306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_OOISCFFL].cnt = 478462306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].cnt / 478562306a36Sopenharmony_ci hmc_fpm_misc->ooiscf_block_size; 478662306a36Sopenharmony_ci} 478762306a36Sopenharmony_ci 478862306a36Sopenharmony_ci/** 478962306a36Sopenharmony_ci * irdma_cfg_fpm_val - configure HMC objects 479062306a36Sopenharmony_ci * @dev: sc device struct 479162306a36Sopenharmony_ci * @qp_count: desired qp count 479262306a36Sopenharmony_ci */ 479362306a36Sopenharmony_ciint irdma_cfg_fpm_val(struct irdma_sc_dev *dev, u32 qp_count) 479462306a36Sopenharmony_ci{ 479562306a36Sopenharmony_ci struct irdma_virt_mem virt_mem; 479662306a36Sopenharmony_ci u32 i, mem_size; 479762306a36Sopenharmony_ci u32 qpwanted, mrwanted, pblewanted; 479862306a36Sopenharmony_ci u32 powerof2, hte; 479962306a36Sopenharmony_ci u32 sd_needed; 480062306a36Sopenharmony_ci u32 sd_diff; 480162306a36Sopenharmony_ci u32 loop_count = 0; 480262306a36Sopenharmony_ci struct irdma_hmc_info *hmc_info; 480362306a36Sopenharmony_ci struct irdma_hmc_fpm_misc *hmc_fpm_misc; 480462306a36Sopenharmony_ci int ret_code = 0; 480562306a36Sopenharmony_ci 480662306a36Sopenharmony_ci hmc_info = dev->hmc_info; 480762306a36Sopenharmony_ci hmc_fpm_misc = &dev->hmc_fpm_misc; 480862306a36Sopenharmony_ci 480962306a36Sopenharmony_ci ret_code = irdma_sc_init_iw_hmc(dev, dev->hmc_fn_id); 481062306a36Sopenharmony_ci if (ret_code) { 481162306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 481262306a36Sopenharmony_ci "HMC: irdma_sc_init_iw_hmc returned error_code = %d\n", 481362306a36Sopenharmony_ci ret_code); 481462306a36Sopenharmony_ci return ret_code; 481562306a36Sopenharmony_ci } 481662306a36Sopenharmony_ci 481762306a36Sopenharmony_ci for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) 481862306a36Sopenharmony_ci hmc_info->hmc_obj[i].cnt = hmc_info->hmc_obj[i].max_cnt; 481962306a36Sopenharmony_ci sd_needed = irdma_est_sd(dev, hmc_info); 482062306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 482162306a36Sopenharmony_ci "HMC: FW max resources sd_needed[%08d] first_sd_index[%04d]\n", 482262306a36Sopenharmony_ci sd_needed, hmc_info->first_sd_index); 482362306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), "HMC: sd count %d where max sd is %d\n", 482462306a36Sopenharmony_ci hmc_info->sd_table.sd_cnt, hmc_fpm_misc->max_sds); 482562306a36Sopenharmony_ci 482662306a36Sopenharmony_ci qpwanted = min(qp_count, hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt); 482762306a36Sopenharmony_ci 482862306a36Sopenharmony_ci powerof2 = 1; 482962306a36Sopenharmony_ci while (powerof2 <= qpwanted) 483062306a36Sopenharmony_ci powerof2 *= 2; 483162306a36Sopenharmony_ci powerof2 /= 2; 483262306a36Sopenharmony_ci qpwanted = powerof2; 483362306a36Sopenharmony_ci 483462306a36Sopenharmony_ci mrwanted = hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt; 483562306a36Sopenharmony_ci pblewanted = hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].max_cnt; 483662306a36Sopenharmony_ci 483762306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 483862306a36Sopenharmony_ci "HMC: req_qp=%d max_sd=%d, max_qp = %d, max_cq=%d, max_mr=%d, max_pble=%d, mc=%d, av=%d\n", 483962306a36Sopenharmony_ci qp_count, hmc_fpm_misc->max_sds, 484062306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt, 484162306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].max_cnt, 484262306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt, 484362306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].max_cnt, 484462306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].max_cnt, 484562306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt); 484662306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt = 484762306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].max_cnt; 484862306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt = 484962306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt; 485062306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_ARP].cnt = 485162306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_ARP].max_cnt; 485262306a36Sopenharmony_ci 485362306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_APBVT_ENTRY].cnt = 1; 485462306a36Sopenharmony_ci 485562306a36Sopenharmony_ci while (irdma_q1_cnt(dev, hmc_info, qpwanted) > hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].max_cnt) 485662306a36Sopenharmony_ci qpwanted /= 2; 485762306a36Sopenharmony_ci 485862306a36Sopenharmony_ci do { 485962306a36Sopenharmony_ci ++loop_count; 486062306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_QP].cnt = qpwanted; 486162306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt = 486262306a36Sopenharmony_ci min(2 * qpwanted, hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt); 486362306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_RESERVED].cnt = 0; /* Reserved */ 486462306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt = mrwanted; 486562306a36Sopenharmony_ci 486662306a36Sopenharmony_ci hte = round_up(qpwanted + hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt, 512); 486762306a36Sopenharmony_ci powerof2 = 1; 486862306a36Sopenharmony_ci while (powerof2 < hte) 486962306a36Sopenharmony_ci powerof2 *= 2; 487062306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_HTE].cnt = 487162306a36Sopenharmony_ci powerof2 * hmc_fpm_misc->ht_multiplier; 487262306a36Sopenharmony_ci if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) 487362306a36Sopenharmony_ci cfg_fpm_value_gen_1(dev, hmc_info, qpwanted); 487462306a36Sopenharmony_ci else 487562306a36Sopenharmony_ci cfg_fpm_value_gen_2(dev, hmc_info, qpwanted); 487662306a36Sopenharmony_ci 487762306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt = irdma_q1_cnt(dev, hmc_info, qpwanted); 487862306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_XFFL].cnt = 487962306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt / hmc_fpm_misc->xf_block_size; 488062306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_Q1FL].cnt = 488162306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt / hmc_fpm_misc->q1_block_size; 488262306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_TIMER].cnt = 488362306a36Sopenharmony_ci (round_up(qpwanted, 512) / 512 + 1) * hmc_fpm_misc->timer_bucket; 488462306a36Sopenharmony_ci 488562306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt = pblewanted; 488662306a36Sopenharmony_ci sd_needed = irdma_est_sd(dev, hmc_info); 488762306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 488862306a36Sopenharmony_ci "HMC: sd_needed = %d, hmc_fpm_misc->max_sds=%d, mrwanted=%d, pblewanted=%d qpwanted=%d\n", 488962306a36Sopenharmony_ci sd_needed, hmc_fpm_misc->max_sds, mrwanted, 489062306a36Sopenharmony_ci pblewanted, qpwanted); 489162306a36Sopenharmony_ci 489262306a36Sopenharmony_ci /* Do not reduce resources further. All objects fit with max SDs */ 489362306a36Sopenharmony_ci if (sd_needed <= hmc_fpm_misc->max_sds) 489462306a36Sopenharmony_ci break; 489562306a36Sopenharmony_ci 489662306a36Sopenharmony_ci sd_diff = sd_needed - hmc_fpm_misc->max_sds; 489762306a36Sopenharmony_ci if (sd_diff > 128) { 489862306a36Sopenharmony_ci if (!(loop_count % 2) && qpwanted > 128) { 489962306a36Sopenharmony_ci qpwanted /= 2; 490062306a36Sopenharmony_ci } else { 490162306a36Sopenharmony_ci mrwanted /= 2; 490262306a36Sopenharmony_ci pblewanted /= 2; 490362306a36Sopenharmony_ci } 490462306a36Sopenharmony_ci continue; 490562306a36Sopenharmony_ci } 490662306a36Sopenharmony_ci if (dev->cqp->hmc_profile != IRDMA_HMC_PROFILE_FAVOR_VF && 490762306a36Sopenharmony_ci pblewanted > (512 * FPM_MULTIPLIER * sd_diff)) { 490862306a36Sopenharmony_ci pblewanted -= 256 * FPM_MULTIPLIER * sd_diff; 490962306a36Sopenharmony_ci continue; 491062306a36Sopenharmony_ci } else if (pblewanted > (100 * FPM_MULTIPLIER)) { 491162306a36Sopenharmony_ci pblewanted -= 10 * FPM_MULTIPLIER; 491262306a36Sopenharmony_ci } else if (pblewanted > FPM_MULTIPLIER) { 491362306a36Sopenharmony_ci pblewanted -= FPM_MULTIPLIER; 491462306a36Sopenharmony_ci } else if (qpwanted <= 128) { 491562306a36Sopenharmony_ci if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt > 256) 491662306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt /= 2; 491762306a36Sopenharmony_ci if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt > 256) 491862306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt /= 2; 491962306a36Sopenharmony_ci } 492062306a36Sopenharmony_ci if (mrwanted > FPM_MULTIPLIER) 492162306a36Sopenharmony_ci mrwanted -= FPM_MULTIPLIER; 492262306a36Sopenharmony_ci if (!(loop_count % 10) && qpwanted > 128) { 492362306a36Sopenharmony_ci qpwanted /= 2; 492462306a36Sopenharmony_ci if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt > 256) 492562306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt /= 2; 492662306a36Sopenharmony_ci } 492762306a36Sopenharmony_ci } while (loop_count < 2000); 492862306a36Sopenharmony_ci 492962306a36Sopenharmony_ci if (sd_needed > hmc_fpm_misc->max_sds) { 493062306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 493162306a36Sopenharmony_ci "HMC: cfg_fpm failed loop_cnt=%d, sd_needed=%d, max sd count %d\n", 493262306a36Sopenharmony_ci loop_count, sd_needed, hmc_info->sd_table.sd_cnt); 493362306a36Sopenharmony_ci return -EINVAL; 493462306a36Sopenharmony_ci } 493562306a36Sopenharmony_ci 493662306a36Sopenharmony_ci if (loop_count > 1 && sd_needed < hmc_fpm_misc->max_sds) { 493762306a36Sopenharmony_ci pblewanted += (hmc_fpm_misc->max_sds - sd_needed) * 256 * 493862306a36Sopenharmony_ci FPM_MULTIPLIER; 493962306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt = pblewanted; 494062306a36Sopenharmony_ci sd_needed = irdma_est_sd(dev, hmc_info); 494162306a36Sopenharmony_ci } 494262306a36Sopenharmony_ci 494362306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 494462306a36Sopenharmony_ci "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", 494562306a36Sopenharmony_ci loop_count, sd_needed, 494662306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_QP].cnt, 494762306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt, 494862306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt, 494962306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt, 495062306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt, 495162306a36Sopenharmony_ci hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt, 495262306a36Sopenharmony_ci hmc_info->sd_table.sd_cnt, hmc_info->first_sd_index); 495362306a36Sopenharmony_ci 495462306a36Sopenharmony_ci ret_code = irdma_sc_cfg_iw_fpm(dev, dev->hmc_fn_id); 495562306a36Sopenharmony_ci if (ret_code) { 495662306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 495762306a36Sopenharmony_ci "HMC: cfg_iw_fpm returned error_code[x%08X]\n", 495862306a36Sopenharmony_ci readl(dev->hw_regs[IRDMA_CQPERRCODES])); 495962306a36Sopenharmony_ci return ret_code; 496062306a36Sopenharmony_ci } 496162306a36Sopenharmony_ci 496262306a36Sopenharmony_ci mem_size = sizeof(struct irdma_hmc_sd_entry) * 496362306a36Sopenharmony_ci (hmc_info->sd_table.sd_cnt + hmc_info->first_sd_index + 1); 496462306a36Sopenharmony_ci virt_mem.size = mem_size; 496562306a36Sopenharmony_ci virt_mem.va = kzalloc(virt_mem.size, GFP_KERNEL); 496662306a36Sopenharmony_ci if (!virt_mem.va) { 496762306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 496862306a36Sopenharmony_ci "HMC: failed to allocate memory for sd_entry buffer\n"); 496962306a36Sopenharmony_ci return -ENOMEM; 497062306a36Sopenharmony_ci } 497162306a36Sopenharmony_ci hmc_info->sd_table.sd_entry = virt_mem.va; 497262306a36Sopenharmony_ci 497362306a36Sopenharmony_ci return ret_code; 497462306a36Sopenharmony_ci} 497562306a36Sopenharmony_ci 497662306a36Sopenharmony_ci/** 497762306a36Sopenharmony_ci * irdma_exec_cqp_cmd - execute cqp cmd when wqe are available 497862306a36Sopenharmony_ci * @dev: rdma device 497962306a36Sopenharmony_ci * @pcmdinfo: cqp command info 498062306a36Sopenharmony_ci */ 498162306a36Sopenharmony_cistatic int irdma_exec_cqp_cmd(struct irdma_sc_dev *dev, 498262306a36Sopenharmony_ci struct cqp_cmds_info *pcmdinfo) 498362306a36Sopenharmony_ci{ 498462306a36Sopenharmony_ci int status; 498562306a36Sopenharmony_ci struct irdma_dma_mem val_mem; 498662306a36Sopenharmony_ci bool alloc = false; 498762306a36Sopenharmony_ci 498862306a36Sopenharmony_ci dev->cqp_cmd_stats[pcmdinfo->cqp_cmd]++; 498962306a36Sopenharmony_ci switch (pcmdinfo->cqp_cmd) { 499062306a36Sopenharmony_ci case IRDMA_OP_CEQ_DESTROY: 499162306a36Sopenharmony_ci status = irdma_sc_ceq_destroy(pcmdinfo->in.u.ceq_destroy.ceq, 499262306a36Sopenharmony_ci pcmdinfo->in.u.ceq_destroy.scratch, 499362306a36Sopenharmony_ci pcmdinfo->post_sq); 499462306a36Sopenharmony_ci break; 499562306a36Sopenharmony_ci case IRDMA_OP_AEQ_DESTROY: 499662306a36Sopenharmony_ci status = irdma_sc_aeq_destroy(pcmdinfo->in.u.aeq_destroy.aeq, 499762306a36Sopenharmony_ci pcmdinfo->in.u.aeq_destroy.scratch, 499862306a36Sopenharmony_ci pcmdinfo->post_sq); 499962306a36Sopenharmony_ci 500062306a36Sopenharmony_ci break; 500162306a36Sopenharmony_ci case IRDMA_OP_CEQ_CREATE: 500262306a36Sopenharmony_ci status = irdma_sc_ceq_create(pcmdinfo->in.u.ceq_create.ceq, 500362306a36Sopenharmony_ci pcmdinfo->in.u.ceq_create.scratch, 500462306a36Sopenharmony_ci pcmdinfo->post_sq); 500562306a36Sopenharmony_ci break; 500662306a36Sopenharmony_ci case IRDMA_OP_AEQ_CREATE: 500762306a36Sopenharmony_ci status = irdma_sc_aeq_create(pcmdinfo->in.u.aeq_create.aeq, 500862306a36Sopenharmony_ci pcmdinfo->in.u.aeq_create.scratch, 500962306a36Sopenharmony_ci pcmdinfo->post_sq); 501062306a36Sopenharmony_ci break; 501162306a36Sopenharmony_ci case IRDMA_OP_QP_UPLOAD_CONTEXT: 501262306a36Sopenharmony_ci status = irdma_sc_qp_upload_context(pcmdinfo->in.u.qp_upload_context.dev, 501362306a36Sopenharmony_ci &pcmdinfo->in.u.qp_upload_context.info, 501462306a36Sopenharmony_ci pcmdinfo->in.u.qp_upload_context.scratch, 501562306a36Sopenharmony_ci pcmdinfo->post_sq); 501662306a36Sopenharmony_ci break; 501762306a36Sopenharmony_ci case IRDMA_OP_CQ_CREATE: 501862306a36Sopenharmony_ci status = irdma_sc_cq_create(pcmdinfo->in.u.cq_create.cq, 501962306a36Sopenharmony_ci pcmdinfo->in.u.cq_create.scratch, 502062306a36Sopenharmony_ci pcmdinfo->in.u.cq_create.check_overflow, 502162306a36Sopenharmony_ci pcmdinfo->post_sq); 502262306a36Sopenharmony_ci break; 502362306a36Sopenharmony_ci case IRDMA_OP_CQ_MODIFY: 502462306a36Sopenharmony_ci status = irdma_sc_cq_modify(pcmdinfo->in.u.cq_modify.cq, 502562306a36Sopenharmony_ci &pcmdinfo->in.u.cq_modify.info, 502662306a36Sopenharmony_ci pcmdinfo->in.u.cq_modify.scratch, 502762306a36Sopenharmony_ci pcmdinfo->post_sq); 502862306a36Sopenharmony_ci break; 502962306a36Sopenharmony_ci case IRDMA_OP_CQ_DESTROY: 503062306a36Sopenharmony_ci status = irdma_sc_cq_destroy(pcmdinfo->in.u.cq_destroy.cq, 503162306a36Sopenharmony_ci pcmdinfo->in.u.cq_destroy.scratch, 503262306a36Sopenharmony_ci pcmdinfo->post_sq); 503362306a36Sopenharmony_ci break; 503462306a36Sopenharmony_ci case IRDMA_OP_QP_FLUSH_WQES: 503562306a36Sopenharmony_ci status = irdma_sc_qp_flush_wqes(pcmdinfo->in.u.qp_flush_wqes.qp, 503662306a36Sopenharmony_ci &pcmdinfo->in.u.qp_flush_wqes.info, 503762306a36Sopenharmony_ci pcmdinfo->in.u.qp_flush_wqes.scratch, 503862306a36Sopenharmony_ci pcmdinfo->post_sq); 503962306a36Sopenharmony_ci break; 504062306a36Sopenharmony_ci case IRDMA_OP_GEN_AE: 504162306a36Sopenharmony_ci status = irdma_sc_gen_ae(pcmdinfo->in.u.gen_ae.qp, 504262306a36Sopenharmony_ci &pcmdinfo->in.u.gen_ae.info, 504362306a36Sopenharmony_ci pcmdinfo->in.u.gen_ae.scratch, 504462306a36Sopenharmony_ci pcmdinfo->post_sq); 504562306a36Sopenharmony_ci break; 504662306a36Sopenharmony_ci case IRDMA_OP_MANAGE_PUSH_PAGE: 504762306a36Sopenharmony_ci status = irdma_sc_manage_push_page(pcmdinfo->in.u.manage_push_page.cqp, 504862306a36Sopenharmony_ci &pcmdinfo->in.u.manage_push_page.info, 504962306a36Sopenharmony_ci pcmdinfo->in.u.manage_push_page.scratch, 505062306a36Sopenharmony_ci pcmdinfo->post_sq); 505162306a36Sopenharmony_ci break; 505262306a36Sopenharmony_ci case IRDMA_OP_UPDATE_PE_SDS: 505362306a36Sopenharmony_ci status = irdma_update_pe_sds(pcmdinfo->in.u.update_pe_sds.dev, 505462306a36Sopenharmony_ci &pcmdinfo->in.u.update_pe_sds.info, 505562306a36Sopenharmony_ci pcmdinfo->in.u.update_pe_sds.scratch); 505662306a36Sopenharmony_ci break; 505762306a36Sopenharmony_ci case IRDMA_OP_MANAGE_HMC_PM_FUNC_TABLE: 505862306a36Sopenharmony_ci /* switch to calling through the call table */ 505962306a36Sopenharmony_ci status = 506062306a36Sopenharmony_ci irdma_sc_manage_hmc_pm_func_table(pcmdinfo->in.u.manage_hmc_pm.dev->cqp, 506162306a36Sopenharmony_ci &pcmdinfo->in.u.manage_hmc_pm.info, 506262306a36Sopenharmony_ci pcmdinfo->in.u.manage_hmc_pm.scratch, 506362306a36Sopenharmony_ci true); 506462306a36Sopenharmony_ci break; 506562306a36Sopenharmony_ci case IRDMA_OP_SUSPEND: 506662306a36Sopenharmony_ci status = irdma_sc_suspend_qp(pcmdinfo->in.u.suspend_resume.cqp, 506762306a36Sopenharmony_ci pcmdinfo->in.u.suspend_resume.qp, 506862306a36Sopenharmony_ci pcmdinfo->in.u.suspend_resume.scratch); 506962306a36Sopenharmony_ci break; 507062306a36Sopenharmony_ci case IRDMA_OP_RESUME: 507162306a36Sopenharmony_ci status = irdma_sc_resume_qp(pcmdinfo->in.u.suspend_resume.cqp, 507262306a36Sopenharmony_ci pcmdinfo->in.u.suspend_resume.qp, 507362306a36Sopenharmony_ci pcmdinfo->in.u.suspend_resume.scratch); 507462306a36Sopenharmony_ci break; 507562306a36Sopenharmony_ci case IRDMA_OP_QUERY_FPM_VAL: 507662306a36Sopenharmony_ci val_mem.pa = pcmdinfo->in.u.query_fpm_val.fpm_val_pa; 507762306a36Sopenharmony_ci val_mem.va = pcmdinfo->in.u.query_fpm_val.fpm_val_va; 507862306a36Sopenharmony_ci status = irdma_sc_query_fpm_val(pcmdinfo->in.u.query_fpm_val.cqp, 507962306a36Sopenharmony_ci pcmdinfo->in.u.query_fpm_val.scratch, 508062306a36Sopenharmony_ci pcmdinfo->in.u.query_fpm_val.hmc_fn_id, 508162306a36Sopenharmony_ci &val_mem, true, IRDMA_CQP_WAIT_EVENT); 508262306a36Sopenharmony_ci break; 508362306a36Sopenharmony_ci case IRDMA_OP_COMMIT_FPM_VAL: 508462306a36Sopenharmony_ci val_mem.pa = pcmdinfo->in.u.commit_fpm_val.fpm_val_pa; 508562306a36Sopenharmony_ci val_mem.va = pcmdinfo->in.u.commit_fpm_val.fpm_val_va; 508662306a36Sopenharmony_ci status = irdma_sc_commit_fpm_val(pcmdinfo->in.u.commit_fpm_val.cqp, 508762306a36Sopenharmony_ci pcmdinfo->in.u.commit_fpm_val.scratch, 508862306a36Sopenharmony_ci pcmdinfo->in.u.commit_fpm_val.hmc_fn_id, 508962306a36Sopenharmony_ci &val_mem, 509062306a36Sopenharmony_ci true, 509162306a36Sopenharmony_ci IRDMA_CQP_WAIT_EVENT); 509262306a36Sopenharmony_ci break; 509362306a36Sopenharmony_ci case IRDMA_OP_STATS_ALLOCATE: 509462306a36Sopenharmony_ci alloc = true; 509562306a36Sopenharmony_ci fallthrough; 509662306a36Sopenharmony_ci case IRDMA_OP_STATS_FREE: 509762306a36Sopenharmony_ci status = irdma_sc_manage_stats_inst(pcmdinfo->in.u.stats_manage.cqp, 509862306a36Sopenharmony_ci &pcmdinfo->in.u.stats_manage.info, 509962306a36Sopenharmony_ci alloc, 510062306a36Sopenharmony_ci pcmdinfo->in.u.stats_manage.scratch); 510162306a36Sopenharmony_ci break; 510262306a36Sopenharmony_ci case IRDMA_OP_STATS_GATHER: 510362306a36Sopenharmony_ci status = irdma_sc_gather_stats(pcmdinfo->in.u.stats_gather.cqp, 510462306a36Sopenharmony_ci &pcmdinfo->in.u.stats_gather.info, 510562306a36Sopenharmony_ci pcmdinfo->in.u.stats_gather.scratch); 510662306a36Sopenharmony_ci break; 510762306a36Sopenharmony_ci case IRDMA_OP_WS_MODIFY_NODE: 510862306a36Sopenharmony_ci status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp, 510962306a36Sopenharmony_ci &pcmdinfo->in.u.ws_node.info, 511062306a36Sopenharmony_ci IRDMA_MODIFY_NODE, 511162306a36Sopenharmony_ci pcmdinfo->in.u.ws_node.scratch); 511262306a36Sopenharmony_ci break; 511362306a36Sopenharmony_ci case IRDMA_OP_WS_DELETE_NODE: 511462306a36Sopenharmony_ci status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp, 511562306a36Sopenharmony_ci &pcmdinfo->in.u.ws_node.info, 511662306a36Sopenharmony_ci IRDMA_DEL_NODE, 511762306a36Sopenharmony_ci pcmdinfo->in.u.ws_node.scratch); 511862306a36Sopenharmony_ci break; 511962306a36Sopenharmony_ci case IRDMA_OP_WS_ADD_NODE: 512062306a36Sopenharmony_ci status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp, 512162306a36Sopenharmony_ci &pcmdinfo->in.u.ws_node.info, 512262306a36Sopenharmony_ci IRDMA_ADD_NODE, 512362306a36Sopenharmony_ci pcmdinfo->in.u.ws_node.scratch); 512462306a36Sopenharmony_ci break; 512562306a36Sopenharmony_ci case IRDMA_OP_SET_UP_MAP: 512662306a36Sopenharmony_ci status = irdma_sc_set_up_map(pcmdinfo->in.u.up_map.cqp, 512762306a36Sopenharmony_ci &pcmdinfo->in.u.up_map.info, 512862306a36Sopenharmony_ci pcmdinfo->in.u.up_map.scratch); 512962306a36Sopenharmony_ci break; 513062306a36Sopenharmony_ci case IRDMA_OP_QUERY_RDMA_FEATURES: 513162306a36Sopenharmony_ci status = irdma_sc_query_rdma_features(pcmdinfo->in.u.query_rdma.cqp, 513262306a36Sopenharmony_ci &pcmdinfo->in.u.query_rdma.query_buff_mem, 513362306a36Sopenharmony_ci pcmdinfo->in.u.query_rdma.scratch); 513462306a36Sopenharmony_ci break; 513562306a36Sopenharmony_ci case IRDMA_OP_DELETE_ARP_CACHE_ENTRY: 513662306a36Sopenharmony_ci status = irdma_sc_del_arp_cache_entry(pcmdinfo->in.u.del_arp_cache_entry.cqp, 513762306a36Sopenharmony_ci pcmdinfo->in.u.del_arp_cache_entry.scratch, 513862306a36Sopenharmony_ci pcmdinfo->in.u.del_arp_cache_entry.arp_index, 513962306a36Sopenharmony_ci pcmdinfo->post_sq); 514062306a36Sopenharmony_ci break; 514162306a36Sopenharmony_ci case IRDMA_OP_MANAGE_APBVT_ENTRY: 514262306a36Sopenharmony_ci status = irdma_sc_manage_apbvt_entry(pcmdinfo->in.u.manage_apbvt_entry.cqp, 514362306a36Sopenharmony_ci &pcmdinfo->in.u.manage_apbvt_entry.info, 514462306a36Sopenharmony_ci pcmdinfo->in.u.manage_apbvt_entry.scratch, 514562306a36Sopenharmony_ci pcmdinfo->post_sq); 514662306a36Sopenharmony_ci break; 514762306a36Sopenharmony_ci case IRDMA_OP_MANAGE_QHASH_TABLE_ENTRY: 514862306a36Sopenharmony_ci status = irdma_sc_manage_qhash_table_entry(pcmdinfo->in.u.manage_qhash_table_entry.cqp, 514962306a36Sopenharmony_ci &pcmdinfo->in.u.manage_qhash_table_entry.info, 515062306a36Sopenharmony_ci pcmdinfo->in.u.manage_qhash_table_entry.scratch, 515162306a36Sopenharmony_ci pcmdinfo->post_sq); 515262306a36Sopenharmony_ci break; 515362306a36Sopenharmony_ci case IRDMA_OP_QP_MODIFY: 515462306a36Sopenharmony_ci status = irdma_sc_qp_modify(pcmdinfo->in.u.qp_modify.qp, 515562306a36Sopenharmony_ci &pcmdinfo->in.u.qp_modify.info, 515662306a36Sopenharmony_ci pcmdinfo->in.u.qp_modify.scratch, 515762306a36Sopenharmony_ci pcmdinfo->post_sq); 515862306a36Sopenharmony_ci break; 515962306a36Sopenharmony_ci case IRDMA_OP_QP_CREATE: 516062306a36Sopenharmony_ci status = irdma_sc_qp_create(pcmdinfo->in.u.qp_create.qp, 516162306a36Sopenharmony_ci &pcmdinfo->in.u.qp_create.info, 516262306a36Sopenharmony_ci pcmdinfo->in.u.qp_create.scratch, 516362306a36Sopenharmony_ci pcmdinfo->post_sq); 516462306a36Sopenharmony_ci break; 516562306a36Sopenharmony_ci case IRDMA_OP_QP_DESTROY: 516662306a36Sopenharmony_ci status = irdma_sc_qp_destroy(pcmdinfo->in.u.qp_destroy.qp, 516762306a36Sopenharmony_ci pcmdinfo->in.u.qp_destroy.scratch, 516862306a36Sopenharmony_ci pcmdinfo->in.u.qp_destroy.remove_hash_idx, 516962306a36Sopenharmony_ci pcmdinfo->in.u.qp_destroy.ignore_mw_bnd, 517062306a36Sopenharmony_ci pcmdinfo->post_sq); 517162306a36Sopenharmony_ci break; 517262306a36Sopenharmony_ci case IRDMA_OP_ALLOC_STAG: 517362306a36Sopenharmony_ci status = irdma_sc_alloc_stag(pcmdinfo->in.u.alloc_stag.dev, 517462306a36Sopenharmony_ci &pcmdinfo->in.u.alloc_stag.info, 517562306a36Sopenharmony_ci pcmdinfo->in.u.alloc_stag.scratch, 517662306a36Sopenharmony_ci pcmdinfo->post_sq); 517762306a36Sopenharmony_ci break; 517862306a36Sopenharmony_ci case IRDMA_OP_MR_REG_NON_SHARED: 517962306a36Sopenharmony_ci status = irdma_sc_mr_reg_non_shared(pcmdinfo->in.u.mr_reg_non_shared.dev, 518062306a36Sopenharmony_ci &pcmdinfo->in.u.mr_reg_non_shared.info, 518162306a36Sopenharmony_ci pcmdinfo->in.u.mr_reg_non_shared.scratch, 518262306a36Sopenharmony_ci pcmdinfo->post_sq); 518362306a36Sopenharmony_ci break; 518462306a36Sopenharmony_ci case IRDMA_OP_DEALLOC_STAG: 518562306a36Sopenharmony_ci status = irdma_sc_dealloc_stag(pcmdinfo->in.u.dealloc_stag.dev, 518662306a36Sopenharmony_ci &pcmdinfo->in.u.dealloc_stag.info, 518762306a36Sopenharmony_ci pcmdinfo->in.u.dealloc_stag.scratch, 518862306a36Sopenharmony_ci pcmdinfo->post_sq); 518962306a36Sopenharmony_ci break; 519062306a36Sopenharmony_ci case IRDMA_OP_MW_ALLOC: 519162306a36Sopenharmony_ci status = irdma_sc_mw_alloc(pcmdinfo->in.u.mw_alloc.dev, 519262306a36Sopenharmony_ci &pcmdinfo->in.u.mw_alloc.info, 519362306a36Sopenharmony_ci pcmdinfo->in.u.mw_alloc.scratch, 519462306a36Sopenharmony_ci pcmdinfo->post_sq); 519562306a36Sopenharmony_ci break; 519662306a36Sopenharmony_ci case IRDMA_OP_ADD_ARP_CACHE_ENTRY: 519762306a36Sopenharmony_ci status = irdma_sc_add_arp_cache_entry(pcmdinfo->in.u.add_arp_cache_entry.cqp, 519862306a36Sopenharmony_ci &pcmdinfo->in.u.add_arp_cache_entry.info, 519962306a36Sopenharmony_ci pcmdinfo->in.u.add_arp_cache_entry.scratch, 520062306a36Sopenharmony_ci pcmdinfo->post_sq); 520162306a36Sopenharmony_ci break; 520262306a36Sopenharmony_ci case IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY: 520362306a36Sopenharmony_ci status = irdma_sc_alloc_local_mac_entry(pcmdinfo->in.u.alloc_local_mac_entry.cqp, 520462306a36Sopenharmony_ci pcmdinfo->in.u.alloc_local_mac_entry.scratch, 520562306a36Sopenharmony_ci pcmdinfo->post_sq); 520662306a36Sopenharmony_ci break; 520762306a36Sopenharmony_ci case IRDMA_OP_ADD_LOCAL_MAC_ENTRY: 520862306a36Sopenharmony_ci status = irdma_sc_add_local_mac_entry(pcmdinfo->in.u.add_local_mac_entry.cqp, 520962306a36Sopenharmony_ci &pcmdinfo->in.u.add_local_mac_entry.info, 521062306a36Sopenharmony_ci pcmdinfo->in.u.add_local_mac_entry.scratch, 521162306a36Sopenharmony_ci pcmdinfo->post_sq); 521262306a36Sopenharmony_ci break; 521362306a36Sopenharmony_ci case IRDMA_OP_DELETE_LOCAL_MAC_ENTRY: 521462306a36Sopenharmony_ci status = irdma_sc_del_local_mac_entry(pcmdinfo->in.u.del_local_mac_entry.cqp, 521562306a36Sopenharmony_ci pcmdinfo->in.u.del_local_mac_entry.scratch, 521662306a36Sopenharmony_ci pcmdinfo->in.u.del_local_mac_entry.entry_idx, 521762306a36Sopenharmony_ci pcmdinfo->in.u.del_local_mac_entry.ignore_ref_count, 521862306a36Sopenharmony_ci pcmdinfo->post_sq); 521962306a36Sopenharmony_ci break; 522062306a36Sopenharmony_ci case IRDMA_OP_AH_CREATE: 522162306a36Sopenharmony_ci status = irdma_sc_create_ah(pcmdinfo->in.u.ah_create.cqp, 522262306a36Sopenharmony_ci &pcmdinfo->in.u.ah_create.info, 522362306a36Sopenharmony_ci pcmdinfo->in.u.ah_create.scratch); 522462306a36Sopenharmony_ci break; 522562306a36Sopenharmony_ci case IRDMA_OP_AH_DESTROY: 522662306a36Sopenharmony_ci status = irdma_sc_destroy_ah(pcmdinfo->in.u.ah_destroy.cqp, 522762306a36Sopenharmony_ci &pcmdinfo->in.u.ah_destroy.info, 522862306a36Sopenharmony_ci pcmdinfo->in.u.ah_destroy.scratch); 522962306a36Sopenharmony_ci break; 523062306a36Sopenharmony_ci case IRDMA_OP_MC_CREATE: 523162306a36Sopenharmony_ci status = irdma_sc_create_mcast_grp(pcmdinfo->in.u.mc_create.cqp, 523262306a36Sopenharmony_ci &pcmdinfo->in.u.mc_create.info, 523362306a36Sopenharmony_ci pcmdinfo->in.u.mc_create.scratch); 523462306a36Sopenharmony_ci break; 523562306a36Sopenharmony_ci case IRDMA_OP_MC_DESTROY: 523662306a36Sopenharmony_ci status = irdma_sc_destroy_mcast_grp(pcmdinfo->in.u.mc_destroy.cqp, 523762306a36Sopenharmony_ci &pcmdinfo->in.u.mc_destroy.info, 523862306a36Sopenharmony_ci pcmdinfo->in.u.mc_destroy.scratch); 523962306a36Sopenharmony_ci break; 524062306a36Sopenharmony_ci case IRDMA_OP_MC_MODIFY: 524162306a36Sopenharmony_ci status = irdma_sc_modify_mcast_grp(pcmdinfo->in.u.mc_modify.cqp, 524262306a36Sopenharmony_ci &pcmdinfo->in.u.mc_modify.info, 524362306a36Sopenharmony_ci pcmdinfo->in.u.mc_modify.scratch); 524462306a36Sopenharmony_ci break; 524562306a36Sopenharmony_ci default: 524662306a36Sopenharmony_ci status = -EOPNOTSUPP; 524762306a36Sopenharmony_ci break; 524862306a36Sopenharmony_ci } 524962306a36Sopenharmony_ci 525062306a36Sopenharmony_ci return status; 525162306a36Sopenharmony_ci} 525262306a36Sopenharmony_ci 525362306a36Sopenharmony_ci/** 525462306a36Sopenharmony_ci * irdma_process_cqp_cmd - process all cqp commands 525562306a36Sopenharmony_ci * @dev: sc device struct 525662306a36Sopenharmony_ci * @pcmdinfo: cqp command info 525762306a36Sopenharmony_ci */ 525862306a36Sopenharmony_ciint irdma_process_cqp_cmd(struct irdma_sc_dev *dev, 525962306a36Sopenharmony_ci struct cqp_cmds_info *pcmdinfo) 526062306a36Sopenharmony_ci{ 526162306a36Sopenharmony_ci int status = 0; 526262306a36Sopenharmony_ci unsigned long flags; 526362306a36Sopenharmony_ci 526462306a36Sopenharmony_ci spin_lock_irqsave(&dev->cqp_lock, flags); 526562306a36Sopenharmony_ci if (list_empty(&dev->cqp_cmd_head) && !irdma_cqp_ring_full(dev->cqp)) 526662306a36Sopenharmony_ci status = irdma_exec_cqp_cmd(dev, pcmdinfo); 526762306a36Sopenharmony_ci else 526862306a36Sopenharmony_ci list_add_tail(&pcmdinfo->cqp_cmd_entry, &dev->cqp_cmd_head); 526962306a36Sopenharmony_ci spin_unlock_irqrestore(&dev->cqp_lock, flags); 527062306a36Sopenharmony_ci return status; 527162306a36Sopenharmony_ci} 527262306a36Sopenharmony_ci 527362306a36Sopenharmony_ci/** 527462306a36Sopenharmony_ci * irdma_process_bh - called from tasklet for cqp list 527562306a36Sopenharmony_ci * @dev: sc device struct 527662306a36Sopenharmony_ci */ 527762306a36Sopenharmony_ciint irdma_process_bh(struct irdma_sc_dev *dev) 527862306a36Sopenharmony_ci{ 527962306a36Sopenharmony_ci int status = 0; 528062306a36Sopenharmony_ci struct cqp_cmds_info *pcmdinfo; 528162306a36Sopenharmony_ci unsigned long flags; 528262306a36Sopenharmony_ci 528362306a36Sopenharmony_ci spin_lock_irqsave(&dev->cqp_lock, flags); 528462306a36Sopenharmony_ci while (!list_empty(&dev->cqp_cmd_head) && 528562306a36Sopenharmony_ci !irdma_cqp_ring_full(dev->cqp)) { 528662306a36Sopenharmony_ci pcmdinfo = (struct cqp_cmds_info *)irdma_remove_cqp_head(dev); 528762306a36Sopenharmony_ci status = irdma_exec_cqp_cmd(dev, pcmdinfo); 528862306a36Sopenharmony_ci if (status) 528962306a36Sopenharmony_ci break; 529062306a36Sopenharmony_ci } 529162306a36Sopenharmony_ci spin_unlock_irqrestore(&dev->cqp_lock, flags); 529262306a36Sopenharmony_ci return status; 529362306a36Sopenharmony_ci} 529462306a36Sopenharmony_ci 529562306a36Sopenharmony_ci/** 529662306a36Sopenharmony_ci * irdma_cfg_aeq- Configure AEQ interrupt 529762306a36Sopenharmony_ci * @dev: pointer to the device structure 529862306a36Sopenharmony_ci * @idx: vector index 529962306a36Sopenharmony_ci * @enable: True to enable, False disables 530062306a36Sopenharmony_ci */ 530162306a36Sopenharmony_civoid irdma_cfg_aeq(struct irdma_sc_dev *dev, u32 idx, bool enable) 530262306a36Sopenharmony_ci{ 530362306a36Sopenharmony_ci u32 reg_val; 530462306a36Sopenharmony_ci 530562306a36Sopenharmony_ci reg_val = FIELD_PREP(IRDMA_PFINT_AEQCTL_CAUSE_ENA, enable) | 530662306a36Sopenharmony_ci FIELD_PREP(IRDMA_PFINT_AEQCTL_MSIX_INDX, idx) | 530762306a36Sopenharmony_ci FIELD_PREP(IRDMA_PFINT_AEQCTL_ITR_INDX, 3); 530862306a36Sopenharmony_ci writel(reg_val, dev->hw_regs[IRDMA_PFINT_AEQCTL]); 530962306a36Sopenharmony_ci} 531062306a36Sopenharmony_ci 531162306a36Sopenharmony_ci/** 531262306a36Sopenharmony_ci * sc_vsi_update_stats - Update statistics 531362306a36Sopenharmony_ci * @vsi: sc_vsi instance to update 531462306a36Sopenharmony_ci */ 531562306a36Sopenharmony_civoid sc_vsi_update_stats(struct irdma_sc_vsi *vsi) 531662306a36Sopenharmony_ci{ 531762306a36Sopenharmony_ci struct irdma_gather_stats *gather_stats; 531862306a36Sopenharmony_ci struct irdma_gather_stats *last_gather_stats; 531962306a36Sopenharmony_ci 532062306a36Sopenharmony_ci gather_stats = vsi->pestat->gather_info.gather_stats_va; 532162306a36Sopenharmony_ci last_gather_stats = vsi->pestat->gather_info.last_gather_stats_va; 532262306a36Sopenharmony_ci irdma_update_stats(&vsi->pestat->hw_stats, gather_stats, 532362306a36Sopenharmony_ci last_gather_stats, vsi->dev->hw_stats_map, 532462306a36Sopenharmony_ci vsi->dev->hw_attrs.max_stat_idx); 532562306a36Sopenharmony_ci} 532662306a36Sopenharmony_ci 532762306a36Sopenharmony_ci/** 532862306a36Sopenharmony_ci * irdma_wait_pe_ready - Check if firmware is ready 532962306a36Sopenharmony_ci * @dev: provides access to registers 533062306a36Sopenharmony_ci */ 533162306a36Sopenharmony_cistatic int irdma_wait_pe_ready(struct irdma_sc_dev *dev) 533262306a36Sopenharmony_ci{ 533362306a36Sopenharmony_ci u32 statuscpu0; 533462306a36Sopenharmony_ci u32 statuscpu1; 533562306a36Sopenharmony_ci u32 statuscpu2; 533662306a36Sopenharmony_ci u32 retrycount = 0; 533762306a36Sopenharmony_ci 533862306a36Sopenharmony_ci do { 533962306a36Sopenharmony_ci statuscpu0 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS0]); 534062306a36Sopenharmony_ci statuscpu1 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS1]); 534162306a36Sopenharmony_ci statuscpu2 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS2]); 534262306a36Sopenharmony_ci if (statuscpu0 == 0x80 && statuscpu1 == 0x80 && 534362306a36Sopenharmony_ci statuscpu2 == 0x80) 534462306a36Sopenharmony_ci return 0; 534562306a36Sopenharmony_ci mdelay(1000); 534662306a36Sopenharmony_ci } while (retrycount++ < dev->hw_attrs.max_pe_ready_count); 534762306a36Sopenharmony_ci return -1; 534862306a36Sopenharmony_ci} 534962306a36Sopenharmony_ci 535062306a36Sopenharmony_cistatic inline void irdma_sc_init_hw(struct irdma_sc_dev *dev) 535162306a36Sopenharmony_ci{ 535262306a36Sopenharmony_ci switch (dev->hw_attrs.uk_attrs.hw_rev) { 535362306a36Sopenharmony_ci case IRDMA_GEN_1: 535462306a36Sopenharmony_ci i40iw_init_hw(dev); 535562306a36Sopenharmony_ci break; 535662306a36Sopenharmony_ci case IRDMA_GEN_2: 535762306a36Sopenharmony_ci icrdma_init_hw(dev); 535862306a36Sopenharmony_ci break; 535962306a36Sopenharmony_ci } 536062306a36Sopenharmony_ci} 536162306a36Sopenharmony_ci 536262306a36Sopenharmony_ci/** 536362306a36Sopenharmony_ci * irdma_sc_dev_init - Initialize control part of device 536462306a36Sopenharmony_ci * @ver: version 536562306a36Sopenharmony_ci * @dev: Device pointer 536662306a36Sopenharmony_ci * @info: Device init info 536762306a36Sopenharmony_ci */ 536862306a36Sopenharmony_ciint irdma_sc_dev_init(enum irdma_vers ver, struct irdma_sc_dev *dev, 536962306a36Sopenharmony_ci struct irdma_device_init_info *info) 537062306a36Sopenharmony_ci{ 537162306a36Sopenharmony_ci u32 val; 537262306a36Sopenharmony_ci int ret_code = 0; 537362306a36Sopenharmony_ci u8 db_size; 537462306a36Sopenharmony_ci 537562306a36Sopenharmony_ci INIT_LIST_HEAD(&dev->cqp_cmd_head); /* for CQP command backlog */ 537662306a36Sopenharmony_ci mutex_init(&dev->ws_mutex); 537762306a36Sopenharmony_ci dev->hmc_fn_id = info->hmc_fn_id; 537862306a36Sopenharmony_ci dev->fpm_query_buf_pa = info->fpm_query_buf_pa; 537962306a36Sopenharmony_ci dev->fpm_query_buf = info->fpm_query_buf; 538062306a36Sopenharmony_ci dev->fpm_commit_buf_pa = info->fpm_commit_buf_pa; 538162306a36Sopenharmony_ci dev->fpm_commit_buf = info->fpm_commit_buf; 538262306a36Sopenharmony_ci dev->hw = info->hw; 538362306a36Sopenharmony_ci dev->hw->hw_addr = info->bar0; 538462306a36Sopenharmony_ci /* Setup the hardware limits, hmc may limit further */ 538562306a36Sopenharmony_ci dev->hw_attrs.min_hw_qp_id = IRDMA_MIN_IW_QP_ID; 538662306a36Sopenharmony_ci dev->hw_attrs.min_hw_aeq_size = IRDMA_MIN_AEQ_ENTRIES; 538762306a36Sopenharmony_ci dev->hw_attrs.max_hw_aeq_size = IRDMA_MAX_AEQ_ENTRIES; 538862306a36Sopenharmony_ci dev->hw_attrs.min_hw_ceq_size = IRDMA_MIN_CEQ_ENTRIES; 538962306a36Sopenharmony_ci dev->hw_attrs.max_hw_ceq_size = IRDMA_MAX_CEQ_ENTRIES; 539062306a36Sopenharmony_ci dev->hw_attrs.uk_attrs.min_hw_cq_size = IRDMA_MIN_CQ_SIZE; 539162306a36Sopenharmony_ci dev->hw_attrs.uk_attrs.max_hw_cq_size = IRDMA_MAX_CQ_SIZE; 539262306a36Sopenharmony_ci dev->hw_attrs.uk_attrs.max_hw_wq_frags = IRDMA_MAX_WQ_FRAGMENT_COUNT; 539362306a36Sopenharmony_ci dev->hw_attrs.uk_attrs.max_hw_read_sges = IRDMA_MAX_SGE_RD; 539462306a36Sopenharmony_ci dev->hw_attrs.max_hw_outbound_msg_size = IRDMA_MAX_OUTBOUND_MSG_SIZE; 539562306a36Sopenharmony_ci dev->hw_attrs.max_mr_size = IRDMA_MAX_MR_SIZE; 539662306a36Sopenharmony_ci dev->hw_attrs.max_hw_inbound_msg_size = IRDMA_MAX_INBOUND_MSG_SIZE; 539762306a36Sopenharmony_ci dev->hw_attrs.max_hw_device_pages = IRDMA_MAX_PUSH_PAGE_COUNT; 539862306a36Sopenharmony_ci dev->hw_attrs.uk_attrs.max_hw_inline = IRDMA_MAX_INLINE_DATA_SIZE; 539962306a36Sopenharmony_ci dev->hw_attrs.max_hw_wqes = IRDMA_MAX_WQ_ENTRIES; 540062306a36Sopenharmony_ci dev->hw_attrs.max_qp_wr = IRDMA_MAX_QP_WRS(IRDMA_MAX_QUANTA_PER_WR); 540162306a36Sopenharmony_ci 540262306a36Sopenharmony_ci dev->hw_attrs.uk_attrs.max_hw_rq_quanta = IRDMA_QP_SW_MAX_RQ_QUANTA; 540362306a36Sopenharmony_ci dev->hw_attrs.uk_attrs.max_hw_wq_quanta = IRDMA_QP_SW_MAX_WQ_QUANTA; 540462306a36Sopenharmony_ci dev->hw_attrs.max_hw_pds = IRDMA_MAX_PDS; 540562306a36Sopenharmony_ci dev->hw_attrs.max_hw_ena_vf_count = IRDMA_MAX_PE_ENA_VF_COUNT; 540662306a36Sopenharmony_ci 540762306a36Sopenharmony_ci dev->hw_attrs.max_pe_ready_count = 14; 540862306a36Sopenharmony_ci dev->hw_attrs.max_done_count = IRDMA_DONE_COUNT; 540962306a36Sopenharmony_ci dev->hw_attrs.max_sleep_count = IRDMA_SLEEP_COUNT; 541062306a36Sopenharmony_ci dev->hw_attrs.max_cqp_compl_wait_time_ms = CQP_COMPL_WAIT_TIME_MS; 541162306a36Sopenharmony_ci 541262306a36Sopenharmony_ci dev->hw_attrs.uk_attrs.hw_rev = ver; 541362306a36Sopenharmony_ci irdma_sc_init_hw(dev); 541462306a36Sopenharmony_ci 541562306a36Sopenharmony_ci if (irdma_wait_pe_ready(dev)) 541662306a36Sopenharmony_ci return -ETIMEDOUT; 541762306a36Sopenharmony_ci 541862306a36Sopenharmony_ci val = readl(dev->hw_regs[IRDMA_GLPCI_LBARCTRL]); 541962306a36Sopenharmony_ci db_size = (u8)FIELD_GET(IRDMA_GLPCI_LBARCTRL_PE_DB_SIZE, val); 542062306a36Sopenharmony_ci if (db_size != IRDMA_PE_DB_SIZE_4M && db_size != IRDMA_PE_DB_SIZE_8M) { 542162306a36Sopenharmony_ci ibdev_dbg(to_ibdev(dev), 542262306a36Sopenharmony_ci "DEV: RDMA PE doorbell is not enabled in CSR val 0x%x db_size=%d\n", 542362306a36Sopenharmony_ci val, db_size); 542462306a36Sopenharmony_ci return -ENODEV; 542562306a36Sopenharmony_ci } 542662306a36Sopenharmony_ci dev->db_addr = dev->hw->hw_addr + (uintptr_t)dev->hw_regs[IRDMA_DB_ADDR_OFFSET]; 542762306a36Sopenharmony_ci 542862306a36Sopenharmony_ci return ret_code; 542962306a36Sopenharmony_ci} 543062306a36Sopenharmony_ci 543162306a36Sopenharmony_ci/** 543262306a36Sopenharmony_ci * irdma_stat_val - Extract HW counter value from statistics buffer 543362306a36Sopenharmony_ci * @stats_val: pointer to statistics buffer 543462306a36Sopenharmony_ci * @byteoff: byte offset of counter value in the buffer (8B-aligned) 543562306a36Sopenharmony_ci * @bitoff: bit offset of counter value within 8B entry 543662306a36Sopenharmony_ci * @bitmask: maximum counter value (e.g. 0xffffff for 24-bit counter) 543762306a36Sopenharmony_ci */ 543862306a36Sopenharmony_cistatic inline u64 irdma_stat_val(const u64 *stats_val, u16 byteoff, u8 bitoff, 543962306a36Sopenharmony_ci u64 bitmask) 544062306a36Sopenharmony_ci{ 544162306a36Sopenharmony_ci u16 idx = byteoff / sizeof(*stats_val); 544262306a36Sopenharmony_ci 544362306a36Sopenharmony_ci return (stats_val[idx] >> bitoff) & bitmask; 544462306a36Sopenharmony_ci} 544562306a36Sopenharmony_ci 544662306a36Sopenharmony_ci/** 544762306a36Sopenharmony_ci * irdma_stat_delta - Calculate counter delta 544862306a36Sopenharmony_ci * @new_val: updated counter value 544962306a36Sopenharmony_ci * @old_val: last counter value 545062306a36Sopenharmony_ci * @max_val: maximum counter value (e.g. 0xffffff for 24-bit counter) 545162306a36Sopenharmony_ci */ 545262306a36Sopenharmony_cistatic inline u64 irdma_stat_delta(u64 new_val, u64 old_val, u64 max_val) 545362306a36Sopenharmony_ci{ 545462306a36Sopenharmony_ci if (new_val >= old_val) 545562306a36Sopenharmony_ci return new_val - old_val; 545662306a36Sopenharmony_ci 545762306a36Sopenharmony_ci /* roll-over case */ 545862306a36Sopenharmony_ci return max_val - old_val + new_val + 1; 545962306a36Sopenharmony_ci} 546062306a36Sopenharmony_ci 546162306a36Sopenharmony_ci/** 546262306a36Sopenharmony_ci * irdma_update_stats - Update statistics 546362306a36Sopenharmony_ci * @hw_stats: hw_stats instance to update 546462306a36Sopenharmony_ci * @gather_stats: updated stat counters 546562306a36Sopenharmony_ci * @last_gather_stats: last stat counters 546662306a36Sopenharmony_ci * @map: HW stat map (hw_stats => gather_stats) 546762306a36Sopenharmony_ci * @max_stat_idx: number of HW stats 546862306a36Sopenharmony_ci */ 546962306a36Sopenharmony_civoid irdma_update_stats(struct irdma_dev_hw_stats *hw_stats, 547062306a36Sopenharmony_ci struct irdma_gather_stats *gather_stats, 547162306a36Sopenharmony_ci struct irdma_gather_stats *last_gather_stats, 547262306a36Sopenharmony_ci const struct irdma_hw_stat_map *map, u16 max_stat_idx) 547362306a36Sopenharmony_ci{ 547462306a36Sopenharmony_ci u64 *stats_val = hw_stats->stats_val; 547562306a36Sopenharmony_ci u16 i; 547662306a36Sopenharmony_ci 547762306a36Sopenharmony_ci for (i = 0; i < max_stat_idx; i++) { 547862306a36Sopenharmony_ci u64 new_val = irdma_stat_val(gather_stats->val, map[i].byteoff, 547962306a36Sopenharmony_ci map[i].bitoff, map[i].bitmask); 548062306a36Sopenharmony_ci u64 last_val = irdma_stat_val(last_gather_stats->val, 548162306a36Sopenharmony_ci map[i].byteoff, map[i].bitoff, 548262306a36Sopenharmony_ci map[i].bitmask); 548362306a36Sopenharmony_ci 548462306a36Sopenharmony_ci stats_val[i] += 548562306a36Sopenharmony_ci irdma_stat_delta(new_val, last_val, map[i].bitmask); 548662306a36Sopenharmony_ci } 548762306a36Sopenharmony_ci 548862306a36Sopenharmony_ci memcpy(last_gather_stats, gather_stats, sizeof(*last_gather_stats)); 548962306a36Sopenharmony_ci} 5490