1dd90451fSMustafa Ismail // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 2dd90451fSMustafa Ismail /* Copyright (c) 2016 - 2021 Intel Corporation */ 3b6459415SJakub Kicinski #include <linux/etherdevice.h> 4b6459415SJakub Kicinski 5dd90451fSMustafa Ismail #include "osdep.h" 6dd90451fSMustafa Ismail #include "hmc.h" 7dd90451fSMustafa Ismail #include "defs.h" 8dd90451fSMustafa Ismail #include "type.h" 9dd90451fSMustafa Ismail #include "protos.h" 10dd90451fSMustafa Ismail #include "uda.h" 11dd90451fSMustafa Ismail #include "uda_d.h" 12dd90451fSMustafa Ismail 13dd90451fSMustafa Ismail /** 14dd90451fSMustafa Ismail * irdma_sc_access_ah() - Create, modify or delete AH 15dd90451fSMustafa Ismail * @cqp: struct for cqp hw 16dd90451fSMustafa Ismail * @info: ah information 17dd90451fSMustafa Ismail * @op: Operation 18dd90451fSMustafa Ismail * @scratch: u64 saved to be used during cqp completion 19dd90451fSMustafa Ismail */ 202c4b14eaSShiraz Saleem int irdma_sc_access_ah(struct irdma_sc_cqp *cqp, struct irdma_ah_info *info, 21dd90451fSMustafa Ismail u32 op, u64 scratch) 22dd90451fSMustafa Ismail { 23dd90451fSMustafa Ismail __le64 *wqe; 24dd90451fSMustafa Ismail u64 qw1, qw2; 25dd90451fSMustafa Ismail 26dd90451fSMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 27dd90451fSMustafa Ismail if (!wqe) 282c4b14eaSShiraz Saleem return -ENOMEM; 29dd90451fSMustafa Ismail 30dd90451fSMustafa Ismail set_64bit_val(wqe, 0, ether_addr_to_u64(info->mac_addr) << 16); 31dd90451fSMustafa Ismail qw1 = FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_PDINDEXLO, info->pd_idx) | 32dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_TC, info->tc_tos) | 33dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDAQPC_VLANTAG, info->vlan_tag); 34dd90451fSMustafa Ismail 35dd90451fSMustafa Ismail qw2 = FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ARPINDEX, info->dst_arpindex) | 36dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_FLOWLABEL, info->flow_label) | 37dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_HOPLIMIT, info->hop_ttl) | 38dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_PDINDEXHI, info->pd_idx >> 16); 39dd90451fSMustafa Ismail 40dd90451fSMustafa Ismail if (!info->ipv4_valid) { 41dd90451fSMustafa Ismail set_64bit_val(wqe, 40, 42dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->dest_ip_addr[0]) | 43dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->dest_ip_addr[1])); 44dd90451fSMustafa Ismail set_64bit_val(wqe, 32, 45dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->dest_ip_addr[2]) | 46dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[3])); 47dd90451fSMustafa Ismail 48dd90451fSMustafa Ismail set_64bit_val(wqe, 56, 49dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->src_ip_addr[0]) | 50dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->src_ip_addr[1])); 51dd90451fSMustafa Ismail set_64bit_val(wqe, 48, 52dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->src_ip_addr[2]) | 53dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->src_ip_addr[3])); 54dd90451fSMustafa Ismail } else { 55dd90451fSMustafa Ismail set_64bit_val(wqe, 32, 56dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[0])); 57dd90451fSMustafa Ismail 58dd90451fSMustafa Ismail set_64bit_val(wqe, 48, 59dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->src_ip_addr[0])); 60dd90451fSMustafa Ismail } 61dd90451fSMustafa Ismail 62dd90451fSMustafa Ismail set_64bit_val(wqe, 8, qw1); 63dd90451fSMustafa Ismail set_64bit_val(wqe, 16, qw2); 64dd90451fSMustafa Ismail 65dd90451fSMustafa Ismail dma_wmb(); /* need write block before writing WQE header */ 66dd90451fSMustafa Ismail 67dd90451fSMustafa Ismail set_64bit_val( 68dd90451fSMustafa Ismail wqe, 24, 69dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_WQEVALID, cqp->polarity) | 70dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_OPCODE, op) | 71dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_DOLOOPBACKK, info->do_lpbk) | 72dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_IPV4VALID, info->ipv4_valid) | 73dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_AVIDX, info->ah_idx) | 74dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_INSERTVLANTAG, info->insert_vlan_tag)); 75dd90451fSMustafa Ismail 76dd90451fSMustafa Ismail print_hex_dump_debug("WQE: MANAGE_AH WQE", DUMP_PREFIX_OFFSET, 16, 8, 77dd90451fSMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false); 78dd90451fSMustafa Ismail irdma_sc_cqp_post_sq(cqp); 79dd90451fSMustafa Ismail 80dd90451fSMustafa Ismail return 0; 81dd90451fSMustafa Ismail } 82dd90451fSMustafa Ismail 83dd90451fSMustafa Ismail /** 84dd90451fSMustafa Ismail * irdma_create_mg_ctx() - create a mcg context 85dd90451fSMustafa Ismail * @info: multicast group context info 86dd90451fSMustafa Ismail */ 87*ea7596c1SZhu Yanjun static void irdma_create_mg_ctx(struct irdma_mcast_grp_info *info) 88dd90451fSMustafa Ismail { 89dd90451fSMustafa Ismail struct irdma_mcast_grp_ctx_entry_info *entry_info = NULL; 90dd90451fSMustafa Ismail u8 idx = 0; /* index in the array */ 91dd90451fSMustafa Ismail u8 ctx_idx = 0; /* index in the MG context */ 92dd90451fSMustafa Ismail 93dd90451fSMustafa Ismail memset(info->dma_mem_mc.va, 0, IRDMA_MAX_MGS_PER_CTX * sizeof(u64)); 94dd90451fSMustafa Ismail 95dd90451fSMustafa Ismail for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) { 96dd90451fSMustafa Ismail entry_info = &info->mg_ctx_info[idx]; 97dd90451fSMustafa Ismail if (entry_info->valid_entry) { 98dd90451fSMustafa Ismail set_64bit_val((__le64 *)info->dma_mem_mc.va, 99dd90451fSMustafa Ismail ctx_idx * sizeof(u64), 100dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_MGCTX_DESTPORT, entry_info->dest_port) | 101dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_MGCTX_VALIDENT, entry_info->valid_entry) | 102dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_MGCTX_QPID, entry_info->qp_id)); 103dd90451fSMustafa Ismail ctx_idx++; 104dd90451fSMustafa Ismail } 105dd90451fSMustafa Ismail } 106dd90451fSMustafa Ismail } 107dd90451fSMustafa Ismail 108dd90451fSMustafa Ismail /** 109dd90451fSMustafa Ismail * irdma_access_mcast_grp() - Access mcast group based on op 110dd90451fSMustafa Ismail * @cqp: Control QP 111dd90451fSMustafa Ismail * @info: multicast group context info 112dd90451fSMustafa Ismail * @op: operation to perform 113dd90451fSMustafa Ismail * @scratch: u64 saved to be used during cqp completion 114dd90451fSMustafa Ismail */ 1152c4b14eaSShiraz Saleem int irdma_access_mcast_grp(struct irdma_sc_cqp *cqp, 1162c4b14eaSShiraz Saleem struct irdma_mcast_grp_info *info, u32 op, 1172c4b14eaSShiraz Saleem u64 scratch) 118dd90451fSMustafa Ismail { 119dd90451fSMustafa Ismail __le64 *wqe; 120dd90451fSMustafa Ismail 121dd90451fSMustafa Ismail if (info->mg_id >= IRDMA_UDA_MAX_FSI_MGS) { 122dd90451fSMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev), "WQE: mg_id out of range\n"); 1232c4b14eaSShiraz Saleem return -EINVAL; 124dd90451fSMustafa Ismail } 125dd90451fSMustafa Ismail 126dd90451fSMustafa Ismail wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); 127dd90451fSMustafa Ismail if (!wqe) { 128dd90451fSMustafa Ismail ibdev_dbg(to_ibdev(cqp->dev), "WQE: ring full\n"); 1292c4b14eaSShiraz Saleem return -ENOMEM; 130dd90451fSMustafa Ismail } 131dd90451fSMustafa Ismail 132*ea7596c1SZhu Yanjun irdma_create_mg_ctx(info); 133dd90451fSMustafa Ismail 134dd90451fSMustafa Ismail set_64bit_val(wqe, 32, info->dma_mem_mc.pa); 135dd90451fSMustafa Ismail set_64bit_val(wqe, 16, 136dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MG_VLANID, info->vlan_id) | 137dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_QS_HANDLE, info->qs_handle)); 138dd90451fSMustafa Ismail set_64bit_val(wqe, 0, ether_addr_to_u64(info->dest_mac_addr)); 139dd90451fSMustafa Ismail set_64bit_val(wqe, 8, 140dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MG_HMC_FCN_ID, info->hmc_fcn_id)); 141dd90451fSMustafa Ismail 142dd90451fSMustafa Ismail if (!info->ipv4_valid) { 143dd90451fSMustafa Ismail set_64bit_val(wqe, 56, 144dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->dest_ip_addr[0]) | 145dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->dest_ip_addr[1])); 146dd90451fSMustafa Ismail set_64bit_val(wqe, 48, 147dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->dest_ip_addr[2]) | 148dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[3])); 149dd90451fSMustafa Ismail } else { 150dd90451fSMustafa Ismail set_64bit_val(wqe, 48, 151dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[0])); 152dd90451fSMustafa Ismail } 153dd90451fSMustafa Ismail 154dd90451fSMustafa Ismail dma_wmb(); /* need write memory block before writing the WQE header. */ 155dd90451fSMustafa Ismail 156dd90451fSMustafa Ismail set_64bit_val(wqe, 24, 157dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MG_WQEVALID, cqp->polarity) | 158dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MG_OPCODE, op) | 159dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MG_MGIDX, info->mg_id) | 160dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MG_VLANVALID, info->vlan_valid) | 161dd90451fSMustafa Ismail FIELD_PREP(IRDMA_UDA_CQPSQ_MG_IPV4VALID, info->ipv4_valid)); 162dd90451fSMustafa Ismail 163dd90451fSMustafa Ismail print_hex_dump_debug("WQE: MANAGE_MCG WQE", DUMP_PREFIX_OFFSET, 16, 8, 164dd90451fSMustafa Ismail wqe, IRDMA_CQP_WQE_SIZE * 8, false); 165dd90451fSMustafa Ismail print_hex_dump_debug("WQE: MCG_HOST CTX WQE", DUMP_PREFIX_OFFSET, 16, 166dd90451fSMustafa Ismail 8, info->dma_mem_mc.va, 167dd90451fSMustafa Ismail IRDMA_MAX_MGS_PER_CTX * 8, false); 168dd90451fSMustafa Ismail irdma_sc_cqp_post_sq(cqp); 169dd90451fSMustafa Ismail 170dd90451fSMustafa Ismail return 0; 171dd90451fSMustafa Ismail } 172dd90451fSMustafa Ismail 173dd90451fSMustafa Ismail /** 174dd90451fSMustafa Ismail * irdma_compare_mgs - Compares two multicast group structures 175dd90451fSMustafa Ismail * @entry1: Multcast group info 176dd90451fSMustafa Ismail * @entry2: Multcast group info in context 177dd90451fSMustafa Ismail */ 178dd90451fSMustafa Ismail static bool irdma_compare_mgs(struct irdma_mcast_grp_ctx_entry_info *entry1, 179dd90451fSMustafa Ismail struct irdma_mcast_grp_ctx_entry_info *entry2) 180dd90451fSMustafa Ismail { 181dd90451fSMustafa Ismail if (entry1->dest_port == entry2->dest_port && 182dd90451fSMustafa Ismail entry1->qp_id == entry2->qp_id) 183dd90451fSMustafa Ismail return true; 184dd90451fSMustafa Ismail 185dd90451fSMustafa Ismail return false; 186dd90451fSMustafa Ismail } 187dd90451fSMustafa Ismail 188dd90451fSMustafa Ismail /** 189dd90451fSMustafa Ismail * irdma_sc_add_mcast_grp - Allocates mcast group entry in ctx 190dd90451fSMustafa Ismail * @ctx: Multcast group context 191dd90451fSMustafa Ismail * @mg: Multcast group info 192dd90451fSMustafa Ismail */ 1932c4b14eaSShiraz Saleem int irdma_sc_add_mcast_grp(struct irdma_mcast_grp_info *ctx, 194dd90451fSMustafa Ismail struct irdma_mcast_grp_ctx_entry_info *mg) 195dd90451fSMustafa Ismail { 196dd90451fSMustafa Ismail u32 idx; 197dd90451fSMustafa Ismail bool free_entry_found = false; 198dd90451fSMustafa Ismail u32 free_entry_idx = 0; 199dd90451fSMustafa Ismail 200dd90451fSMustafa Ismail /* find either an identical or a free entry for a multicast group */ 201dd90451fSMustafa Ismail for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) { 202dd90451fSMustafa Ismail if (ctx->mg_ctx_info[idx].valid_entry) { 203dd90451fSMustafa Ismail if (irdma_compare_mgs(&ctx->mg_ctx_info[idx], mg)) { 204dd90451fSMustafa Ismail ctx->mg_ctx_info[idx].use_cnt++; 205dd90451fSMustafa Ismail return 0; 206dd90451fSMustafa Ismail } 207dd90451fSMustafa Ismail continue; 208dd90451fSMustafa Ismail } 209dd90451fSMustafa Ismail if (!free_entry_found) { 210dd90451fSMustafa Ismail free_entry_found = true; 211dd90451fSMustafa Ismail free_entry_idx = idx; 212dd90451fSMustafa Ismail } 213dd90451fSMustafa Ismail } 214dd90451fSMustafa Ismail 215dd90451fSMustafa Ismail if (free_entry_found) { 216dd90451fSMustafa Ismail ctx->mg_ctx_info[free_entry_idx] = *mg; 217dd90451fSMustafa Ismail ctx->mg_ctx_info[free_entry_idx].valid_entry = true; 218dd90451fSMustafa Ismail ctx->mg_ctx_info[free_entry_idx].use_cnt = 1; 219dd90451fSMustafa Ismail ctx->no_of_mgs++; 220dd90451fSMustafa Ismail return 0; 221dd90451fSMustafa Ismail } 222dd90451fSMustafa Ismail 2232c4b14eaSShiraz Saleem return -ENOMEM; 224dd90451fSMustafa Ismail } 225dd90451fSMustafa Ismail 226dd90451fSMustafa Ismail /** 227dd90451fSMustafa Ismail * irdma_sc_del_mcast_grp - Delete mcast group 228dd90451fSMustafa Ismail * @ctx: Multcast group context 229dd90451fSMustafa Ismail * @mg: Multcast group info 230dd90451fSMustafa Ismail * 231dd90451fSMustafa Ismail * Finds and removes a specific mulicast group from context, all 232dd90451fSMustafa Ismail * parameters must match to remove a multicast group. 233dd90451fSMustafa Ismail */ 2342c4b14eaSShiraz Saleem int irdma_sc_del_mcast_grp(struct irdma_mcast_grp_info *ctx, 235dd90451fSMustafa Ismail struct irdma_mcast_grp_ctx_entry_info *mg) 236dd90451fSMustafa Ismail { 237dd90451fSMustafa Ismail u32 idx; 238dd90451fSMustafa Ismail 239dd90451fSMustafa Ismail /* find an entry in multicast group context */ 240dd90451fSMustafa Ismail for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) { 241dd90451fSMustafa Ismail if (!ctx->mg_ctx_info[idx].valid_entry) 242dd90451fSMustafa Ismail continue; 243dd90451fSMustafa Ismail 244dd90451fSMustafa Ismail if (irdma_compare_mgs(mg, &ctx->mg_ctx_info[idx])) { 245dd90451fSMustafa Ismail ctx->mg_ctx_info[idx].use_cnt--; 246dd90451fSMustafa Ismail 247dd90451fSMustafa Ismail if (!ctx->mg_ctx_info[idx].use_cnt) { 248dd90451fSMustafa Ismail ctx->mg_ctx_info[idx].valid_entry = false; 249dd90451fSMustafa Ismail ctx->no_of_mgs--; 250dd90451fSMustafa Ismail /* Remove gap if element was not the last */ 251dd90451fSMustafa Ismail if (idx != ctx->no_of_mgs && 252dd90451fSMustafa Ismail ctx->no_of_mgs > 0) { 253dd90451fSMustafa Ismail memcpy(&ctx->mg_ctx_info[idx], 254dd90451fSMustafa Ismail &ctx->mg_ctx_info[ctx->no_of_mgs - 1], 255dd90451fSMustafa Ismail sizeof(ctx->mg_ctx_info[idx])); 256dd90451fSMustafa Ismail ctx->mg_ctx_info[ctx->no_of_mgs - 1].valid_entry = false; 257dd90451fSMustafa Ismail } 258dd90451fSMustafa Ismail } 259dd90451fSMustafa Ismail 260dd90451fSMustafa Ismail return 0; 261dd90451fSMustafa Ismail } 262dd90451fSMustafa Ismail } 263dd90451fSMustafa Ismail 2642c4b14eaSShiraz Saleem return -EINVAL; 265dd90451fSMustafa Ismail } 266