Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA/irdma: Add GEN3 core driver support

Introduce support for the GEN3 auxiliary core driver, which is
responsible for initializing PCI-level RDMA resources.

Facilitate host-driver communication with the device's Control Plane (CP)
to discover capabilities and perform privileged operations through an
RDMA-specific messaging interface built atop the IDPF mailbox and virtual
channel protocol.

Establish the RDMA virtual channel message interface and incorporate
operations to retrieve the hardware version and discover capabilities
from the CP.

Additionally, set up the RDMA MMIO regions and initialize the RF structure.

Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
Co-developed-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
Link: https://patch.msgid.link/20250827152545.2056-3-tatyana.e.nikolova@intel.com
Tested-by: Jacob Moroni <jmoroni@google.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Mustafa Ismail and committed by
Leon Romanovsky
d5edd333 0c2b80ca

+1224 -127
+2
drivers/infiniband/hw/irdma/Makefile
··· 13 13 hw.o \ 14 14 i40iw_hw.o \ 15 15 i40iw_if.o \ 16 + ig3rdma_if.o\ 16 17 icrdma_if.o \ 17 18 icrdma_hw.o \ 18 19 main.o \ ··· 24 23 uk.o \ 25 24 utils.o \ 26 25 verbs.o \ 26 + virtchnl.o \ 27 27 ws.o \ 28 28 29 29 CFLAGS_trace.o = -I$(src)
+407 -77
drivers/infiniband/hw/irdma/ctrl.c
··· 1080 1080 FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID) | 1081 1081 FIELD_PREP(IRDMA_CQPSQ_STAG_STAGLEN, info->total_len)); 1082 1082 set_64bit_val(wqe, 16, 1083 - FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx)); 1083 + FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx) | 1084 + FIELD_PREP(IRDMA_CQPSQ_STAG_PDID_HI, info->pd_id >> 18)); 1084 1085 set_64bit_val(wqe, 40, 1085 1086 FIELD_PREP(IRDMA_CQPSQ_STAG_HMCFNIDX, info->hmc_fcn_index)); 1086 1087 ··· 1166 1165 FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID)); 1167 1166 set_64bit_val(wqe, 16, 1168 1167 FIELD_PREP(IRDMA_CQPSQ_STAG_KEY, info->stag_key) | 1168 + FIELD_PREP(IRDMA_CQPSQ_STAG_PDID_HI, info->pd_id >> 18) | 1169 1169 FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx)); 1170 1170 if (!info->chunk_size) { 1171 1171 set_64bit_val(wqe, 32, info->reg_addr_pa); ··· 1225 1223 set_64bit_val(wqe, 8, 1226 1224 FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID)); 1227 1225 set_64bit_val(wqe, 16, 1228 - FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx)); 1226 + FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->stag_idx) | 1227 + FIELD_PREP(IRDMA_CQPSQ_STAG_PDID_HI, info->pd_id >> 18)); 1229 1228 1230 1229 hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_DEALLOC_STAG) | 1231 1230 FIELD_PREP(IRDMA_CQPSQ_STAG_MR, info->mr) | ··· 1266 1263 set_64bit_val(wqe, 8, 1267 1264 FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID)); 1268 1265 set_64bit_val(wqe, 16, 1269 - FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->mw_stag_index)); 1266 + FIELD_PREP(IRDMA_CQPSQ_STAG_IDX, info->mw_stag_index) | 1267 + FIELD_PREP(IRDMA_CQPSQ_STAG_PDID_HI, info->pd_id >> 18)); 1270 1268 1271 1269 hdr = FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_ALLOC_STAG) | 1272 1270 FIELD_PREP(IRDMA_CQPSQ_STAG_MWTYPE, info->mw_wide) | ··· 1892 1888 * irdma_get_stats_idx - Return stats index 1893 1889 * @vsi: pointer to the vsi 1894 1890 */ 1895 - static u8 irdma_get_stats_idx(struct irdma_sc_vsi *vsi) 1891 + static u16 irdma_get_stats_idx(struct irdma_sc_vsi *vsi) 1896 1892 { 1897 1893 struct irdma_stats_inst_info stats_info = {}; 1898 1894 struct irdma_sc_dev *dev = vsi->dev; ··· 1973 1969 /* when stat allocation is not required default to fcn_id. */ 1974 1970 vsi->stats_idx = info->fcn_id; 1975 1971 if (info->alloc_stats_inst) { 1976 - u8 stats_idx = irdma_get_stats_idx(vsi); 1972 + u16 stats_idx = irdma_get_stats_idx(vsi); 1977 1973 1978 1974 if (stats_idx != IRDMA_INVALID_STATS_IDX) { 1979 1975 vsi->stats_inst_alloc = true; ··· 1997 1993 { 1998 1994 struct irdma_stats_inst_info stats_info = {}; 1999 1995 struct irdma_sc_dev *dev = vsi->dev; 2000 - u8 stats_idx = vsi->stats_idx; 1996 + u16 stats_idx = vsi->stats_idx; 2001 1997 2002 1998 if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) { 2003 1999 if (vsi->stats_inst_alloc) { ··· 2798 2794 obj_info[rsrc_idx].cnt = (u32)FLD_RS_64(dev, temp, IRDMA_COMMIT_FPM_CQCNT); 2799 2795 break; 2800 2796 case IRDMA_HMC_IW_APBVT_ENTRY: 2801 - obj_info[rsrc_idx].cnt = 1; 2797 + if (dev->hw_attrs.uk_attrs.hw_rev <= IRDMA_GEN_2) 2798 + obj_info[rsrc_idx].cnt = 1; 2799 + else 2800 + obj_info[rsrc_idx].cnt = 0; 2802 2801 break; 2803 2802 default: 2804 2803 obj_info[rsrc_idx].cnt = (u32)temp; ··· 2836 2829 IRDMA_HMC_IW_QP); 2837 2830 irdma_sc_decode_fpm_commit(dev, buf, 8, info, 2838 2831 IRDMA_HMC_IW_CQ); 2839 - /* skiping RSRVD */ 2832 + irdma_sc_decode_fpm_commit(dev, buf, 16, info, 2833 + IRDMA_HMC_IW_SRQ); 2840 2834 irdma_sc_decode_fpm_commit(dev, buf, 24, info, 2841 2835 IRDMA_HMC_IW_HTE); 2842 2836 irdma_sc_decode_fpm_commit(dev, buf, 32, info, ··· 2872 2864 IRDMA_HMC_IW_HDR); 2873 2865 irdma_sc_decode_fpm_commit(dev, buf, 152, info, 2874 2866 IRDMA_HMC_IW_MD); 2875 - irdma_sc_decode_fpm_commit(dev, buf, 160, info, 2876 - IRDMA_HMC_IW_OOISC); 2877 - irdma_sc_decode_fpm_commit(dev, buf, 168, info, 2878 - IRDMA_HMC_IW_OOISCFFL); 2867 + if (dev->cqp->protocol_used == IRDMA_IWARP_PROTOCOL_ONLY) { 2868 + irdma_sc_decode_fpm_commit(dev, buf, 160, info, 2869 + IRDMA_HMC_IW_OOISC); 2870 + irdma_sc_decode_fpm_commit(dev, buf, 168, info, 2871 + IRDMA_HMC_IW_OOISCFFL); 2872 + } 2879 2873 } 2880 2874 2881 2875 /* searching for the last object in HMC to find the size of the HMC area. */ 2882 2876 for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) { 2883 - if (info[i].base > max_base) { 2877 + if (info[i].base > max_base && info[i].cnt) { 2884 2878 max_base = info[i].base; 2885 2879 last_hmc_obj = i; 2886 2880 } ··· 2945 2935 2946 2936 get_64bit_val(buf, 0, &temp); 2947 2937 hmc_info->first_sd_index = (u16)FIELD_GET(IRDMA_QUERY_FPM_FIRST_PE_SD_INDEX, temp); 2948 - max_pe_sds = (u16)FIELD_GET(IRDMA_QUERY_FPM_MAX_PE_SDS, temp); 2938 + 2939 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) 2940 + max_pe_sds = (u16)FIELD_GET(IRDMA_QUERY_FPM_MAX_PE_SDS_GEN3, temp); 2941 + else 2942 + max_pe_sds = (u16)FIELD_GET(IRDMA_QUERY_FPM_MAX_PE_SDS, temp); 2943 + 2944 + /* Reduce SD count for unprivleged functions by 1 to account for PBLE 2945 + * backing page rounding 2946 + */ 2947 + if (dev->hw_attrs.uk_attrs.hw_rev <= IRDMA_GEN_2 && 2948 + (hmc_info->hmc_fn_id >= dev->hw_attrs.first_hw_vf_fpm_id || 2949 + !dev->privileged)) 2950 + max_pe_sds--; 2949 2951 2950 2952 hmc_fpm_misc->max_sds = max_pe_sds; 2951 2953 hmc_info->sd_table.sd_cnt = max_pe_sds + hmc_info->first_sd_index; ··· 2971 2949 size = (u32)(temp >> 32); 2972 2950 obj_info[IRDMA_HMC_IW_CQ].size = BIT_ULL(size); 2973 2951 2952 + irdma_sc_decode_fpm_query(buf, 24, obj_info, IRDMA_HMC_IW_SRQ); 2974 2953 irdma_sc_decode_fpm_query(buf, 32, obj_info, IRDMA_HMC_IW_HTE); 2975 2954 irdma_sc_decode_fpm_query(buf, 40, obj_info, IRDMA_HMC_IW_ARP); 2976 2955 2977 - obj_info[IRDMA_HMC_IW_APBVT_ENTRY].size = 8192; 2978 - obj_info[IRDMA_HMC_IW_APBVT_ENTRY].max_cnt = 1; 2956 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) { 2957 + obj_info[IRDMA_HMC_IW_APBVT_ENTRY].size = 0; 2958 + obj_info[IRDMA_HMC_IW_APBVT_ENTRY].max_cnt = 0; 2959 + } else { 2960 + obj_info[IRDMA_HMC_IW_APBVT_ENTRY].size = 8192; 2961 + obj_info[IRDMA_HMC_IW_APBVT_ENTRY].max_cnt = 1; 2962 + } 2979 2963 2980 2964 irdma_sc_decode_fpm_query(buf, 48, obj_info, IRDMA_HMC_IW_MR); 2981 2965 irdma_sc_decode_fpm_query(buf, 56, obj_info, IRDMA_HMC_IW_XF); ··· 2990 2962 obj_info[IRDMA_HMC_IW_XFFL].max_cnt = (u32)temp; 2991 2963 obj_info[IRDMA_HMC_IW_XFFL].size = 4; 2992 2964 hmc_fpm_misc->xf_block_size = FIELD_GET(IRDMA_QUERY_FPM_XFBLOCKSIZE, temp); 2993 - if (!hmc_fpm_misc->xf_block_size) 2965 + if (obj_info[IRDMA_HMC_IW_XF].max_cnt && !hmc_fpm_misc->xf_block_size) 2994 2966 return -EINVAL; 2995 2967 2996 2968 irdma_sc_decode_fpm_query(buf, 72, obj_info, IRDMA_HMC_IW_Q1); ··· 3028 3000 3029 3001 irdma_sc_decode_fpm_query(buf, 144, obj_info, IRDMA_HMC_IW_HDR); 3030 3002 irdma_sc_decode_fpm_query(buf, 152, obj_info, IRDMA_HMC_IW_MD); 3031 - irdma_sc_decode_fpm_query(buf, 160, obj_info, IRDMA_HMC_IW_OOISC); 3032 3003 3033 - get_64bit_val(buf, 168, &temp); 3034 - obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt = (u32)temp; 3035 - obj_info[IRDMA_HMC_IW_OOISCFFL].size = 4; 3036 - hmc_fpm_misc->ooiscf_block_size = FIELD_GET(IRDMA_QUERY_FPM_OOISCFBLOCKSIZE, temp); 3037 - if (!hmc_fpm_misc->ooiscf_block_size && 3038 - obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt) 3039 - return -EINVAL; 3004 + if (dev->cqp->protocol_used == IRDMA_IWARP_PROTOCOL_ONLY) { 3005 + irdma_sc_decode_fpm_query(buf, 160, obj_info, IRDMA_HMC_IW_OOISC); 3006 + 3007 + get_64bit_val(buf, 168, &temp); 3008 + obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt = (u32)temp; 3009 + obj_info[IRDMA_HMC_IW_OOISCFFL].size = 4; 3010 + hmc_fpm_misc->ooiscf_block_size = FIELD_GET(IRDMA_QUERY_FPM_OOISCFBLOCKSIZE, temp); 3011 + if (!hmc_fpm_misc->ooiscf_block_size && 3012 + obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt) 3013 + return -EINVAL; 3014 + } 3015 + 3016 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) { 3017 + get_64bit_val(buf, 176, &temp); 3018 + hmc_fpm_misc->loc_mem_pages = (u32)FIELD_GET(IRDMA_QUERY_FPM_LOC_MEM_PAGES, temp); 3019 + if (!hmc_fpm_misc->loc_mem_pages) 3020 + return -EINVAL; 3021 + } 3040 3022 3041 3023 return 0; 3042 3024 } ··· 4374 4336 } 4375 4337 4376 4338 /** 4339 + * irdma_set_loc_mem() - set a local memory bit field 4340 + * @buf: ptr to a buffer where local memory gets enabled 4341 + */ 4342 + static void irdma_set_loc_mem(__le64 *buf) 4343 + { 4344 + u64 loc_mem_en = BIT_ULL(ENABLE_LOC_MEM); 4345 + u32 offset; 4346 + u64 temp; 4347 + 4348 + for (offset = 0; offset < IRDMA_COMMIT_FPM_BUF_SIZE; 4349 + offset += sizeof(__le64)) { 4350 + if (offset == IRDMA_PBLE_COMMIT_OFFSET) 4351 + continue; 4352 + get_64bit_val(buf, offset, &temp); 4353 + if (temp) 4354 + set_64bit_val(buf, offset, temp | loc_mem_en); 4355 + } 4356 + } 4357 + 4358 + /** 4377 4359 * irdma_sc_cfg_iw_fpm() - commits hmc obj cnt values using cqp 4378 4360 * command and populates fpm base address in hmc_info 4379 4361 * @dev : ptr to irdma_dev struct ··· 4414 4356 4415 4357 set_64bit_val(buf, 0, (u64)obj_info[IRDMA_HMC_IW_QP].cnt); 4416 4358 set_64bit_val(buf, 8, (u64)obj_info[IRDMA_HMC_IW_CQ].cnt); 4417 - set_64bit_val(buf, 16, (u64)0); /* RSRVD */ 4359 + set_64bit_val(buf, 16, (u64)obj_info[IRDMA_HMC_IW_SRQ].cnt); 4418 4360 set_64bit_val(buf, 24, (u64)obj_info[IRDMA_HMC_IW_HTE].cnt); 4419 4361 set_64bit_val(buf, 32, (u64)obj_info[IRDMA_HMC_IW_ARP].cnt); 4420 4362 set_64bit_val(buf, 40, (u64)0); /* RSVD */ ··· 4441 4383 (u64)obj_info[IRDMA_HMC_IW_OOISC].cnt); 4442 4384 set_64bit_val(buf, 168, 4443 4385 (u64)obj_info[IRDMA_HMC_IW_OOISCFFL].cnt); 4444 - 4386 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3 && 4387 + dev->hmc_fpm_misc.loc_mem_pages) 4388 + irdma_set_loc_mem(buf); 4445 4389 commit_fpm_mem.pa = dev->fpm_commit_buf_pa; 4446 4390 commit_fpm_mem.va = dev->fpm_commit_buf; 4447 4391 ··· 4652 4592 static u32 irdma_est_sd(struct irdma_sc_dev *dev, 4653 4593 struct irdma_hmc_info *hmc_info) 4654 4594 { 4595 + struct irdma_hmc_obj_info *pble_info; 4655 4596 int i; 4656 4597 u64 size = 0; 4657 4598 u64 sd; ··· 4661 4600 if (i != IRDMA_HMC_IW_PBLE) 4662 4601 size += round_up(hmc_info->hmc_obj[i].cnt * 4663 4602 hmc_info->hmc_obj[i].size, 512); 4664 - size += round_up(hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt * 4665 - hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].size, 512); 4603 + 4604 + pble_info = &hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE]; 4605 + if (dev->privileged) 4606 + size += round_up(pble_info->cnt * pble_info->size, 512); 4666 4607 if (size & 0x1FFFFF) 4667 4608 sd = (size >> 21) + 1; /* add 1 for remainder */ 4668 4609 else 4669 4610 sd = size >> 21; 4611 + if (!dev->privileged && !dev->hmc_fpm_misc.loc_mem_pages) { 4612 + /* 2MB alignment for VF PBLE HMC */ 4613 + size = pble_info->cnt * pble_info->size; 4614 + if (size & 0x1FFFFF) 4615 + sd += (size >> 21) + 1; /* add 1 for remainder */ 4616 + else 4617 + sd += size >> 21; 4618 + } 4670 4619 if (sd > 0xFFFFFFFF) { 4671 4620 ibdev_dbg(to_ibdev(dev), "HMC: sd overflow[%lld]\n", sd); 4672 4621 sd = 0xFFFFFFFF - 1; 4673 4622 } 4674 4623 4675 4624 return (u32)sd; 4676 - } 4677 - 4678 - /** 4679 - * irdma_sc_query_rdma_features_done - poll cqp for query features done 4680 - * @cqp: struct for cqp hw 4681 - */ 4682 - static int irdma_sc_query_rdma_features_done(struct irdma_sc_cqp *cqp) 4683 - { 4684 - return irdma_sc_poll_for_cqp_op_done(cqp, 4685 - IRDMA_CQP_OP_QUERY_RDMA_FEATURES, 4686 - NULL); 4687 4625 } 4688 4626 4689 4627 /** ··· 4694 4634 static int irdma_sc_query_rdma_features(struct irdma_sc_cqp *cqp, 4695 4635 struct irdma_dma_mem *buf, u64 scratch) 4696 4636 { 4637 + u32 tail, val, error; 4697 4638 __le64 *wqe; 4639 + int status; 4698 4640 u64 temp; 4699 4641 4700 4642 wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch); ··· 4716 4654 4717 4655 print_hex_dump_debug("WQE: QUERY RDMA FEATURES", DUMP_PREFIX_OFFSET, 4718 4656 16, 8, wqe, IRDMA_CQP_WQE_SIZE * 8, false); 4719 - irdma_sc_cqp_post_sq(cqp); 4657 + irdma_get_cqp_reg_info(cqp, &val, &tail, &error); 4720 4658 4721 - return 0; 4659 + irdma_sc_cqp_post_sq(cqp); 4660 + status = irdma_cqp_poll_registers(cqp, tail, 4661 + cqp->dev->hw_attrs.max_done_count); 4662 + if (error || status) 4663 + status = -EINVAL; 4664 + 4665 + return status; 4722 4666 } 4723 4667 4724 4668 /** ··· 4746 4678 return -ENOMEM; 4747 4679 4748 4680 ret_code = irdma_sc_query_rdma_features(dev->cqp, &feat_buf, 0); 4749 - if (!ret_code) 4750 - ret_code = irdma_sc_query_rdma_features_done(dev->cqp); 4751 4681 if (ret_code) 4752 4682 goto exit; 4753 4683 ··· 4769 4703 return -ENOMEM; 4770 4704 4771 4705 ret_code = irdma_sc_query_rdma_features(dev->cqp, &feat_buf, 0); 4772 - if (!ret_code) 4773 - ret_code = irdma_sc_query_rdma_features_done(dev->cqp); 4774 4706 if (ret_code) 4775 4707 goto exit; 4776 4708 ··· 4850 4786 } 4851 4787 4852 4788 /** 4789 + * irdma_get_rsrc_mem_config - configure resources if local memory or host 4790 + * @dev: sc device struct 4791 + * @is_mrte_loc_mem: if true, MR's to be in local memory because sd=loc pages 4792 + * 4793 + * Only mr can be configured host or local memory if qp's are in local memory. 4794 + * If qp is in local memory, then all resource object will be in local memory 4795 + * except mr which can be either host or local memory. The only exception 4796 + * is pble's which are always in host memory. 4797 + */ 4798 + static void irdma_get_rsrc_mem_config(struct irdma_sc_dev *dev, bool is_mrte_loc_mem) 4799 + { 4800 + struct irdma_hmc_info *hmc_info = dev->hmc_info; 4801 + int i; 4802 + 4803 + for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) 4804 + hmc_info->hmc_obj[i].mem_loc = IRDMA_LOC_MEM; 4805 + 4806 + if (dev->feature_info[IRDMA_OBJ_1] && !is_mrte_loc_mem) { 4807 + u8 mem_type; 4808 + 4809 + mem_type = (u8)FIELD_GET(IRDMA_MR_MEM_LOC, dev->feature_info[IRDMA_OBJ_1]); 4810 + 4811 + hmc_info->hmc_obj[IRDMA_HMC_IW_MR].mem_loc = 4812 + (mem_type & IRDMA_OBJ_LOC_MEM_BIT) ? 4813 + IRDMA_LOC_MEM : IRDMA_HOST_MEM; 4814 + } else { 4815 + hmc_info->hmc_obj[IRDMA_HMC_IW_MR].mem_loc = IRDMA_LOC_MEM; 4816 + } 4817 + 4818 + hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].mem_loc = IRDMA_HOST_MEM; 4819 + 4820 + ibdev_dbg(to_ibdev(dev), "HMC: INFO: mrte_mem_loc = %d pble = %d\n", 4821 + hmc_info->hmc_obj[IRDMA_HMC_IW_MR].mem_loc, 4822 + hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].mem_loc); 4823 + } 4824 + 4825 + /** 4826 + * irdma_cfg_sd_mem - allocate sd memory 4827 + * @dev: sc device struct 4828 + * @hmc_info: ptr to irdma_hmc_obj_info struct 4829 + */ 4830 + static int irdma_cfg_sd_mem(struct irdma_sc_dev *dev, 4831 + struct irdma_hmc_info *hmc_info) 4832 + { 4833 + struct irdma_virt_mem virt_mem; 4834 + u32 mem_size; 4835 + 4836 + mem_size = sizeof(struct irdma_hmc_sd_entry) * hmc_info->sd_table.sd_cnt; 4837 + virt_mem.size = mem_size; 4838 + virt_mem.va = kzalloc(virt_mem.size, GFP_KERNEL); 4839 + if (!virt_mem.va) 4840 + return -ENOMEM; 4841 + hmc_info->sd_table.sd_entry = virt_mem.va; 4842 + 4843 + return 0; 4844 + } 4845 + 4846 + /** 4847 + * irdma_get_objs_pages - get number of 2M pages needed 4848 + * @dev: sc device struct 4849 + * @hmc_info: pointer to the HMC configuration information struct 4850 + * @mem_loc: pages for local or host memory 4851 + */ 4852 + static u32 irdma_get_objs_pages(struct irdma_sc_dev *dev, 4853 + struct irdma_hmc_info *hmc_info, 4854 + enum irdma_hmc_obj_mem mem_loc) 4855 + { 4856 + u64 size = 0; 4857 + int i; 4858 + 4859 + for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) { 4860 + if (hmc_info->hmc_obj[i].mem_loc == mem_loc) { 4861 + size += round_up(hmc_info->hmc_obj[i].cnt * 4862 + hmc_info->hmc_obj[i].size, 512); 4863 + } 4864 + } 4865 + 4866 + return DIV_ROUND_UP(size, IRDMA_HMC_PAGE_SIZE); 4867 + } 4868 + 4869 + /** 4870 + * irdma_set_host_hmc_rsrc_gen_3 - calculate host hmc resources for gen 3 4871 + * @dev: sc device struct 4872 + */ 4873 + static void irdma_set_host_hmc_rsrc_gen_3(struct irdma_sc_dev *dev) 4874 + { 4875 + struct irdma_hmc_fpm_misc *hmc_fpm_misc; 4876 + struct irdma_hmc_info *hmc_info; 4877 + enum irdma_hmc_obj_mem mrte_loc; 4878 + u32 mrwanted, pblewanted; 4879 + u32 avail_sds, mr_sds; 4880 + 4881 + hmc_info = dev->hmc_info; 4882 + hmc_fpm_misc = &dev->hmc_fpm_misc; 4883 + avail_sds = hmc_fpm_misc->max_sds; 4884 + mrte_loc = hmc_info->hmc_obj[IRDMA_HMC_IW_MR].mem_loc; 4885 + mrwanted = hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt; 4886 + pblewanted = hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].max_cnt; 4887 + 4888 + if (mrte_loc == IRDMA_HOST_MEM && avail_sds > IRDMA_MIN_PBLE_PAGES) { 4889 + mr_sds = avail_sds - IRDMA_MIN_PBLE_PAGES; 4890 + mrwanted = min(mrwanted, mr_sds * MAX_MR_PER_SD); 4891 + hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt = mrwanted; 4892 + avail_sds -= DIV_ROUND_UP(mrwanted, MAX_MR_PER_SD); 4893 + } 4894 + 4895 + pblewanted = min(pblewanted, avail_sds * MAX_PBLE_PER_SD); 4896 + hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt = pblewanted; 4897 + } 4898 + 4899 + /** 4900 + * irdma_set_loc_hmc_rsrc_gen_3 - calculate hmc resources for gen 3 4901 + * @dev: sc device struct 4902 + * @max_pages: max local memory available 4903 + * @qpwanted: number of qp's wanted 4904 + */ 4905 + static int irdma_set_loc_hmc_rsrc_gen_3(struct irdma_sc_dev *dev, 4906 + u32 max_pages, 4907 + u32 qpwanted) 4908 + { 4909 + struct irdma_hmc_fpm_misc *hmc_fpm_misc; 4910 + u32 rrf_cnt, xf_cnt, timer_cnt, pages_needed; 4911 + struct irdma_hmc_info *hmc_info; 4912 + u32 ird, ord; 4913 + 4914 + hmc_info = dev->hmc_info; 4915 + hmc_fpm_misc = &dev->hmc_fpm_misc; 4916 + ird = dev->hw_attrs.max_hw_ird; 4917 + ord = dev->hw_attrs.max_hw_ord; 4918 + 4919 + hmc_info->hmc_obj[IRDMA_HMC_IW_HDR].cnt = qpwanted; 4920 + hmc_info->hmc_obj[IRDMA_HMC_IW_QP].cnt = qpwanted; 4921 + 4922 + hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt = 4923 + min(hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt, qpwanted * 2); 4924 + 4925 + hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt = 4926 + min(qpwanted * 8, hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt); 4927 + 4928 + rrf_cnt = roundup_pow_of_two(IRDMA_RRF_MULTIPLIER * qpwanted); 4929 + hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].cnt = 4930 + min(hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].max_cnt, rrf_cnt); 4931 + 4932 + if (hmc_info->hmc_obj[IRDMA_HMC_IW_RRFFL].max_cnt) 4933 + hmc_info->hmc_obj[IRDMA_HMC_IW_RRFFL].cnt = 4934 + hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].cnt / 4935 + hmc_fpm_misc->rrf_block_size; 4936 + 4937 + xf_cnt = roundup_pow_of_two(IRDMA_XF_MULTIPLIER * qpwanted); 4938 + hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt = 4939 + min(hmc_info->hmc_obj[IRDMA_HMC_IW_XF].max_cnt, xf_cnt); 4940 + hmc_info->hmc_obj[IRDMA_HMC_IW_XFFL].cnt = 4941 + xf_cnt / hmc_fpm_misc->xf_block_size; 4942 + 4943 + timer_cnt = (round_up(qpwanted, 512) / 512 + 1) * 4944 + hmc_fpm_misc->timer_bucket; 4945 + hmc_info->hmc_obj[IRDMA_HMC_IW_TIMER].cnt = 4946 + min(timer_cnt, hmc_info->hmc_obj[IRDMA_HMC_IW_TIMER].cnt); 4947 + 4948 + do { 4949 + hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt = roundup_pow_of_two(ird * 2 * qpwanted); 4950 + hmc_info->hmc_obj[IRDMA_HMC_IW_Q1FL].cnt = 4951 + hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt / hmc_fpm_misc->q1_block_size; 4952 + 4953 + pages_needed = irdma_get_objs_pages(dev, hmc_info, IRDMA_LOC_MEM); 4954 + if (pages_needed <= max_pages) 4955 + break; 4956 + 4957 + ird /= 2; 4958 + ord /= 2; 4959 + } while (ird >= IRDMA_MIN_IRD); 4960 + 4961 + if (ird < IRDMA_MIN_IRD) { 4962 + ibdev_dbg(to_ibdev(dev), "HMC: FAIL: IRD=%u Q1 CNT = %u\n", 4963 + ird, hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt); 4964 + return -EINVAL; 4965 + } 4966 + 4967 + dev->hw_attrs.max_hw_ird = ird; 4968 + dev->hw_attrs.max_hw_ord = ord; 4969 + hmc_fpm_misc->max_sds -= pages_needed; 4970 + 4971 + return 0; 4972 + } 4973 + 4974 + /** 4975 + * cfg_fpm_value_gen_3 - configure fpm for gen 3 4976 + * @dev: sc device struct 4977 + * @hmc_info: ptr to irdma_hmc_obj_info struct 4978 + * @hmc_fpm_misc: ptr to fpm data 4979 + */ 4980 + static int cfg_fpm_value_gen_3(struct irdma_sc_dev *dev, 4981 + struct irdma_hmc_info *hmc_info, 4982 + struct irdma_hmc_fpm_misc *hmc_fpm_misc) 4983 + { 4984 + enum irdma_hmc_obj_mem mrte_loc; 4985 + u32 mrwanted, qpwanted; 4986 + int i, ret_code = 0; 4987 + u32 loc_mem_pages; 4988 + bool is_mrte_loc_mem; 4989 + 4990 + loc_mem_pages = hmc_fpm_misc->loc_mem_pages; 4991 + is_mrte_loc_mem = hmc_fpm_misc->loc_mem_pages == hmc_fpm_misc->max_sds ? 4992 + true : false; 4993 + 4994 + irdma_get_rsrc_mem_config(dev, is_mrte_loc_mem); 4995 + mrte_loc = hmc_info->hmc_obj[IRDMA_HMC_IW_MR].mem_loc; 4996 + 4997 + if (is_mrte_loc_mem) 4998 + loc_mem_pages -= IRDMA_MIN_PBLE_PAGES; 4999 + 5000 + ibdev_dbg(to_ibdev(dev), 5001 + "HMC: mrte_loc %d loc_mem %u fpm max sds %u host_obj %d\n", 5002 + hmc_info->hmc_obj[IRDMA_HMC_IW_MR].mem_loc, 5003 + hmc_fpm_misc->loc_mem_pages, hmc_fpm_misc->max_sds, 5004 + is_mrte_loc_mem); 5005 + 5006 + mrwanted = hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt; 5007 + qpwanted = hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt; 5008 + hmc_info->hmc_obj[IRDMA_HMC_IW_HDR].cnt = qpwanted; 5009 + 5010 + hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].max_cnt = 0; 5011 + hmc_info->hmc_obj[IRDMA_HMC_IW_OOISCFFL].max_cnt = 0; 5012 + hmc_info->hmc_obj[IRDMA_HMC_IW_HTE].max_cnt = 0; 5013 + hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].max_cnt = 0; 5014 + hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt = 5015 + min(hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt, 5016 + (u32)IRDMA_FSIAV_CNT_MAX); 5017 + for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) 5018 + hmc_info->hmc_obj[i].cnt = hmc_info->hmc_obj[i].max_cnt; 5019 + 5020 + while (qpwanted >= IRDMA_MIN_QP_CNT) { 5021 + if (!irdma_set_loc_hmc_rsrc_gen_3(dev, loc_mem_pages, qpwanted)) 5022 + break; 5023 + 5024 + qpwanted /= 2; 5025 + if (mrte_loc == IRDMA_LOC_MEM) { 5026 + mrwanted = qpwanted * IRDMA_MIN_MR_PER_QP; 5027 + hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt = 5028 + min(hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt, mrwanted); 5029 + } 5030 + } 5031 + 5032 + if (qpwanted < IRDMA_MIN_QP_CNT) { 5033 + ibdev_dbg(to_ibdev(dev), 5034 + "HMC: ERROR: could not allocate fpm resources\n"); 5035 + return -EINVAL; 5036 + } 5037 + 5038 + irdma_set_host_hmc_rsrc_gen_3(dev); 5039 + ret_code = irdma_sc_cfg_iw_fpm(dev, dev->hmc_fn_id); 5040 + if (ret_code) { 5041 + ibdev_dbg(to_ibdev(dev), 5042 + "HMC: cfg_iw_fpm returned error_code[x%08X]\n", 5043 + readl(dev->hw_regs[IRDMA_CQPERRCODES])); 5044 + 5045 + return ret_code; 5046 + } 5047 + 5048 + return irdma_cfg_sd_mem(dev, hmc_info); 5049 + } 5050 + 5051 + /** 4853 5052 * irdma_cfg_fpm_val - configure HMC objects 4854 5053 * @dev: sc device struct 4855 5054 * @qp_count: desired qp count 4856 5055 */ 4857 5056 int irdma_cfg_fpm_val(struct irdma_sc_dev *dev, u32 qp_count) 4858 5057 { 4859 - struct irdma_virt_mem virt_mem; 4860 - u32 i, mem_size; 4861 5058 u32 qpwanted, mrwanted, pblewanted; 4862 - u32 powerof2, hte; 5059 + u32 powerof2, hte, i; 4863 5060 u32 sd_needed; 4864 5061 u32 sd_diff; 4865 5062 u32 loop_count = 0; 4866 5063 struct irdma_hmc_info *hmc_info; 4867 5064 struct irdma_hmc_fpm_misc *hmc_fpm_misc; 4868 5065 int ret_code = 0; 5066 + u32 max_sds; 4869 5067 4870 5068 hmc_info = dev->hmc_info; 4871 5069 hmc_fpm_misc = &dev->hmc_fpm_misc; ··· 5140 4814 return ret_code; 5141 4815 } 5142 4816 4817 + max_sds = hmc_fpm_misc->max_sds; 4818 + 4819 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) 4820 + return cfg_fpm_value_gen_3(dev, hmc_info, hmc_fpm_misc); 4821 + 5143 4822 for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) 5144 4823 hmc_info->hmc_obj[i].cnt = hmc_info->hmc_obj[i].max_cnt; 5145 4824 sd_needed = irdma_est_sd(dev, hmc_info); 5146 - ibdev_dbg(to_ibdev(dev), 5147 - "HMC: FW max resources sd_needed[%08d] first_sd_index[%04d]\n", 5148 - sd_needed, hmc_info->first_sd_index); 5149 - ibdev_dbg(to_ibdev(dev), "HMC: sd count %d where max sd is %d\n", 5150 - hmc_info->sd_table.sd_cnt, hmc_fpm_misc->max_sds); 4825 + ibdev_dbg(to_ibdev(dev), "HMC: sd count %u where max sd is %u\n", 4826 + hmc_info->sd_table.sd_cnt, max_sds); 5151 4827 5152 4828 qpwanted = min(qp_count, hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt); 5153 4829 ··· 5163 4835 pblewanted = hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].max_cnt; 5164 4836 5165 4837 ibdev_dbg(to_ibdev(dev), 5166 - "HMC: req_qp=%d max_sd=%d, max_qp = %d, max_cq=%d, max_mr=%d, max_pble=%d, mc=%d, av=%d\n", 5167 - qp_count, hmc_fpm_misc->max_sds, 4838 + "HMC: req_qp=%d max_sd=%u, max_qp = %u, max_cq=%u, max_mr=%u, max_pble=%u, mc=%d, av=%u\n", 4839 + qp_count, max_sds, 5168 4840 hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt, 5169 4841 hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].max_cnt, 5170 4842 hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt, ··· 5177 4849 hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt; 5178 4850 hmc_info->hmc_obj[IRDMA_HMC_IW_ARP].cnt = 5179 4851 hmc_info->hmc_obj[IRDMA_HMC_IW_ARP].max_cnt; 5180 - 5181 4852 hmc_info->hmc_obj[IRDMA_HMC_IW_APBVT_ENTRY].cnt = 1; 5182 4853 5183 4854 while (irdma_q1_cnt(dev, hmc_info, qpwanted) > hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].max_cnt) ··· 5187 4860 hmc_info->hmc_obj[IRDMA_HMC_IW_QP].cnt = qpwanted; 5188 4861 hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt = 5189 4862 min(2 * qpwanted, hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt); 5190 - hmc_info->hmc_obj[IRDMA_HMC_IW_RESERVED].cnt = 0; /* Reserved */ 4863 + hmc_info->hmc_obj[IRDMA_HMC_IW_SRQ].cnt = 0; /* Reserved */ 5191 4864 hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt = mrwanted; 5192 4865 5193 4866 hte = round_up(qpwanted + hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt, 512); ··· 5225 4898 if (!(loop_count % 2) && qpwanted > 128) { 5226 4899 qpwanted /= 2; 5227 4900 } else { 5228 - mrwanted /= 2; 5229 4901 pblewanted /= 2; 4902 + mrwanted /= 2; 5230 4903 } 5231 4904 continue; 5232 4905 } 4906 + 5233 4907 if (dev->cqp->hmc_profile != IRDMA_HMC_PROFILE_FAVOR_VF && 5234 4908 pblewanted > (512 * FPM_MULTIPLIER * sd_diff)) { 5235 4909 pblewanted -= 256 * FPM_MULTIPLIER * sd_diff; ··· 5256 4928 5257 4929 if (sd_needed > hmc_fpm_misc->max_sds) { 5258 4930 ibdev_dbg(to_ibdev(dev), 5259 - "HMC: cfg_fpm failed loop_cnt=%d, sd_needed=%d, max sd count %d\n", 4931 + "HMC: cfg_fpm failed loop_cnt=%u, sd_needed=%u, max sd count %u\n", 5260 4932 loop_count, sd_needed, hmc_info->sd_table.sd_cnt); 5261 4933 return -EINVAL; 5262 4934 } 5263 4935 5264 - if (loop_count > 1 && sd_needed < hmc_fpm_misc->max_sds) { 5265 - pblewanted += (hmc_fpm_misc->max_sds - sd_needed) * 256 * 5266 - FPM_MULTIPLIER; 4936 + if (loop_count > 1 && sd_needed < max_sds) { 4937 + pblewanted += (max_sds - sd_needed) * 256 * FPM_MULTIPLIER; 5267 4938 hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt = pblewanted; 5268 4939 sd_needed = irdma_est_sd(dev, hmc_info); 5269 4940 } ··· 5286 4959 return ret_code; 5287 4960 } 5288 4961 5289 - mem_size = sizeof(struct irdma_hmc_sd_entry) * 5290 - (hmc_info->sd_table.sd_cnt + hmc_info->first_sd_index + 1); 5291 - virt_mem.size = mem_size; 5292 - virt_mem.va = kzalloc(virt_mem.size, GFP_KERNEL); 5293 - if (!virt_mem.va) { 5294 - ibdev_dbg(to_ibdev(dev), 5295 - "HMC: failed to allocate memory for sd_entry buffer\n"); 5296 - return -ENOMEM; 5297 - } 5298 - hmc_info->sd_table.sd_entry = virt_mem.va; 5299 - 5300 - return ret_code; 4962 + return irdma_cfg_sd_mem(dev, hmc_info); 5301 4963 } 5302 4964 5303 4965 /** ··· 5697 5381 dev->fpm_commit_buf = info->fpm_commit_buf; 5698 5382 dev->hw = info->hw; 5699 5383 dev->hw->hw_addr = info->bar0; 5384 + dev->protocol_used = info->protocol_used; 5700 5385 /* Setup the hardware limits, hmc may limit further */ 5701 5386 dev->hw_attrs.min_hw_qp_id = IRDMA_MIN_IW_QP_ID; 5702 5387 dev->hw_attrs.min_hw_aeq_size = IRDMA_MIN_AEQ_ENTRIES; 5703 - dev->hw_attrs.max_hw_aeq_size = IRDMA_MAX_AEQ_ENTRIES; 5388 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) 5389 + dev->hw_attrs.max_hw_aeq_size = IRDMA_MAX_AEQ_ENTRIES_GEN_3; 5390 + else 5391 + dev->hw_attrs.max_hw_aeq_size = IRDMA_MAX_AEQ_ENTRIES; 5704 5392 dev->hw_attrs.min_hw_ceq_size = IRDMA_MIN_CEQ_ENTRIES; 5705 5393 dev->hw_attrs.max_hw_ceq_size = IRDMA_MAX_CEQ_ENTRIES; 5706 5394 dev->hw_attrs.uk_attrs.min_hw_cq_size = IRDMA_MIN_CQ_SIZE; ··· 5729 5409 dev->hw_attrs.max_sleep_count = IRDMA_SLEEP_COUNT; 5730 5410 dev->hw_attrs.max_cqp_compl_wait_time_ms = CQP_COMPL_WAIT_TIME_MS; 5731 5411 5732 - dev->hw_attrs.uk_attrs.hw_rev = ver; 5412 + if (!dev->privileged) { 5413 + ret_code = irdma_vchnl_req_get_hmc_fcn(dev); 5414 + if (ret_code) { 5415 + ibdev_dbg(to_ibdev(dev), 5416 + "DEV: Get HMC function ret = %d\n", 5417 + ret_code); 5418 + 5419 + return ret_code; 5420 + } 5421 + } 5422 + 5733 5423 irdma_sc_init_hw(dev); 5734 5424 5735 5425 if (irdma_wait_pe_ready(dev))
+29 -21
drivers/infiniband/hw/irdma/defs.h
··· 114 114 #define IRDMA_UPDATE_SD_BUFF_SIZE 128 115 115 #define IRDMA_FEATURE_BUF_SIZE (8 * IRDMA_MAX_FEATURES) 116 116 117 + #define ENABLE_LOC_MEM 63 118 + #define MAX_PBLE_PER_SD 0x40000 119 + #define MAX_PBLE_SD_PER_FCN 0x400 120 + #define MAX_MR_PER_SD 0x8000 121 + #define MAX_MR_SD_PER_FCN 0x80 122 + #define IRDMA_PBLE_COMMIT_OFFSET 112 117 123 #define IRDMA_MAX_QUANTA_PER_WR 8 118 124 119 125 #define IRDMA_QP_SW_MAX_WQ_QUANTA 32768 ··· 401 395 #define IRDMA_CQPSQ_STATS_INST_INDEX GENMASK_ULL(6, 0) 402 396 #define IRDMA_CQPSQ_STATS_HMC_FCN_INDEX GENMASK_ULL(5, 0) 403 397 #define IRDMA_CQPSQ_WS_WQEVALID BIT_ULL(63) 404 - #define IRDMA_CQPSQ_WS_NODEOP GENMASK_ULL(53, 52) 398 + #define IRDMA_CQPSQ_WS_NODEOP GENMASK_ULL(55, 52) 399 + #define IRDMA_SD_MAX GENMASK_ULL(15, 0) 400 + #define IRDMA_MEM_MAX GENMASK_ULL(15, 0) 401 + #define IRDMA_QP_MEM_LOC GENMASK_ULL(47, 44) 402 + #define IRDMA_MR_MEM_LOC GENMASK_ULL(27, 24) 405 403 406 404 #define IRDMA_CQPSQ_WS_ENABLENODE BIT_ULL(62) 407 405 #define IRDMA_CQPSQ_WS_NODETYPE BIT_ULL(61) ··· 414 404 #define IRDMA_CQPSQ_WS_VMVFTYPE GENMASK_ULL(55, 54) 415 405 #define IRDMA_CQPSQ_WS_VMVFNUM GENMASK_ULL(51, 42) 416 406 #define IRDMA_CQPSQ_WS_OP GENMASK_ULL(37, 32) 417 - #define IRDMA_CQPSQ_WS_PARENTID GENMASK_ULL(25, 16) 418 - #define IRDMA_CQPSQ_WS_NODEID GENMASK_ULL(9, 0) 419 - #define IRDMA_CQPSQ_WS_VSI GENMASK_ULL(57, 48) 407 + #define IRDMA_CQPSQ_WS_PARENTID GENMASK_ULL(29, 16) 408 + #define IRDMA_CQPSQ_WS_NODEID GENMASK_ULL(13, 0) 409 + #define IRDMA_CQPSQ_WS_VSI GENMASK_ULL(63, 48) 420 410 #define IRDMA_CQPSQ_WS_WEIGHT GENMASK_ULL(38, 32) 421 411 422 412 #define IRDMA_CQPSQ_UP_WQEVALID BIT_ULL(63) 423 413 #define IRDMA_CQPSQ_UP_USEVLAN BIT_ULL(62) 424 414 #define IRDMA_CQPSQ_UP_USEOVERRIDE BIT_ULL(61) 425 415 #define IRDMA_CQPSQ_UP_OP GENMASK_ULL(37, 32) 426 - #define IRDMA_CQPSQ_UP_HMCFCNIDX GENMASK_ULL(5, 0) 416 + #define IRDMA_CQPSQ_UP_HMCFCNIDX GENMASK_ULL(15, 0) 427 417 #define IRDMA_CQPSQ_UP_CNPOVERRIDE GENMASK_ULL(37, 32) 428 418 #define IRDMA_CQPSQ_QUERY_RDMA_FEATURES_WQEVALID BIT_ULL(63) 429 419 #define IRDMA_CQPSQ_QUERY_RDMA_FEATURES_BUF_LEN GENMASK_ULL(31, 0) ··· 486 476 #define IRDMA_CQ_UDSMAC GENMASK_ULL(47, 0) 487 477 #define IRDMA_CQ_UDVLAN GENMASK_ULL(63, 48) 488 478 489 - #define IRDMA_CQ_IMMDATA_S 0 490 - #define IRDMA_CQ_IMMDATA_M (0xffffffffffffffffULL << IRDMA_CQ_IMMVALID_S) 491 479 #define IRDMA_CQ_IMMDATALOW32 GENMASK_ULL(31, 0) 492 480 #define IRDMA_CQ_IMMDATAUP32 GENMASK_ULL(63, 32) 493 481 #define IRDMACQ_PAYLDLEN GENMASK_ULL(31, 0) ··· 598 590 #define IRDMA_CQPSQ_STAG_MR BIT_ULL(43) 599 591 #define IRDMA_CQPSQ_STAG_MWTYPE BIT_ULL(42) 600 592 #define IRDMA_CQPSQ_STAG_MW1_BIND_DONT_VLDT_KEY BIT_ULL(58) 593 + #define IRDMA_CQPSQ_STAG_PDID_HI GENMASK_ULL(59, 54) 601 594 602 595 #define IRDMA_CQPSQ_STAG_LPBLSIZE IRDMA_CQPSQ_CQ_LPBLSIZE 603 596 #define IRDMA_CQPSQ_STAG_HPAGESIZE GENMASK_ULL(47, 46) ··· 637 628 /* Manage Push Page - MPP */ 638 629 #define IRDMA_INVALID_PUSH_PAGE_INDEX_GEN_1 0xffff 639 630 #define IRDMA_INVALID_PUSH_PAGE_INDEX 0xffffffff 640 - 641 - #define IRDMA_CQPSQ_MPP_QS_HANDLE GENMASK_ULL(9, 0) 642 - #define IRDMA_CQPSQ_MPP_PPIDX GENMASK_ULL(9, 0) 631 + #define IRDMA_CQPSQ_MPP_PPIDX GENMASK_ULL(31, 0) 643 632 #define IRDMA_CQPSQ_MPP_PPTYPE GENMASK_ULL(61, 60) 644 - 645 633 #define IRDMA_CQPSQ_MPP_FREE_PAGE BIT_ULL(62) 646 634 647 635 /* Upload Context - UCTX */ ··· 666 660 #define IRDMA_CQPSQ_AEQ_VMAP BIT_ULL(47) 667 661 #define IRDMA_CQPSQ_AEQ_FIRSTPMPBLIDX GENMASK_ULL(27, 0) 668 662 669 - #define IRDMA_COMMIT_FPM_QPCNT GENMASK_ULL(18, 0) 670 - 663 + #define IRDMA_COMMIT_FPM_QPCNT GENMASK_ULL(20, 0) 671 664 #define IRDMA_COMMIT_FPM_BASE_S 32 672 - #define IRDMA_CQPSQ_CFPM_HMCFNID GENMASK_ULL(5, 0) 665 + #define IRDMA_CQPSQ_CFPM_HMCFNID GENMASK_ULL(15, 0) 666 + 673 667 #define IRDMA_CQPSQ_FWQE_AECODE GENMASK_ULL(15, 0) 674 668 #define IRDMA_CQPSQ_FWQE_AESOURCE GENMASK_ULL(19, 16) 675 669 #define IRDMA_CQPSQ_FWQE_RQMNERR GENMASK_ULL(15, 0) ··· 793 787 #define IRDMAQPC_MAXSNDWND GENMASK_ULL(31, 0) 794 788 #define IRDMAQPC_REXMIT_THRESH GENMASK_ULL(53, 48) 795 789 #define IRDMAQPC_RNRNAK_THRESH GENMASK_ULL(56, 54) 796 - #define IRDMAQPC_TXCQNUM GENMASK_ULL(18, 0) 797 - #define IRDMAQPC_RXCQNUM GENMASK_ULL(50, 32) 790 + #define IRDMAQPC_TXCQNUM GENMASK_ULL(24, 0) 791 + #define IRDMAQPC_RXCQNUM GENMASK_ULL(56, 32) 798 792 #define IRDMAQPC_STAT_INDEX GENMASK_ULL(6, 0) 799 793 #define IRDMAQPC_Q2ADDR GENMASK_ULL(63, 8) 800 794 #define IRDMAQPC_LASTBYTESENT GENMASK_ULL(7, 0) ··· 862 856 #define IRDMAQPSQ_REMSTAGINV GENMASK_ULL(31, 0) 863 857 #define IRDMAQPSQ_DESTQKEY GENMASK_ULL(31, 0) 864 858 #define IRDMAQPSQ_DESTQPN GENMASK_ULL(55, 32) 865 - #define IRDMAQPSQ_AHID GENMASK_ULL(16, 0) 859 + #define IRDMAQPSQ_AHID GENMASK_ULL(24, 0) 866 860 #define IRDMAQPSQ_INLINEDATAFLAG BIT_ULL(57) 867 861 868 862 #define IRDMA_INLINE_VALID_S 7 ··· 909 903 #define IRDMAPFINT_OICR_PE_PUSH_M BIT(27) 910 904 #define IRDMAPFINT_OICR_PE_CRITERR_M BIT(28) 911 905 912 - #define IRDMA_QUERY_FPM_MAX_QPS GENMASK_ULL(18, 0) 913 - #define IRDMA_QUERY_FPM_MAX_CQS GENMASK_ULL(19, 0) 906 + #define IRDMA_QUERY_FPM_LOC_MEM_PAGES GENMASK_ULL(63, 32) 907 + #define IRDMA_QUERY_FPM_MAX_QPS GENMASK_ULL(31, 0) 908 + #define IRDMA_QUERY_FPM_MAX_CQS GENMASK_ULL(31, 0) 914 909 #define IRDMA_QUERY_FPM_FIRST_PE_SD_INDEX GENMASK_ULL(13, 0) 915 - #define IRDMA_QUERY_FPM_MAX_PE_SDS GENMASK_ULL(45, 32) 910 + #define IRDMA_QUERY_FPM_MAX_PE_SDS GENMASK_ULL(44, 32) 911 + #define IRDMA_QUERY_FPM_MAX_PE_SDS_GEN3 GENMASK_ULL(47, 32) 916 912 #define IRDMA_QUERY_FPM_MAX_CEQS GENMASK_ULL(9, 0) 917 913 #define IRDMA_QUERY_FPM_XFBLOCKSIZE GENMASK_ULL(63, 32) 918 914 #define IRDMA_QUERY_FPM_Q1BLOCKSIZE GENMASK_ULL(63, 32) ··· 1111 1103 IRDMA_CEQ_ALIGNMENT = 0x100, 1112 1104 IRDMA_CQ0_ALIGNMENT = 0x100, 1113 1105 IRDMA_SD_BUF_ALIGNMENT = 0x80, 1114 - IRDMA_FEATURE_BUF_ALIGNMENT = 0x8, 1106 + IRDMA_FEATURE_BUF_ALIGNMENT = 0x10, 1115 1107 }; 1116 1108 1117 1109 enum icrdma_protocol_used {
+15 -3
drivers/infiniband/hw/irdma/hmc.c
··· 5 5 #include "defs.h" 6 6 #include "type.h" 7 7 #include "protos.h" 8 + #include "virtchnl.h" 8 9 9 10 /** 10 11 * irdma_find_sd_index_limit - finds segment descriptor index limit ··· 229 228 bool pd_error = false; 230 229 int ret_code = 0; 231 230 231 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3 && 232 + dev->hmc_info->hmc_obj[info->rsrc_type].mem_loc == IRDMA_LOC_MEM) 233 + return 0; 234 + 232 235 if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) 233 236 return -EINVAL; 234 237 ··· 335 330 u32 i, sd_idx; 336 331 struct irdma_dma_mem *mem; 337 332 338 - if (!reset) 333 + if (dev->privileged && !reset) 339 334 ret_code = irdma_hmc_sd_grp(dev, info->hmc_info, 340 335 info->hmc_info->sd_indexes[0], 341 336 info->del_sd_cnt, false); ··· 380 375 u32 pd_idx, pd_lmt, rel_pd_idx; 381 376 u32 i, j; 382 377 int ret_code = 0; 378 + 379 + if (dev->hmc_info->hmc_obj[info->rsrc_type].mem_loc == IRDMA_LOC_MEM) 380 + return 0; 383 381 384 382 if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) { 385 383 ibdev_dbg(to_ibdev(dev), ··· 597 589 pd_entry->sd_index = sd_idx; 598 590 pd_entry->valid = true; 599 591 pd_table->use_cnt++; 600 - irdma_invalidate_pf_hmc_pd(dev, sd_idx, rel_pd_idx); 592 + 593 + if (hmc_info->hmc_fn_id < dev->hw_attrs.first_hw_vf_fpm_id && 594 + dev->privileged) 595 + irdma_invalidate_pf_hmc_pd(dev, sd_idx, rel_pd_idx); 601 596 } 602 597 pd_entry->bp.use_cnt++; 603 598 ··· 651 640 pd_addr = pd_table->pd_page_addr.va; 652 641 pd_addr += rel_pd_idx; 653 642 memset(pd_addr, 0, sizeof(u64)); 654 - irdma_invalidate_pf_hmc_pd(dev, sd_idx, idx); 643 + if (dev->privileged && dev->hmc_fn_id == hmc_info->hmc_fn_id) 644 + irdma_invalidate_pf_hmc_pd(dev, sd_idx, idx); 655 645 656 646 if (!pd_entry->rsrc_pg) { 657 647 mem = &pd_entry->bp.addr;
+18 -1
drivers/infiniband/hw/irdma/hmc.h
··· 16 16 #define IRDMA_HMC_PD_BP_BUF_ALIGNMENT 4096 17 17 #define IRDMA_FIRST_VF_FPM_ID 8 18 18 #define FPM_MULTIPLIER 1024 19 + #define IRDMA_OBJ_LOC_MEM_BIT 0x4 20 + #define IRDMA_XF_MULTIPLIER 16 21 + #define IRDMA_RRF_MULTIPLIER 8 22 + #define IRDMA_MIN_PBLE_PAGES 3 23 + #define IRDMA_HMC_PAGE_SIZE 2097152 24 + #define IRDMA_MIN_MR_PER_QP 4 25 + #define IRDMA_MIN_QP_CNT 64 26 + #define IRDMA_FSIAV_CNT_MAX 1048576 27 + #define IRDMA_MIN_IRD 8 28 + #define IRDMA_HMC_MIN_RRF 16 19 29 20 30 enum irdma_hmc_rsrc_type { 21 31 IRDMA_HMC_IW_QP = 0, 22 32 IRDMA_HMC_IW_CQ = 1, 23 - IRDMA_HMC_IW_RESERVED = 2, 33 + IRDMA_HMC_IW_SRQ = 2, 24 34 IRDMA_HMC_IW_HTE = 3, 25 35 IRDMA_HMC_IW_ARP = 4, 26 36 IRDMA_HMC_IW_APBVT_ENTRY = 5, ··· 58 48 IRDMA_SD_TYPE_DIRECT = 2, 59 49 }; 60 50 51 + enum irdma_hmc_obj_mem { 52 + IRDMA_HOST_MEM = 0, 53 + IRDMA_LOC_MEM = 1, 54 + }; 55 + 61 56 struct irdma_hmc_obj_info { 62 57 u64 base; 63 58 u32 max_cnt; 64 59 u32 cnt; 65 60 u64 size; 61 + enum irdma_hmc_obj_mem mem_loc; 66 62 }; 67 63 68 64 struct irdma_hmc_bp { ··· 133 117 struct irdma_ccq_cqe_info; 134 118 struct irdma_hmc_fcn_info { 135 119 u32 vf_id; 120 + u8 protocol_used; 136 121 u8 free_fcn; 137 122 }; 138 123
+11 -7
drivers/infiniband/hw/irdma/hw.c
··· 33 33 static enum irdma_hmc_rsrc_type iw_hmc_obj_types[] = { 34 34 IRDMA_HMC_IW_QP, 35 35 IRDMA_HMC_IW_CQ, 36 + IRDMA_HMC_IW_SRQ, 36 37 IRDMA_HMC_IW_HTE, 37 38 IRDMA_HMC_IW_ARP, 38 39 IRDMA_HMC_IW_APBVT_ENTRY, ··· 1570 1569 { 1571 1570 struct irdma_sc_dev *dev = &rf->sc_dev; 1572 1571 1572 + if (!rf->sc_dev.privileged) 1573 + irdma_vchnl_req_put_hmc_fcn(&rf->sc_dev); 1573 1574 kfree(dev->hmc_info->sd_table.sd_entry); 1574 1575 dev->hmc_info->sd_table.sd_entry = NULL; 1575 1576 vfree(rf->mem_rsrc); ··· 1638 1635 1639 1636 info.bar0 = rf->hw.hw_addr; 1640 1637 info.hmc_fn_id = rf->pf_id; 1638 + info.protocol_used = rf->protocol_used; 1641 1639 info.hw = &rf->hw; 1642 1640 status = irdma_sc_dev_init(rf->rdma_ver, &rf->sc_dev, &info); 1643 1641 if (status) ··· 1911 1907 break; 1912 1908 rf->init_state = CQP_CREATED; 1913 1909 1910 + dev->feature_info[IRDMA_FEATURE_FW_INFO] = IRDMA_FW_VER_DEFAULT; 1911 + if (rf->rdma_ver != IRDMA_GEN_1) { 1912 + status = irdma_get_rdma_features(dev); 1913 + if (status) 1914 + break; 1915 + } 1916 + 1914 1917 status = irdma_hmc_setup(rf); 1915 1918 if (status) 1916 1919 break; ··· 1932 1921 if (status) 1933 1922 break; 1934 1923 rf->init_state = CCQ_CREATED; 1935 - 1936 - dev->feature_info[IRDMA_FEATURE_FW_INFO] = IRDMA_FW_VER_DEFAULT; 1937 - if (rf->rdma_ver != IRDMA_GEN_1) { 1938 - status = irdma_get_rdma_features(dev); 1939 - if (status) 1940 - break; 1941 - } 1942 1924 1943 1925 status = irdma_setup_ceq_0(rf); 1944 1926 if (status)
+1
drivers/infiniband/hw/irdma/i40iw_if.c
··· 77 77 rf->rdma_ver = IRDMA_GEN_1; 78 78 rf->sc_dev.hw = &rf->hw; 79 79 rf->sc_dev.hw_attrs.uk_attrs.hw_rev = IRDMA_GEN_1; 80 + rf->sc_dev.privileged = true; 80 81 rf->gen_ops.request_reset = i40iw_request_reset; 81 82 rf->pcidev = cdev_info->pcidev; 82 83 rf->pf_id = cdev_info->fid;
+2
drivers/infiniband/hw/irdma/icrdma_if.c
··· 214 214 rf->pf_id = idc_priv->pf_id; 215 215 rf->rdma_ver = IRDMA_GEN_2; 216 216 rf->sc_dev.hw_attrs.uk_attrs.hw_rev = IRDMA_GEN_2; 217 + rf->sc_dev.is_pf = true; 218 + rf->sc_dev.privileged = true; 217 219 218 220 rf->gen_ops.register_qset = icrdma_lan_register_qset; 219 221 rf->gen_ops.unregister_qset = icrdma_lan_unregister_qset;
+14
drivers/infiniband/hw/irdma/ig3rdma_hw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB */ 2 + /* Copyright (c) 2021 - 2024 Intel Corporation */ 3 + #ifndef IG3RDMA_HW_H 4 + #define IG3RDMA_HW_H 5 + 6 + #define IG3_PF_RDMA_REGION_OFFSET 0xBC00000 7 + #define IG3_PF_RDMA_REGION_LEN 0x401000 8 + #define IG3_VF_RDMA_REGION_OFFSET 0x8C00 9 + #define IG3_VF_RDMA_REGION_LEN 0x8400 10 + 11 + int ig3rdma_vchnl_send_sync(struct irdma_sc_dev *dev, u8 *msg, u16 len, 12 + u8 *recv_msg, u16 *recv_len); 13 + 14 + #endif /* IG3RDMA_HW_H*/
+232
drivers/infiniband/hw/irdma/ig3rdma_if.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 2 + /* Copyright (c) 2023 - 2024 Intel Corporation */ 3 + 4 + #include "main.h" 5 + #include <linux/net/intel/iidc_rdma_idpf.h> 6 + #include "ig3rdma_hw.h" 7 + 8 + static void ig3rdma_idc_core_event_handler(struct iidc_rdma_core_dev_info *cdev_info, 9 + struct iidc_rdma_event *event) 10 + { 11 + struct irdma_pci_f *rf = auxiliary_get_drvdata(cdev_info->adev); 12 + 13 + if (*event->type & BIT(IIDC_RDMA_EVENT_WARN_RESET)) { 14 + rf->reset = true; 15 + rf->sc_dev.vchnl_up = false; 16 + } 17 + } 18 + 19 + int ig3rdma_vchnl_send_sync(struct irdma_sc_dev *dev, u8 *msg, u16 len, 20 + u8 *recv_msg, u16 *recv_len) 21 + { 22 + struct iidc_rdma_core_dev_info *cdev_info = dev_to_rf(dev)->cdev; 23 + int ret; 24 + 25 + ret = idpf_idc_rdma_vc_send_sync(cdev_info, msg, len, recv_msg, 26 + recv_len); 27 + if (ret == -ETIMEDOUT) { 28 + ibdev_err(&(dev_to_rf(dev)->iwdev->ibdev), 29 + "Virtual channel Req <-> Resp completion timeout\n"); 30 + dev->vchnl_up = false; 31 + } 32 + 33 + return ret; 34 + } 35 + 36 + static int ig3rdma_vchnl_init(struct irdma_pci_f *rf, 37 + struct iidc_rdma_core_dev_info *cdev_info, 38 + u8 *rdma_ver) 39 + { 40 + struct iidc_rdma_priv_dev_info *idc_priv = cdev_info->iidc_priv; 41 + struct irdma_vchnl_init_info virt_info; 42 + u8 gen = rf->rdma_ver; 43 + int ret; 44 + 45 + rf->vchnl_wq = alloc_ordered_workqueue("irdma-virtchnl-wq", 0); 46 + if (!rf->vchnl_wq) 47 + return -ENOMEM; 48 + 49 + mutex_init(&rf->sc_dev.vchnl_mutex); 50 + 51 + virt_info.is_pf = !idc_priv->ftype; 52 + virt_info.hw_rev = gen; 53 + virt_info.privileged = gen == IRDMA_GEN_2; 54 + virt_info.vchnl_wq = rf->vchnl_wq; 55 + ret = irdma_sc_vchnl_init(&rf->sc_dev, &virt_info); 56 + if (ret) { 57 + destroy_workqueue(rf->vchnl_wq); 58 + return ret; 59 + } 60 + 61 + *rdma_ver = rf->sc_dev.hw_attrs.uk_attrs.hw_rev; 62 + 63 + return 0; 64 + } 65 + 66 + /** 67 + * ig3rdma_request_reset - Request a reset 68 + * @rf: RDMA PCI function 69 + */ 70 + static void ig3rdma_request_reset(struct irdma_pci_f *rf) 71 + { 72 + ibdev_warn(&rf->iwdev->ibdev, "Requesting a reset\n"); 73 + idpf_idc_request_reset(rf->cdev, IIDC_FUNC_RESET); 74 + } 75 + 76 + static int ig3rdma_cfg_regions(struct irdma_hw *hw, 77 + struct iidc_rdma_core_dev_info *cdev_info) 78 + { 79 + struct iidc_rdma_priv_dev_info *idc_priv = cdev_info->iidc_priv; 80 + struct pci_dev *pdev = cdev_info->pdev; 81 + int i; 82 + 83 + switch (idc_priv->ftype) { 84 + case IIDC_FUNCTION_TYPE_PF: 85 + hw->rdma_reg.len = IG3_PF_RDMA_REGION_LEN; 86 + hw->rdma_reg.offset = IG3_PF_RDMA_REGION_OFFSET; 87 + break; 88 + case IIDC_FUNCTION_TYPE_VF: 89 + hw->rdma_reg.len = IG3_VF_RDMA_REGION_LEN; 90 + hw->rdma_reg.offset = IG3_VF_RDMA_REGION_OFFSET; 91 + break; 92 + default: 93 + return -ENODEV; 94 + } 95 + 96 + hw->rdma_reg.addr = ioremap(pci_resource_start(pdev, 0) + hw->rdma_reg.offset, 97 + hw->rdma_reg.len); 98 + 99 + if (!hw->rdma_reg.addr) 100 + return -ENOMEM; 101 + 102 + hw->num_io_regions = le16_to_cpu(idc_priv->num_memory_regions); 103 + hw->io_regs = kcalloc(hw->num_io_regions, 104 + sizeof(struct irdma_mmio_region), GFP_KERNEL); 105 + 106 + if (!hw->io_regs) { 107 + iounmap(hw->rdma_reg.addr); 108 + return -ENOMEM; 109 + } 110 + 111 + for (i = 0; i < hw->num_io_regions; i++) { 112 + hw->io_regs[i].addr = 113 + idc_priv->mapped_mem_regions[i].region_addr; 114 + hw->io_regs[i].len = 115 + le64_to_cpu(idc_priv->mapped_mem_regions[i].size); 116 + hw->io_regs[i].offset = 117 + le64_to_cpu(idc_priv->mapped_mem_regions[i].start_offset); 118 + } 119 + 120 + return 0; 121 + } 122 + 123 + static void ig3rdma_decfg_rf(struct irdma_pci_f *rf) 124 + { 125 + struct irdma_hw *hw = &rf->hw; 126 + 127 + destroy_workqueue(rf->vchnl_wq); 128 + kfree(hw->io_regs); 129 + iounmap(hw->rdma_reg.addr); 130 + } 131 + 132 + static int ig3rdma_cfg_rf(struct irdma_pci_f *rf, 133 + struct iidc_rdma_core_dev_info *cdev_info) 134 + { 135 + struct iidc_rdma_priv_dev_info *idc_priv = cdev_info->iidc_priv; 136 + int err; 137 + 138 + rf->sc_dev.hw = &rf->hw; 139 + rf->cdev = cdev_info; 140 + rf->pcidev = cdev_info->pdev; 141 + rf->hw.device = &rf->pcidev->dev; 142 + rf->msix_count = idc_priv->msix_count; 143 + rf->msix_entries = idc_priv->msix_entries; 144 + 145 + err = ig3rdma_vchnl_init(rf, cdev_info, &rf->rdma_ver); 146 + if (err) 147 + return err; 148 + 149 + err = ig3rdma_cfg_regions(&rf->hw, cdev_info); 150 + if (err) { 151 + destroy_workqueue(rf->vchnl_wq); 152 + return err; 153 + } 154 + 155 + rf->protocol_used = IRDMA_ROCE_PROTOCOL_ONLY; 156 + rf->rsrc_profile = IRDMA_HMC_PROFILE_DEFAULT; 157 + rf->rst_to = IRDMA_RST_TIMEOUT_HZ; 158 + rf->gen_ops.request_reset = ig3rdma_request_reset; 159 + rf->limits_sel = 7; 160 + mutex_init(&rf->ah_tbl_lock); 161 + 162 + return 0; 163 + } 164 + 165 + static int ig3rdma_core_probe(struct auxiliary_device *aux_dev, 166 + const struct auxiliary_device_id *id) 167 + { 168 + struct iidc_rdma_core_auxiliary_dev *idc_adev = 169 + container_of(aux_dev, struct iidc_rdma_core_auxiliary_dev, adev); 170 + struct iidc_rdma_core_dev_info *cdev_info = idc_adev->cdev_info; 171 + struct irdma_pci_f *rf; 172 + int err; 173 + 174 + rf = kzalloc(sizeof(*rf), GFP_KERNEL); 175 + if (!rf) 176 + return -ENOMEM; 177 + 178 + err = ig3rdma_cfg_rf(rf, cdev_info); 179 + if (err) 180 + goto err_cfg_rf; 181 + 182 + err = irdma_ctrl_init_hw(rf); 183 + if (err) 184 + goto err_ctrl_init; 185 + 186 + auxiliary_set_drvdata(aux_dev, rf); 187 + 188 + err = idpf_idc_vport_dev_ctrl(cdev_info, true); 189 + if (err) 190 + goto err_vport_ctrl; 191 + 192 + return 0; 193 + 194 + err_vport_ctrl: 195 + irdma_ctrl_deinit_hw(rf); 196 + err_ctrl_init: 197 + ig3rdma_decfg_rf(rf); 198 + err_cfg_rf: 199 + kfree(rf); 200 + 201 + return err; 202 + } 203 + 204 + static void ig3rdma_core_remove(struct auxiliary_device *aux_dev) 205 + { 206 + struct iidc_rdma_core_auxiliary_dev *idc_adev = 207 + container_of(aux_dev, struct iidc_rdma_core_auxiliary_dev, adev); 208 + struct iidc_rdma_core_dev_info *cdev_info = idc_adev->cdev_info; 209 + struct irdma_pci_f *rf = auxiliary_get_drvdata(aux_dev); 210 + 211 + idpf_idc_vport_dev_ctrl(cdev_info, false); 212 + irdma_ctrl_deinit_hw(rf); 213 + ig3rdma_decfg_rf(rf); 214 + kfree(rf); 215 + } 216 + 217 + static const struct auxiliary_device_id ig3rdma_core_auxiliary_id_table[] = { 218 + {.name = "idpf.8086.rdma.core", }, 219 + {}, 220 + }; 221 + 222 + MODULE_DEVICE_TABLE(auxiliary, ig3rdma_core_auxiliary_id_table); 223 + 224 + struct iidc_rdma_core_auxiliary_drv ig3rdma_core_auxiliary_drv = { 225 + .adrv = { 226 + .name = "core", 227 + .id_table = ig3rdma_core_auxiliary_id_table, 228 + .probe = ig3rdma_core_probe, 229 + .remove = ig3rdma_core_remove, 230 + }, 231 + .event_handler = ig3rdma_idc_core_event_handler, 232 + };
+4 -1
drivers/infiniband/hw/irdma/irdma.h
··· 92 92 struct irdma_mcast_grp_info { 93 93 u8 dest_mac_addr[ETH_ALEN]; 94 94 u16 vlan_id; 95 - u8 hmc_fcn_id; 95 + u16 hmc_fcn_id; 96 96 bool ipv4_valid:1; 97 97 bool vlan_valid:1; 98 98 u16 mg_id; ··· 107 107 IRDMA_GEN_RSVD, 108 108 IRDMA_GEN_1, 109 109 IRDMA_GEN_2, 110 + IRDMA_GEN_3, 111 + IRDMA_GEN_NEXT, 112 + IRDMA_GEN_MAX = IRDMA_GEN_NEXT-1 110 113 }; 111 114 112 115 struct irdma_uk_attrs {
+10
drivers/infiniband/hw/irdma/main.c
··· 65 65 return ret; 66 66 } 67 67 68 + ret = auxiliary_driver_register(&ig3rdma_core_auxiliary_drv.adrv); 69 + if (ret) { 70 + auxiliary_driver_unregister(&icrdma_core_auxiliary_drv.adrv); 71 + auxiliary_driver_unregister(&i40iw_auxiliary_drv); 72 + pr_err("Failed ig3rdma(gen_3) core auxiliary_driver_register() ret=%d\n", 73 + ret); 74 + 75 + return ret; 76 + } 68 77 irdma_register_notifiers(); 69 78 70 79 return 0; ··· 84 75 irdma_unregister_notifiers(); 85 76 auxiliary_driver_unregister(&icrdma_core_auxiliary_drv.adrv); 86 77 auxiliary_driver_unregister(&i40iw_auxiliary_drv); 78 + auxiliary_driver_unregister(&ig3rdma_core_auxiliary_drv.adrv); 87 79 } 88 80 89 81 module_init(irdma_init_module);
+2
drivers/infiniband/hw/irdma/main.h
··· 54 54 55 55 extern struct auxiliary_driver i40iw_auxiliary_drv; 56 56 extern struct iidc_rdma_core_auxiliary_drv icrdma_core_auxiliary_drv; 57 + extern struct iidc_rdma_core_auxiliary_drv ig3rdma_core_auxiliary_drv; 57 58 58 59 #define IRDMA_FW_VER_DEFAULT 2 59 60 #define IRDMA_HW_VER 2 ··· 328 327 wait_queue_head_t vchnl_waitq; 329 328 struct workqueue_struct *cqp_cmpl_wq; 330 329 struct work_struct cqp_cmpl_work; 330 + struct workqueue_struct *vchnl_wq; 331 331 struct irdma_sc_vsi default_vsi; 332 332 void *back_fcn; 333 333 struct irdma_gen_ops gen_ops;
+14 -6
drivers/infiniband/hw/irdma/pble.c
··· 193 193 { 194 194 enum irdma_sd_entry_type sd_entry_type; 195 195 196 - sd_entry_type = !idx->rel_pd_idx && pages == IRDMA_HMC_PD_CNT_IN_SD ? 197 - IRDMA_SD_TYPE_DIRECT : IRDMA_SD_TYPE_PAGED; 196 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) 197 + sd_entry_type = (!idx->rel_pd_idx && 198 + pages == IRDMA_HMC_PD_CNT_IN_SD) ? 199 + IRDMA_SD_TYPE_DIRECT : IRDMA_SD_TYPE_PAGED; 200 + else 201 + sd_entry_type = (!idx->rel_pd_idx && 202 + pages == IRDMA_HMC_PD_CNT_IN_SD && 203 + dev->privileged) ? 204 + IRDMA_SD_TYPE_DIRECT : IRDMA_SD_TYPE_PAGED; 198 205 return sd_entry_type; 199 206 } 200 207 ··· 286 279 sd_reg_val = (sd_entry_type == IRDMA_SD_TYPE_PAGED) ? 287 280 sd_entry->u.pd_table.pd_page_addr.pa : 288 281 sd_entry->u.bp.addr.pa; 289 - 290 - if (!sd_entry->valid) { 291 - ret_code = irdma_hmc_sd_one(dev, hmc_info->hmc_fn_id, sd_reg_val, 292 - idx->sd_idx, sd_entry->entry_type, true); 282 + if ((dev->privileged && !sd_entry->valid) || 283 + dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) { 284 + ret_code = irdma_hmc_sd_one(dev, hmc_info->hmc_fn_id, 285 + sd_reg_val, idx->sd_idx, 286 + sd_entry->entry_type, true); 293 287 if (ret_code) 294 288 goto error; 295 289 }
+2 -2
drivers/infiniband/hw/irdma/puda.h
··· 91 91 u32 rq_size; 92 92 u32 tx_buf_cnt; /* total bufs allocated will be rq_size + tx_buf_cnt */ 93 93 u16 buf_size; 94 - u8 stats_idx; 94 + u16 stats_idx; 95 95 bool stats_idx_valid:1; 96 96 int abi_ver; 97 97 }; ··· 140 140 u64 crc_err; 141 141 u64 pmode_count; 142 142 u64 partials_handled; 143 - u8 stats_idx; 143 + u16 stats_idx; 144 144 bool check_crc:1; 145 145 bool stats_idx_valid:1; 146 146 };
+60 -7
drivers/infiniband/hw/irdma/type.h
··· 8 8 #include "hmc.h" 9 9 #include "uda.h" 10 10 #include "ws.h" 11 + #include "virtchnl.h" 12 + 11 13 #define IRDMA_DEBUG_ERR "ERR" 12 14 #define IRDMA_DEBUG_INIT "INIT" 13 15 #define IRDMA_DEBUG_DEV "DEV" ··· 161 159 enum irdma_feature_type { 162 160 IRDMA_FEATURE_FW_INFO = 0, 163 161 IRDMA_HW_VERSION_INFO = 1, 162 + IRDMA_QP_MAX_INCR = 2, 163 + IRDMA_CQ_MAX_INCR = 3, 164 + IRDMA_CEQ_MAX_INCR = 4, 165 + IRDMA_SD_MAX_INCR = 5, 166 + IRDMA_QP_SMALL = 6, 167 + IRDMA_QP_MEDIUM = 7, 168 + IRDMA_QP_LARGE = 8, 169 + IRDMA_QP_XLARGE = 9, 170 + IRDMA_CQ_SMALL = 10, 171 + IRDMA_CQ_MEDIUM = 11, 172 + IRDMA_CQ_LARGE = 12, 173 + IRDMA_CQ_XLARGE = 13, 174 + IRDMA_CEQ_SMALL = 14, 175 + IRDMA_CEQ_MEDIUM = 15, 176 + IRDMA_CEQ_LARGE = 16, 177 + IRDMA_CEQ_XLARGE = 17, 178 + IRDMA_SD_SMALL = 18, 179 + IRDMA_SD_MEDIUM = 19, 180 + IRDMA_SD_LARGE = 20, 181 + IRDMA_SD_XLARGE = 21, 182 + IRDMA_OBJ_1 = 22, 183 + IRDMA_OBJ_2 = 23, 184 + IRDMA_ENDPT_TRK = 24, 185 + IRDMA_FTN_INLINE_MAX = 25, 164 186 IRDMA_QSETS_MAX = 26, 187 + IRDMA_ASO = 27, 188 + IRDMA_FTN_FLAGS = 32, 189 + IRDMA_FTN_NOP = 33, 165 190 IRDMA_MAX_FEATURES, /* Must be last entry */ 166 191 }; 167 192 ··· 339 310 spinlock_t lock; /* rdma stats lock */ 340 311 }; 341 312 313 + struct irdma_mmio_region { 314 + u8 __iomem *addr; 315 + resource_size_t len; 316 + resource_size_t offset; 317 + }; 318 + 342 319 struct irdma_hw { 343 - u8 __iomem *hw_addr; 344 - u8 __iomem *priv_hw_addr; 320 + union { 321 + u8 __iomem *hw_addr; 322 + struct { 323 + struct irdma_mmio_region rdma_reg; /* RDMA region */ 324 + struct irdma_mmio_region *io_regs; /* Non-RDMA MMIO regions */ 325 + u16 num_io_regions; /* Number of Non-RDMA MMIO regions */ 326 + }; 327 + }; 345 328 struct device *device; 346 329 struct irdma_hmc_info hmc; 347 330 }; ··· 536 495 struct irdma_up_info { 537 496 u8 map[8]; 538 497 u8 cnp_up_override; 539 - u8 hmc_fcn_idx; 498 + u16 hmc_fcn_idx; 540 499 bool use_vlan:1; 541 500 bool use_cnp_up_override:1; 542 501 }; ··· 559 518 struct irdma_hmc_fpm_misc { 560 519 u32 max_ceqs; 561 520 u32 max_sds; 521 + u32 loc_mem_pages; 562 522 u32 xf_block_size; 563 523 u32 q1_block_size; 564 524 u32 ht_multiplier; ··· 568 526 u32 ooiscf_block_size; 569 527 }; 570 528 529 + #define IRDMA_VCHNL_MAX_MSG_SIZE 512 571 530 #define IRDMA_LEAF_DEFAULT_REL_BW 64 572 531 #define IRDMA_PARENT_DEFAULT_REL_BW 1 573 532 ··· 644 601 u64 cqp_cmd_stats[IRDMA_MAX_CQP_OPS]; 645 602 struct irdma_hw_attrs hw_attrs; 646 603 struct irdma_hmc_info *hmc_info; 604 + struct irdma_vchnl_rdma_caps vc_caps; 605 + u8 vc_recv_buf[IRDMA_VCHNL_MAX_MSG_SIZE]; 606 + u16 vc_recv_len; 647 607 struct irdma_sc_cqp *cqp; 648 608 struct irdma_sc_aeq *aeq; 649 609 struct irdma_sc_ceq *ceq[IRDMA_CEQ_MAX_COUNT]; 650 610 struct irdma_sc_cq *ccq; 651 611 const struct irdma_irq_ops *irq_ops; 612 + struct irdma_qos qos[IRDMA_MAX_USER_PRIORITY]; 652 613 struct irdma_hmc_fpm_misc hmc_fpm_misc; 653 614 struct irdma_ws_node *ws_tree_root; 654 615 struct mutex ws_mutex; /* ws tree mutex */ 616 + u32 vchnl_ver; 655 617 u16 num_vfs; 656 - u8 hmc_fn_id; 618 + u16 hmc_fn_id; 657 619 u8 vf_id; 620 + bool privileged:1; 658 621 bool vchnl_up:1; 659 622 bool ceq_valid:1; 623 + bool is_pf:1; 624 + u8 protocol_used; 625 + struct mutex vchnl_mutex; /* mutex to synchronize RDMA virtual channel messages */ 660 626 u8 pci_rev; 661 627 int (*ws_add)(struct irdma_sc_vsi *vsi, u8 user_pri); 662 628 void (*ws_remove)(struct irdma_sc_vsi *vsi, u8 user_pri); ··· 772 720 773 721 struct irdma_vsi_stats_info { 774 722 struct irdma_vsi_pestat *pestat; 775 - u8 fcn_id; 723 + u16 fcn_id; 776 724 bool alloc_stats_inst; 777 725 }; 778 726 ··· 783 731 __le64 *fpm_commit_buf; 784 732 struct irdma_hw *hw; 785 733 void __iomem *bar0; 786 - u8 hmc_fn_id; 734 + enum irdma_protocol_used protocol_used; 735 + u16 hmc_fn_id; 787 736 }; 788 737 789 738 struct irdma_ceq_init_info { ··· 1025 972 bool use_hmc_fcn_index:1; 1026 973 bool use_pf_rid:1; 1027 974 bool all_memory:1; 1028 - u8 hmc_fcn_index; 975 + u16 hmc_fcn_index; 1029 976 }; 1030 977 1031 978 struct irdma_mw_alloc_info {
+3 -2
drivers/infiniband/hw/irdma/user.h
··· 55 55 IRDMA_CEQE_SIZE = 1, 56 56 IRDMA_CQP_CTX_SIZE = 8, 57 57 IRDMA_SHADOW_AREA_SIZE = 8, 58 - IRDMA_QUERY_FPM_BUF_SIZE = 176, 59 - IRDMA_COMMIT_FPM_BUF_SIZE = 176, 58 + IRDMA_QUERY_FPM_BUF_SIZE = 192, 59 + IRDMA_COMMIT_FPM_BUF_SIZE = 192, 60 60 IRDMA_GATHER_STATS_BUF_SIZE = 1024, 61 61 IRDMA_MIN_IW_QP_ID = 0, 62 62 IRDMA_MAX_IW_QP_ID = 262143, ··· 67 67 IRDMA_MAX_CQID = 524287, 68 68 IRDMA_MIN_AEQ_ENTRIES = 1, 69 69 IRDMA_MAX_AEQ_ENTRIES = 524287, 70 + IRDMA_MAX_AEQ_ENTRIES_GEN_3 = 262144, 70 71 IRDMA_MIN_CEQ_ENTRIES = 1, 71 72 IRDMA_MAX_CEQ_ENTRIES = 262143, 72 73 IRDMA_MIN_CQ_SIZE = 1,
+304
drivers/infiniband/hw/irdma/virtchnl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 2 + /* Copyright (c) 2015 - 2024 Intel Corporation */ 3 + 4 + #include "osdep.h" 5 + #include "hmc.h" 6 + #include "defs.h" 7 + #include "type.h" 8 + #include "protos.h" 9 + #include "virtchnl.h" 10 + #include "ws.h" 11 + #include "i40iw_hw.h" 12 + #include "ig3rdma_hw.h" 13 + 14 + /** 15 + * irdma_sc_vchnl_init - Initialize dev virtchannel and get hw_rev 16 + * @dev: dev structure to update 17 + * @info: virtchannel info parameters to fill into the dev structure 18 + */ 19 + int irdma_sc_vchnl_init(struct irdma_sc_dev *dev, 20 + struct irdma_vchnl_init_info *info) 21 + { 22 + dev->vchnl_up = true; 23 + dev->privileged = info->privileged; 24 + dev->is_pf = info->is_pf; 25 + dev->hw_attrs.uk_attrs.hw_rev = info->hw_rev; 26 + 27 + if (!dev->privileged) { 28 + int ret = irdma_vchnl_req_get_ver(dev, IRDMA_VCHNL_CHNL_VER_MAX, 29 + &dev->vchnl_ver); 30 + 31 + ibdev_dbg(to_ibdev(dev), 32 + "DEV: Get Channel version ret = %d, version is %u\n", 33 + ret, dev->vchnl_ver); 34 + 35 + if (ret) 36 + return ret; 37 + 38 + ret = irdma_vchnl_req_get_caps(dev); 39 + if (ret) 40 + return ret; 41 + 42 + dev->hw_attrs.uk_attrs.hw_rev = dev->vc_caps.hw_rev; 43 + } 44 + 45 + return 0; 46 + } 47 + 48 + /** 49 + * irdma_vchnl_req_verify_resp - Verify requested response size 50 + * @vchnl_req: vchnl message requested 51 + * @resp_len: response length sent from vchnl peer 52 + */ 53 + static int irdma_vchnl_req_verify_resp(struct irdma_vchnl_req *vchnl_req, 54 + u16 resp_len) 55 + { 56 + switch (vchnl_req->vchnl_msg->op_code) { 57 + case IRDMA_VCHNL_OP_GET_VER: 58 + case IRDMA_VCHNL_OP_GET_HMC_FCN: 59 + case IRDMA_VCHNL_OP_PUT_HMC_FCN: 60 + if (resp_len != vchnl_req->parm_len) 61 + return -EBADMSG; 62 + break; 63 + case IRDMA_VCHNL_OP_GET_RDMA_CAPS: 64 + if (resp_len < IRDMA_VCHNL_OP_GET_RDMA_CAPS_MIN_SIZE) 65 + return -EBADMSG; 66 + break; 67 + default: 68 + return -EOPNOTSUPP; 69 + } 70 + 71 + return 0; 72 + } 73 + 74 + static void irdma_free_vchnl_req_msg(struct irdma_vchnl_req *vchnl_req) 75 + { 76 + kfree(vchnl_req->vchnl_msg); 77 + } 78 + 79 + static int irdma_alloc_vchnl_req_msg(struct irdma_vchnl_req *vchnl_req, 80 + struct irdma_vchnl_req_init_info *info) 81 + { 82 + struct irdma_vchnl_op_buf *vchnl_msg; 83 + 84 + vchnl_msg = kzalloc(IRDMA_VCHNL_MAX_MSG_SIZE, GFP_KERNEL); 85 + 86 + if (!vchnl_msg) 87 + return -ENOMEM; 88 + 89 + vchnl_msg->op_ctx = (uintptr_t)vchnl_req; 90 + vchnl_msg->buf_len = sizeof(*vchnl_msg) + info->req_parm_len; 91 + if (info->req_parm_len) 92 + memcpy(vchnl_msg->buf, info->req_parm, info->req_parm_len); 93 + vchnl_msg->op_code = info->op_code; 94 + vchnl_msg->op_ver = info->op_ver; 95 + 96 + vchnl_req->vchnl_msg = vchnl_msg; 97 + vchnl_req->parm = info->resp_parm; 98 + vchnl_req->parm_len = info->resp_parm_len; 99 + 100 + return 0; 101 + } 102 + 103 + static int irdma_vchnl_req_send_sync(struct irdma_sc_dev *dev, 104 + struct irdma_vchnl_req_init_info *info) 105 + { 106 + u16 resp_len = sizeof(dev->vc_recv_buf); 107 + struct irdma_vchnl_req vchnl_req = {}; 108 + u16 msg_len; 109 + u8 *msg; 110 + int ret; 111 + 112 + ret = irdma_alloc_vchnl_req_msg(&vchnl_req, info); 113 + if (ret) 114 + return ret; 115 + 116 + msg_len = vchnl_req.vchnl_msg->buf_len; 117 + msg = (u8 *)vchnl_req.vchnl_msg; 118 + 119 + mutex_lock(&dev->vchnl_mutex); 120 + ret = ig3rdma_vchnl_send_sync(dev, msg, msg_len, dev->vc_recv_buf, 121 + &resp_len); 122 + dev->vc_recv_len = resp_len; 123 + if (ret) 124 + goto exit; 125 + 126 + ret = irdma_vchnl_req_get_resp(dev, &vchnl_req); 127 + exit: 128 + mutex_unlock(&dev->vchnl_mutex); 129 + ibdev_dbg(to_ibdev(dev), 130 + "VIRT: virtual channel send %s caller: %pS ret=%d op=%u op_ver=%u req_len=%u parm_len=%u resp_len=%u\n", 131 + !ret ? "SUCCEEDS" : "FAILS", __builtin_return_address(0), 132 + ret, vchnl_req.vchnl_msg->op_code, 133 + vchnl_req.vchnl_msg->op_ver, vchnl_req.vchnl_msg->buf_len, 134 + vchnl_req.parm_len, vchnl_req.resp_len); 135 + irdma_free_vchnl_req_msg(&vchnl_req); 136 + 137 + return ret; 138 + } 139 + 140 + /** 141 + * irdma_vchnl_req_get_ver - Request Channel version 142 + * @dev: RDMA device pointer 143 + * @ver_req: Virtual channel version requested 144 + * @ver_res: Virtual channel version response 145 + */ 146 + int irdma_vchnl_req_get_ver(struct irdma_sc_dev *dev, u16 ver_req, u32 *ver_res) 147 + { 148 + struct irdma_vchnl_req_init_info info = {}; 149 + int ret; 150 + 151 + if (!dev->vchnl_up) 152 + return -EBUSY; 153 + 154 + info.op_code = IRDMA_VCHNL_OP_GET_VER; 155 + info.op_ver = ver_req; 156 + info.resp_parm = ver_res; 157 + info.resp_parm_len = sizeof(*ver_res); 158 + 159 + ret = irdma_vchnl_req_send_sync(dev, &info); 160 + if (ret) 161 + return ret; 162 + 163 + if (*ver_res < IRDMA_VCHNL_CHNL_VER_MIN) { 164 + ibdev_dbg(to_ibdev(dev), 165 + "VIRT: %s unsupported vchnl version 0x%0x\n", 166 + __func__, *ver_res); 167 + return -EOPNOTSUPP; 168 + } 169 + 170 + return 0; 171 + } 172 + 173 + /** 174 + * irdma_vchnl_req_get_hmc_fcn - Request VF HMC Function 175 + * @dev: RDMA device pointer 176 + */ 177 + int irdma_vchnl_req_get_hmc_fcn(struct irdma_sc_dev *dev) 178 + { 179 + struct irdma_vchnl_req_hmc_info req_hmc = {}; 180 + struct irdma_vchnl_resp_hmc_info resp_hmc = {}; 181 + struct irdma_vchnl_req_init_info info = {}; 182 + int ret; 183 + 184 + if (!dev->vchnl_up) 185 + return -EBUSY; 186 + 187 + info.op_code = IRDMA_VCHNL_OP_GET_HMC_FCN; 188 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) { 189 + info.op_ver = IRDMA_VCHNL_OP_GET_HMC_FCN_V2; 190 + req_hmc.protocol_used = dev->protocol_used; 191 + info.req_parm_len = sizeof(req_hmc); 192 + info.req_parm = &req_hmc; 193 + info.resp_parm = &resp_hmc; 194 + info.resp_parm_len = sizeof(resp_hmc); 195 + } 196 + 197 + ret = irdma_vchnl_req_send_sync(dev, &info); 198 + 199 + if (ret) 200 + return ret; 201 + 202 + if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) { 203 + int i; 204 + 205 + dev->hmc_fn_id = resp_hmc.hmc_func; 206 + 207 + for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) { 208 + dev->qos[i].qs_handle = resp_hmc.qs_handle[i]; 209 + dev->qos[i].valid = true; 210 + } 211 + } 212 + return 0; 213 + } 214 + 215 + /** 216 + * irdma_vchnl_req_put_hmc_fcn - Free VF HMC Function 217 + * @dev: RDMA device pointer 218 + */ 219 + int irdma_vchnl_req_put_hmc_fcn(struct irdma_sc_dev *dev) 220 + { 221 + struct irdma_vchnl_req_init_info info = {}; 222 + 223 + if (!dev->vchnl_up) 224 + return -EBUSY; 225 + 226 + info.op_code = IRDMA_VCHNL_OP_PUT_HMC_FCN; 227 + info.op_ver = IRDMA_VCHNL_OP_PUT_HMC_FCN_V0; 228 + 229 + return irdma_vchnl_req_send_sync(dev, &info); 230 + } 231 + 232 + /** 233 + * irdma_vchnl_req_get_caps - Request RDMA capabilities 234 + * @dev: RDMA device pointer 235 + */ 236 + int irdma_vchnl_req_get_caps(struct irdma_sc_dev *dev) 237 + { 238 + struct irdma_vchnl_req_init_info info = {}; 239 + int ret; 240 + 241 + if (!dev->vchnl_up) 242 + return -EBUSY; 243 + 244 + info.op_code = IRDMA_VCHNL_OP_GET_RDMA_CAPS; 245 + info.op_ver = IRDMA_VCHNL_OP_GET_RDMA_CAPS_V0; 246 + info.resp_parm = &dev->vc_caps; 247 + info.resp_parm_len = sizeof(dev->vc_caps); 248 + 249 + ret = irdma_vchnl_req_send_sync(dev, &info); 250 + 251 + if (ret) 252 + return ret; 253 + 254 + if (dev->vc_caps.hw_rev > IRDMA_GEN_MAX || 255 + dev->vc_caps.hw_rev < IRDMA_GEN_2) { 256 + ibdev_dbg(to_ibdev(dev), 257 + "ERR: %s unsupported hw_rev version 0x%0x\n", 258 + __func__, dev->vc_caps.hw_rev); 259 + return -EOPNOTSUPP; 260 + } 261 + 262 + return 0; 263 + } 264 + 265 + /** 266 + * irdma_vchnl_req_get_resp - Receive the inbound vchnl response. 267 + * @dev: Dev pointer 268 + * @vchnl_req: Vchannel request 269 + */ 270 + int irdma_vchnl_req_get_resp(struct irdma_sc_dev *dev, 271 + struct irdma_vchnl_req *vchnl_req) 272 + { 273 + struct irdma_vchnl_resp_buf *vchnl_msg_resp = 274 + (struct irdma_vchnl_resp_buf *)dev->vc_recv_buf; 275 + u16 resp_len; 276 + int ret; 277 + 278 + if ((uintptr_t)vchnl_req != (uintptr_t)vchnl_msg_resp->op_ctx) { 279 + ibdev_dbg(to_ibdev(dev), 280 + "VIRT: error vchnl context value does not match\n"); 281 + return -EBADMSG; 282 + } 283 + 284 + resp_len = dev->vc_recv_len - sizeof(*vchnl_msg_resp); 285 + resp_len = min(resp_len, vchnl_req->parm_len); 286 + 287 + ret = irdma_vchnl_req_verify_resp(vchnl_req, resp_len); 288 + if (ret) 289 + return ret; 290 + 291 + ret = (int)vchnl_msg_resp->op_ret; 292 + if (ret) 293 + return ret; 294 + 295 + vchnl_req->resp_len = 0; 296 + if (vchnl_req->parm_len && vchnl_req->parm && resp_len) { 297 + memcpy(vchnl_req->parm, vchnl_msg_resp->buf, resp_len); 298 + vchnl_req->resp_len = resp_len; 299 + ibdev_dbg(to_ibdev(dev), "VIRT: Got response, data size %u\n", 300 + resp_len); 301 + } 302 + 303 + return 0; 304 + }
+94
drivers/infiniband/hw/irdma/virtchnl.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB */ 2 + /* Copyright (c) 2015 - 2024 Intel Corporation */ 3 + #ifndef IRDMA_VIRTCHNL_H 4 + #define IRDMA_VIRTCHNL_H 5 + 6 + #include "hmc.h" 7 + #include "irdma.h" 8 + 9 + /* IRDMA_VCHNL_CHNL_VER_V0 is for legacy hw, no longer supported. */ 10 + #define IRDMA_VCHNL_CHNL_VER_V2 2 11 + #define IRDMA_VCHNL_CHNL_VER_MIN IRDMA_VCHNL_CHNL_VER_V2 12 + #define IRDMA_VCHNL_CHNL_VER_MAX IRDMA_VCHNL_CHNL_VER_V2 13 + #define IRDMA_VCHNL_OP_GET_HMC_FCN_V0 0 14 + #define IRDMA_VCHNL_OP_GET_HMC_FCN_V1 1 15 + #define IRDMA_VCHNL_OP_GET_HMC_FCN_V2 2 16 + #define IRDMA_VCHNL_OP_PUT_HMC_FCN_V0 0 17 + #define IRDMA_VCHNL_OP_GET_RDMA_CAPS_V0 0 18 + #define IRDMA_VCHNL_OP_GET_RDMA_CAPS_MIN_SIZE 1 19 + 20 + enum irdma_vchnl_ops { 21 + IRDMA_VCHNL_OP_GET_VER = 0, 22 + IRDMA_VCHNL_OP_GET_HMC_FCN = 1, 23 + IRDMA_VCHNL_OP_PUT_HMC_FCN = 2, 24 + IRDMA_VCHNL_OP_GET_RDMA_CAPS = 13, 25 + }; 26 + 27 + struct irdma_vchnl_req_hmc_info { 28 + u8 protocol_used; 29 + u8 disable_qos; 30 + } __packed; 31 + 32 + struct irdma_vchnl_resp_hmc_info { 33 + u16 hmc_func; 34 + u16 qs_handle[IRDMA_MAX_USER_PRIORITY]; 35 + } __packed; 36 + 37 + struct irdma_vchnl_op_buf { 38 + u16 op_code; 39 + u16 op_ver; 40 + u16 buf_len; 41 + u16 rsvd; 42 + u64 op_ctx; 43 + u8 buf[]; 44 + } __packed; 45 + 46 + struct irdma_vchnl_resp_buf { 47 + u64 op_ctx; 48 + u16 buf_len; 49 + s16 op_ret; 50 + u16 rsvd[2]; 51 + u8 buf[]; 52 + } __packed; 53 + 54 + struct irdma_vchnl_rdma_caps { 55 + u8 hw_rev; 56 + u16 cqp_timeout_s; 57 + u16 cqp_def_timeout_s; 58 + u16 max_hw_push_len; 59 + } __packed; 60 + 61 + struct irdma_vchnl_init_info { 62 + struct workqueue_struct *vchnl_wq; 63 + enum irdma_vers hw_rev; 64 + bool privileged; 65 + bool is_pf; 66 + }; 67 + 68 + struct irdma_vchnl_req { 69 + struct irdma_vchnl_op_buf *vchnl_msg; 70 + void *parm; 71 + u32 vf_id; 72 + u16 parm_len; 73 + u16 resp_len; 74 + }; 75 + 76 + struct irdma_vchnl_req_init_info { 77 + void *req_parm; 78 + void *resp_parm; 79 + u16 req_parm_len; 80 + u16 resp_parm_len; 81 + u16 op_code; 82 + u16 op_ver; 83 + } __packed; 84 + 85 + int irdma_sc_vchnl_init(struct irdma_sc_dev *dev, 86 + struct irdma_vchnl_init_info *info); 87 + int irdma_vchnl_req_get_ver(struct irdma_sc_dev *dev, u16 ver_req, 88 + u32 *ver_res); 89 + int irdma_vchnl_req_get_hmc_fcn(struct irdma_sc_dev *dev); 90 + int irdma_vchnl_req_put_hmc_fcn(struct irdma_sc_dev *dev); 91 + int irdma_vchnl_req_get_caps(struct irdma_sc_dev *dev); 92 + int irdma_vchnl_req_get_resp(struct irdma_sc_dev *dev, 93 + struct irdma_vchnl_req *vc_req); 94 + #endif /* IRDMA_VIRTCHNL_H */