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: Discover and set up GEN3 hardware register layout

Discover the hardware register layout for GEN3 devices through an RDMA
virtual channel operation with the Control Plane (CP). Set up the
corresponding hardware attributes specific to GEN3 devices.

Signed-off-by: Christopher Bednarz <christopher.n.bednarz@intel.com>
Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
Link: https://patch.msgid.link/20250827152545.2056-4-tatyana.e.nikolova@intel.com
Tested-by: Jacob Moroni <jmoroni@google.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Christopher Bednarz and committed by
Leon Romanovsky
7d5a7cc7 d5edd333

+351 -15
+1
drivers/infiniband/hw/irdma/Makefile
··· 16 16 ig3rdma_if.o\ 17 17 icrdma_if.o \ 18 18 icrdma_hw.o \ 19 + ig3rdma_hw.o\ 19 20 main.o \ 20 21 pble.o \ 21 22 puda.o \
+21 -10
drivers/infiniband/hw/irdma/ctrl.c
··· 5672 5672 case IRDMA_GEN_2: 5673 5673 icrdma_init_hw(dev); 5674 5674 break; 5675 + case IRDMA_GEN_3: 5676 + ig3rdma_init_hw(dev); 5677 + break; 5675 5678 } 5676 5679 } 5677 5680 ··· 5745 5742 5746 5743 irdma_sc_init_hw(dev); 5747 5744 5748 - if (irdma_wait_pe_ready(dev)) 5749 - return -ETIMEDOUT; 5745 + if (dev->privileged) { 5746 + if (irdma_wait_pe_ready(dev)) 5747 + return -ETIMEDOUT; 5750 5748 5751 - val = readl(dev->hw_regs[IRDMA_GLPCI_LBARCTRL]); 5752 - db_size = (u8)FIELD_GET(IRDMA_GLPCI_LBARCTRL_PE_DB_SIZE, val); 5753 - if (db_size != IRDMA_PE_DB_SIZE_4M && db_size != IRDMA_PE_DB_SIZE_8M) { 5754 - ibdev_dbg(to_ibdev(dev), 5755 - "DEV: RDMA PE doorbell is not enabled in CSR val 0x%x db_size=%d\n", 5756 - val, db_size); 5757 - return -ENODEV; 5749 + val = readl(dev->hw_regs[IRDMA_GLPCI_LBARCTRL]); 5750 + db_size = (u8)FIELD_GET(IRDMA_GLPCI_LBARCTRL_PE_DB_SIZE, val); 5751 + if (db_size != IRDMA_PE_DB_SIZE_4M && 5752 + db_size != IRDMA_PE_DB_SIZE_8M) { 5753 + ibdev_dbg(to_ibdev(dev), 5754 + "DEV: RDMA PE doorbell is not enabled in CSR val 0x%x db_size=%d\n", 5755 + val, db_size); 5756 + return -ENODEV; 5757 + } 5758 + } else { 5759 + ret_code = irdma_vchnl_req_get_reg_layout(dev); 5760 + if (ret_code) 5761 + ibdev_dbg(to_ibdev(dev), 5762 + "DEV: Get Register layout failed ret = %d\n", 5763 + ret_code); 5758 5764 } 5759 - dev->db_addr = dev->hw->hw_addr + (uintptr_t)dev->hw_regs[IRDMA_DB_ADDR_OFFSET]; 5760 5765 5761 5766 return ret_code; 5762 5767 }
+9 -3
drivers/infiniband/hw/irdma/defs.h
··· 115 115 #define IRDMA_FEATURE_BUF_SIZE (8 * IRDMA_MAX_FEATURES) 116 116 117 117 #define ENABLE_LOC_MEM 63 118 + #define IRDMA_ATOMICS_ALLOWED_BIT 1 118 119 #define MAX_PBLE_PER_SD 0x40000 119 120 #define MAX_PBLE_SD_PER_FCN 0x400 120 121 #define MAX_MR_PER_SD 0x8000 ··· 128 127 #define IRDMA_QP_SW_MAX_RQ_QUANTA 32768 129 128 #define IRDMA_MAX_QP_WRS(max_quanta_per_wr) \ 130 129 ((IRDMA_QP_SW_MAX_WQ_QUANTA - IRDMA_SQ_RSVD) / (max_quanta_per_wr)) 131 - 130 + #define IRDMA_SRQ_MAX_QUANTA 262144 132 131 #define IRDMAQP_TERM_SEND_TERM_AND_FIN 0 133 132 #define IRDMAQP_TERM_SEND_TERM_ONLY 1 134 133 #define IRDMAQP_TERM_SEND_FIN_ONLY 2 ··· 154 153 #define IRDMA_SQ_RSVD 258 155 154 #define IRDMA_RQ_RSVD 1 156 155 157 - #define IRDMA_FEATURE_RTS_AE 1ULL 158 - #define IRDMA_FEATURE_CQ_RESIZE 2ULL 156 + #define IRDMA_FEATURE_RTS_AE BIT_ULL(0) 157 + #define IRDMA_FEATURE_CQ_RESIZE BIT_ULL(1) 158 + #define IRDMA_FEATURE_64_BYTE_CQE BIT_ULL(5) 159 + #define IRDMA_FEATURE_ATOMIC_OPS BIT_ULL(6) 160 + #define IRDMA_FEATURE_SRQ BIT_ULL(7) 161 + #define IRDMA_FEATURE_CQE_TIMESTAMPING BIT_ULL(8) 162 + 159 163 #define IRDMAQP_OP_RDMA_WRITE 0x00 160 164 #define IRDMAQP_OP_RDMA_READ 0x01 161 165 #define IRDMAQP_OP_RDMA_SEND 0x03
+2
drivers/infiniband/hw/irdma/i40iw_hw.c
··· 85 85 I40E_CQPSQ_CQ_CEQID, 86 86 I40E_CQPSQ_CQ_CQID, 87 87 I40E_COMMIT_FPM_CQCNT, 88 + I40E_CQPSQ_UPESD_HMCFNID, 88 89 }; 89 90 90 91 static u64 i40iw_shifts[IRDMA_MAX_SHIFTS] = { ··· 95 94 I40E_CQPSQ_CQ_CEQID_S, 96 95 I40E_CQPSQ_CQ_CQID_S, 97 96 I40E_COMMIT_FPM_CQCNT_S, 97 + I40E_CQPSQ_UPESD_HMCFNID_S, 98 98 }; 99 99 100 100 /**
+2
drivers/infiniband/hw/irdma/i40iw_hw.h
··· 123 123 #define I40E_CQPSQ_CQ_CQID GENMASK_ULL(15, 0) 124 124 #define I40E_COMMIT_FPM_CQCNT_S 0 125 125 #define I40E_COMMIT_FPM_CQCNT GENMASK_ULL(17, 0) 126 + #define I40E_CQPSQ_UPESD_HMCFNID_S 0 127 + #define I40E_CQPSQ_UPESD_HMCFNID GENMASK_ULL(5, 0) 126 128 127 129 #define I40E_VSIQF_CTL(_VSI) (0x0020D800 + ((_VSI) * 4)) 128 130
+3
drivers/infiniband/hw/irdma/icrdma_hw.c
··· 38 38 ICRDMA_CQPSQ_CQ_CEQID, 39 39 ICRDMA_CQPSQ_CQ_CQID, 40 40 ICRDMA_COMMIT_FPM_CQCNT, 41 + ICRDMA_CQPSQ_UPESD_HMCFNID, 41 42 }; 42 43 43 44 static u64 icrdma_shifts[IRDMA_MAX_SHIFTS] = { ··· 48 47 ICRDMA_CQPSQ_CQ_CEQID_S, 49 48 ICRDMA_CQPSQ_CQ_CQID_S, 50 49 ICRDMA_COMMIT_FPM_CQCNT_S, 50 + ICRDMA_CQPSQ_UPESD_HMCFNID_S, 51 51 }; 52 52 53 53 /** ··· 196 194 dev->hw_attrs.max_hw_ord = ICRDMA_MAX_ORD_SIZE; 197 195 dev->hw_attrs.max_stat_inst = ICRDMA_MAX_STATS_COUNT; 198 196 dev->hw_attrs.max_stat_idx = IRDMA_HW_STAT_INDEX_MAX_GEN_2; 197 + dev->hw_attrs.max_hw_device_pages = ICRDMA_MAX_PUSH_PAGE_COUNT; 199 198 200 199 dev->hw_attrs.uk_attrs.min_hw_wq_size = ICRDMA_MIN_WQ_SIZE; 201 200 dev->hw_attrs.uk_attrs.max_hw_sq_chunk = IRDMA_MAX_QUANTA_PER_WR;
+3 -2
drivers/infiniband/hw/irdma/icrdma_hw.h
··· 58 58 #define ICRDMA_CQPSQ_CQ_CQID GENMASK_ULL(18, 0) 59 59 #define ICRDMA_COMMIT_FPM_CQCNT_S 0 60 60 #define ICRDMA_COMMIT_FPM_CQCNT GENMASK_ULL(19, 0) 61 - 61 + #define ICRDMA_CQPSQ_UPESD_HMCFNID_S 0 62 + #define ICRDMA_CQPSQ_UPESD_HMCFNID GENMASK_ULL(5, 0) 62 63 enum icrdma_device_caps_const { 63 64 ICRDMA_MAX_STATS_COUNT = 128, 64 65 65 66 ICRDMA_MAX_IRD_SIZE = 127, 66 67 ICRDMA_MAX_ORD_SIZE = 255, 67 68 ICRDMA_MIN_WQ_SIZE = 8 /* WQEs */, 68 - 69 + ICRDMA_MAX_PUSH_PAGE_COUNT = 256, 69 70 }; 70 71 71 72 void icrdma_init_hw(struct irdma_sc_dev *dev);
+65
drivers/infiniband/hw/irdma/ig3rdma_hw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 2 + /* Copyright (c) 2018 - 2024 Intel Corporation */ 3 + #include "osdep.h" 4 + #include "type.h" 5 + #include "protos.h" 6 + #include "ig3rdma_hw.h" 7 + 8 + void ig3rdma_init_hw(struct irdma_sc_dev *dev) 9 + { 10 + dev->hw_attrs.uk_attrs.hw_rev = IRDMA_GEN_3; 11 + dev->hw_attrs.uk_attrs.max_hw_wq_frags = IG3RDMA_MAX_WQ_FRAGMENT_COUNT; 12 + dev->hw_attrs.uk_attrs.max_hw_read_sges = IG3RDMA_MAX_SGE_RD; 13 + dev->hw_attrs.uk_attrs.max_hw_sq_chunk = IRDMA_MAX_QUANTA_PER_WR; 14 + dev->hw_attrs.first_hw_vf_fpm_id = 0; 15 + dev->hw_attrs.max_hw_vf_fpm_id = IG3_MAX_APFS + IG3_MAX_AVFS; 16 + dev->hw_attrs.uk_attrs.feature_flags |= IRDMA_FEATURE_64_BYTE_CQE; 17 + if (dev->feature_info[IRDMA_FTN_FLAGS] & IRDMA_ATOMICS_ALLOWED_BIT) 18 + dev->hw_attrs.uk_attrs.feature_flags |= 19 + IRDMA_FEATURE_ATOMIC_OPS; 20 + dev->hw_attrs.uk_attrs.feature_flags |= IRDMA_FEATURE_CQE_TIMESTAMPING; 21 + 22 + dev->hw_attrs.uk_attrs.feature_flags |= IRDMA_FEATURE_SRQ; 23 + dev->hw_attrs.uk_attrs.feature_flags |= IRDMA_FEATURE_RTS_AE | 24 + IRDMA_FEATURE_CQ_RESIZE; 25 + dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M | SZ_1G; 26 + dev->hw_attrs.max_hw_ird = IG3RDMA_MAX_IRD_SIZE; 27 + dev->hw_attrs.max_hw_ord = IG3RDMA_MAX_ORD_SIZE; 28 + dev->hw_attrs.uk_attrs.min_hw_wq_size = IG3RDMA_MIN_WQ_SIZE; 29 + dev->hw_attrs.uk_attrs.max_hw_srq_quanta = IRDMA_SRQ_MAX_QUANTA; 30 + dev->hw_attrs.uk_attrs.max_hw_inline = IG3RDMA_MAX_INLINE_DATA_SIZE; 31 + dev->hw_attrs.max_hw_device_pages = 32 + dev->is_pf ? IG3RDMA_MAX_PF_PUSH_PAGE_COUNT : IG3RDMA_MAX_VF_PUSH_PAGE_COUNT; 33 + } 34 + 35 + static void __iomem *__ig3rdma_get_reg_addr(struct irdma_mmio_region *region, u64 reg_offset) 36 + { 37 + if (reg_offset >= region->offset && 38 + reg_offset < (region->offset + region->len)) { 39 + reg_offset -= region->offset; 40 + 41 + return region->addr + reg_offset; 42 + } 43 + 44 + return NULL; 45 + } 46 + 47 + void __iomem *ig3rdma_get_reg_addr(struct irdma_hw *hw, u64 reg_offset) 48 + { 49 + u8 __iomem *reg_addr; 50 + int i; 51 + 52 + reg_addr = __ig3rdma_get_reg_addr(&hw->rdma_reg, reg_offset); 53 + if (reg_addr) 54 + return reg_addr; 55 + 56 + for (i = 0; i < hw->num_io_regions; i++) { 57 + reg_addr = __ig3rdma_get_reg_addr(&hw->io_regs[i], reg_offset); 58 + if (reg_addr) 59 + return reg_addr; 60 + } 61 + 62 + WARN_ON_ONCE(1); 63 + 64 + return NULL; 65 + }
+18
drivers/infiniband/hw/irdma/ig3rdma_hw.h
··· 3 3 #ifndef IG3RDMA_HW_H 4 4 #define IG3RDMA_HW_H 5 5 6 + #define IG3_MAX_APFS 1 7 + #define IG3_MAX_AVFS 0 8 + 6 9 #define IG3_PF_RDMA_REGION_OFFSET 0xBC00000 7 10 #define IG3_PF_RDMA_REGION_LEN 0x401000 8 11 #define IG3_VF_RDMA_REGION_OFFSET 0x8C00 9 12 #define IG3_VF_RDMA_REGION_LEN 0x8400 10 13 14 + enum ig3rdma_device_caps_const { 15 + IG3RDMA_MAX_WQ_FRAGMENT_COUNT = 14, 16 + IG3RDMA_MAX_SGE_RD = 14, 17 + 18 + IG3RDMA_MAX_STATS_COUNT = 128, 19 + 20 + IG3RDMA_MAX_IRD_SIZE = 64, 21 + IG3RDMA_MAX_ORD_SIZE = 64, 22 + IG3RDMA_MIN_WQ_SIZE = 16 /* WQEs */, 23 + IG3RDMA_MAX_INLINE_DATA_SIZE = 216, 24 + IG3RDMA_MAX_PF_PUSH_PAGE_COUNT = 8192, 25 + IG3RDMA_MAX_VF_PUSH_PAGE_COUNT = 16, 26 + }; 27 + 28 + void __iomem *ig3rdma_get_reg_addr(struct irdma_hw *hw, u64 reg_offset); 11 29 int ig3rdma_vchnl_send_sync(struct irdma_sc_dev *dev, u8 *msg, u16 len, 12 30 u8 *recv_msg, u16 *recv_len); 13 31
+5
drivers/infiniband/hw/irdma/irdma.h
··· 67 67 IRDMA_CQPSQ_CQ_CEQID_S, 68 68 IRDMA_CQPSQ_CQ_CQID_S, 69 69 IRDMA_COMMIT_FPM_CQCNT_S, 70 + IRDMA_CQPSQ_UPESD_HMCFNID_S, 70 71 IRDMA_MAX_SHIFTS, 71 72 }; 72 73 ··· 78 77 IRDMA_CQPSQ_CQ_CEQID_M, 79 78 IRDMA_CQPSQ_CQ_CQID_M, 80 79 IRDMA_COMMIT_FPM_CQCNT_M, 80 + IRDMA_CQPSQ_UPESD_HMCFNID_M, 81 81 IRDMA_MAX_MASKS, /* Must be last entry */ 82 82 }; 83 83 ··· 123 121 u32 max_hw_wq_quanta; 124 122 u32 min_hw_cq_size; 125 123 u32 max_hw_cq_size; 124 + u32 max_hw_srq_quanta; 126 125 u16 max_hw_sq_chunk; 127 126 u16 min_hw_wq_size; 128 127 u8 hw_rev; ··· 159 156 160 157 void i40iw_init_hw(struct irdma_sc_dev *dev); 161 158 void icrdma_init_hw(struct irdma_sc_dev *dev); 159 + void ig3rdma_init_hw(struct irdma_sc_dev *dev); 160 + void __iomem *ig3rdma_get_reg_addr(struct irdma_hw *hw, u64 reg_offset); 162 161 #endif /* IRDMA_H*/
+178
drivers/infiniband/hw/irdma/virtchnl.c
··· 11 11 #include "i40iw_hw.h" 12 12 #include "ig3rdma_hw.h" 13 13 14 + struct vchnl_reg_map_elem { 15 + u16 reg_id; 16 + u16 reg_idx; 17 + bool pg_rel; 18 + }; 19 + 20 + struct vchnl_regfld_map_elem { 21 + u16 regfld_id; 22 + u16 regfld_idx; 23 + }; 24 + 25 + static struct vchnl_reg_map_elem vchnl_reg_map[] = { 26 + {IRDMA_VCHNL_REG_ID_CQPTAIL, IRDMA_CQPTAIL, false}, 27 + {IRDMA_VCHNL_REG_ID_CQPDB, IRDMA_CQPDB, false}, 28 + {IRDMA_VCHNL_REG_ID_CCQPSTATUS, IRDMA_CCQPSTATUS, false}, 29 + {IRDMA_VCHNL_REG_ID_CCQPHIGH, IRDMA_CCQPHIGH, false}, 30 + {IRDMA_VCHNL_REG_ID_CCQPLOW, IRDMA_CCQPLOW, false}, 31 + {IRDMA_VCHNL_REG_ID_CQARM, IRDMA_CQARM, false}, 32 + {IRDMA_VCHNL_REG_ID_CQACK, IRDMA_CQACK, false}, 33 + {IRDMA_VCHNL_REG_ID_AEQALLOC, IRDMA_AEQALLOC, false}, 34 + {IRDMA_VCHNL_REG_ID_CQPERRCODES, IRDMA_CQPERRCODES, false}, 35 + {IRDMA_VCHNL_REG_ID_WQEALLOC, IRDMA_WQEALLOC, false}, 36 + {IRDMA_VCHNL_REG_ID_DB_ADDR_OFFSET, IRDMA_DB_ADDR_OFFSET, false }, 37 + {IRDMA_VCHNL_REG_ID_DYN_CTL, IRDMA_GLINT_DYN_CTL, false }, 38 + {IRDMA_VCHNL_REG_INV_ID, IRDMA_VCHNL_REG_INV_ID, false } 39 + }; 40 + 41 + static struct vchnl_regfld_map_elem vchnl_regfld_map[] = { 42 + {IRDMA_VCHNL_REGFLD_ID_CCQPSTATUS_CQP_OP_ERR, IRDMA_CCQPSTATUS_CCQP_ERR_M}, 43 + {IRDMA_VCHNL_REGFLD_ID_CCQPSTATUS_CCQP_DONE, IRDMA_CCQPSTATUS_CCQP_DONE_M}, 44 + {IRDMA_VCHNL_REGFLD_ID_CQPSQ_STAG_PDID, IRDMA_CQPSQ_STAG_PDID_M}, 45 + {IRDMA_VCHNL_REGFLD_ID_CQPSQ_CQ_CEQID, IRDMA_CQPSQ_CQ_CEQID_M}, 46 + {IRDMA_VCHNL_REGFLD_ID_CQPSQ_CQ_CQID, IRDMA_CQPSQ_CQ_CQID_M}, 47 + {IRDMA_VCHNL_REGFLD_ID_COMMIT_FPM_CQCNT, IRDMA_COMMIT_FPM_CQCNT_M}, 48 + {IRDMA_VCHNL_REGFLD_ID_UPESD_HMCN_ID, IRDMA_CQPSQ_UPESD_HMCFNID_M}, 49 + {IRDMA_VCHNL_REGFLD_INV_ID, IRDMA_VCHNL_REGFLD_INV_ID} 50 + }; 51 + 52 + #define IRDMA_VCHNL_REG_COUNT ARRAY_SIZE(vchnl_reg_map) 53 + #define IRDMA_VCHNL_REGFLD_COUNT ARRAY_SIZE(vchnl_regfld_map) 54 + #define IRDMA_VCHNL_REGFLD_BUF_SIZE \ 55 + (IRDMA_VCHNL_REG_COUNT * sizeof(struct irdma_vchnl_reg_info) + \ 56 + IRDMA_VCHNL_REGFLD_COUNT * sizeof(struct irdma_vchnl_reg_field_info)) 57 + #define IRDMA_REGMAP_RESP_BUF_SIZE (IRDMA_VCHNL_RESP_MIN_SIZE + IRDMA_VCHNL_REGFLD_BUF_SIZE) 58 + 14 59 /** 15 60 * irdma_sc_vchnl_init - Initialize dev virtchannel and get hw_rev 16 61 * @dev: dev structure to update ··· 108 63 case IRDMA_VCHNL_OP_GET_RDMA_CAPS: 109 64 if (resp_len < IRDMA_VCHNL_OP_GET_RDMA_CAPS_MIN_SIZE) 110 65 return -EBADMSG; 66 + break; 67 + case IRDMA_VCHNL_OP_GET_REG_LAYOUT: 111 68 break; 112 69 default: 113 70 return -EOPNOTSUPP; ··· 182 135 irdma_free_vchnl_req_msg(&vchnl_req); 183 136 184 137 return ret; 138 + } 139 + 140 + /** 141 + * irdma_vchnl_req_get_reg_layout - Get Register Layout 142 + * @dev: RDMA device pointer 143 + */ 144 + int irdma_vchnl_req_get_reg_layout(struct irdma_sc_dev *dev) 145 + { 146 + u16 reg_idx, reg_id, tmp_reg_id, regfld_idx, regfld_id, tmp_regfld_id; 147 + struct irdma_vchnl_reg_field_info *regfld_array = NULL; 148 + u8 resp_buffer[IRDMA_REGMAP_RESP_BUF_SIZE] = {}; 149 + struct vchnl_regfld_map_elem *regfld_map_array; 150 + struct irdma_vchnl_req_init_info info = {}; 151 + struct vchnl_reg_map_elem *reg_map_array; 152 + struct irdma_vchnl_reg_info *reg_array; 153 + u8 num_bits, shift_cnt; 154 + u16 buf_len = 0; 155 + u64 bitmask; 156 + u32 rindex; 157 + int ret; 158 + 159 + if (!dev->vchnl_up) 160 + return -EBUSY; 161 + 162 + info.op_code = IRDMA_VCHNL_OP_GET_REG_LAYOUT; 163 + info.op_ver = IRDMA_VCHNL_OP_GET_REG_LAYOUT_V0; 164 + info.resp_parm = resp_buffer; 165 + info.resp_parm_len = sizeof(resp_buffer); 166 + 167 + ret = irdma_vchnl_req_send_sync(dev, &info); 168 + 169 + if (ret) 170 + return ret; 171 + 172 + /* parse the response buffer and update reg info*/ 173 + /* Parse registers till invalid */ 174 + /* Parse register fields till invalid */ 175 + reg_array = (struct irdma_vchnl_reg_info *)resp_buffer; 176 + for (rindex = 0; rindex < IRDMA_VCHNL_REG_COUNT; rindex++) { 177 + buf_len += sizeof(struct irdma_vchnl_reg_info); 178 + if (buf_len >= sizeof(resp_buffer)) 179 + return -ENOMEM; 180 + 181 + regfld_array = 182 + (struct irdma_vchnl_reg_field_info *)&reg_array[rindex + 1]; 183 + reg_id = reg_array[rindex].reg_id; 184 + if (reg_id == IRDMA_VCHNL_REG_INV_ID) 185 + break; 186 + 187 + reg_id &= ~IRDMA_VCHNL_REG_PAGE_REL; 188 + if (reg_id >= IRDMA_VCHNL_REG_COUNT) 189 + return -EINVAL; 190 + 191 + /* search regmap for register index in hw_regs.*/ 192 + reg_map_array = vchnl_reg_map; 193 + do { 194 + tmp_reg_id = reg_map_array->reg_id; 195 + if (tmp_reg_id == reg_id) 196 + break; 197 + 198 + reg_map_array++; 199 + } while (tmp_reg_id != IRDMA_VCHNL_REG_INV_ID); 200 + if (tmp_reg_id != reg_id) 201 + continue; 202 + 203 + reg_idx = reg_map_array->reg_idx; 204 + 205 + /* Page relative, DB Offset do not need bar offset */ 206 + if (reg_idx == IRDMA_DB_ADDR_OFFSET || 207 + (reg_array[rindex].reg_id & IRDMA_VCHNL_REG_PAGE_REL)) { 208 + dev->hw_regs[reg_idx] = 209 + (u32 __iomem *)(uintptr_t)reg_array[rindex].reg_offset; 210 + continue; 211 + } 212 + 213 + /* Update the local HW struct */ 214 + dev->hw_regs[reg_idx] = ig3rdma_get_reg_addr(dev->hw, 215 + reg_array[rindex].reg_offset); 216 + if (!dev->hw_regs[reg_idx]) 217 + return -EINVAL; 218 + } 219 + 220 + if (!regfld_array) 221 + return -ENOMEM; 222 + 223 + /* set up doorbell variables using mapped DB page */ 224 + dev->wqe_alloc_db = dev->hw_regs[IRDMA_WQEALLOC]; 225 + dev->cq_arm_db = dev->hw_regs[IRDMA_CQARM]; 226 + dev->aeq_alloc_db = dev->hw_regs[IRDMA_AEQALLOC]; 227 + dev->cqp_db = dev->hw_regs[IRDMA_CQPDB]; 228 + dev->cq_ack_db = dev->hw_regs[IRDMA_CQACK]; 229 + 230 + for (rindex = 0; rindex < IRDMA_VCHNL_REGFLD_COUNT; rindex++) { 231 + buf_len += sizeof(struct irdma_vchnl_reg_field_info); 232 + if ((buf_len - 1) > sizeof(resp_buffer)) 233 + break; 234 + 235 + if (regfld_array[rindex].fld_id == IRDMA_VCHNL_REGFLD_INV_ID) 236 + break; 237 + 238 + regfld_id = regfld_array[rindex].fld_id; 239 + regfld_map_array = vchnl_regfld_map; 240 + do { 241 + tmp_regfld_id = regfld_map_array->regfld_id; 242 + if (tmp_regfld_id == regfld_id) 243 + break; 244 + 245 + regfld_map_array++; 246 + } while (tmp_regfld_id != IRDMA_VCHNL_REGFLD_INV_ID); 247 + 248 + if (tmp_regfld_id != regfld_id) 249 + continue; 250 + 251 + regfld_idx = regfld_map_array->regfld_idx; 252 + 253 + num_bits = regfld_array[rindex].fld_bits; 254 + shift_cnt = regfld_array[rindex].fld_shift; 255 + if ((num_bits + shift_cnt > 64) || !num_bits) { 256 + ibdev_dbg(to_ibdev(dev), 257 + "ERR: Invalid field mask id %d bits %d shift %d", 258 + regfld_id, num_bits, shift_cnt); 259 + 260 + continue; 261 + } 262 + 263 + bitmask = (1ULL << num_bits) - 1; 264 + dev->hw_masks[regfld_idx] = bitmask << shift_cnt; 265 + dev->hw_shifts[regfld_idx] = shift_cnt; 266 + } 267 + 268 + return 0; 185 269 } 186 270 187 271 /**
+44
drivers/infiniband/hw/irdma/virtchnl.h
··· 14 14 #define IRDMA_VCHNL_OP_GET_HMC_FCN_V1 1 15 15 #define IRDMA_VCHNL_OP_GET_HMC_FCN_V2 2 16 16 #define IRDMA_VCHNL_OP_PUT_HMC_FCN_V0 0 17 + #define IRDMA_VCHNL_OP_GET_REG_LAYOUT_V0 0 17 18 #define IRDMA_VCHNL_OP_GET_RDMA_CAPS_V0 0 18 19 #define IRDMA_VCHNL_OP_GET_RDMA_CAPS_MIN_SIZE 1 20 + 21 + #define IRDMA_VCHNL_REG_ID_CQPTAIL 0 22 + #define IRDMA_VCHNL_REG_ID_CQPDB 1 23 + #define IRDMA_VCHNL_REG_ID_CCQPSTATUS 2 24 + #define IRDMA_VCHNL_REG_ID_CCQPHIGH 3 25 + #define IRDMA_VCHNL_REG_ID_CCQPLOW 4 26 + #define IRDMA_VCHNL_REG_ID_CQARM 5 27 + #define IRDMA_VCHNL_REG_ID_CQACK 6 28 + #define IRDMA_VCHNL_REG_ID_AEQALLOC 7 29 + #define IRDMA_VCHNL_REG_ID_CQPERRCODES 8 30 + #define IRDMA_VCHNL_REG_ID_WQEALLOC 9 31 + #define IRDMA_VCHNL_REG_ID_IPCONFIG0 10 32 + #define IRDMA_VCHNL_REG_ID_DB_ADDR_OFFSET 11 33 + #define IRDMA_VCHNL_REG_ID_DYN_CTL 12 34 + #define IRDMA_VCHNL_REG_ID_AEQITRMASK 13 35 + #define IRDMA_VCHNL_REG_ID_CEQITRMASK 14 36 + #define IRDMA_VCHNL_REG_INV_ID 0xFFFF 37 + #define IRDMA_VCHNL_REG_PAGE_REL 0x8000 38 + 39 + #define IRDMA_VCHNL_REGFLD_ID_CCQPSTATUS_CQP_OP_ERR 2 40 + #define IRDMA_VCHNL_REGFLD_ID_CCQPSTATUS_CCQP_DONE 5 41 + #define IRDMA_VCHNL_REGFLD_ID_CQPSQ_STAG_PDID 6 42 + #define IRDMA_VCHNL_REGFLD_ID_CQPSQ_CQ_CEQID 7 43 + #define IRDMA_VCHNL_REGFLD_ID_CQPSQ_CQ_CQID 8 44 + #define IRDMA_VCHNL_REGFLD_ID_COMMIT_FPM_CQCNT 9 45 + #define IRDMA_VCHNL_REGFLD_ID_UPESD_HMCN_ID 10 46 + #define IRDMA_VCHNL_REGFLD_INV_ID 0xFFFF 47 + 48 + #define IRDMA_VCHNL_RESP_MIN_SIZE (sizeof(struct irdma_vchnl_resp_buf)) 19 49 20 50 enum irdma_vchnl_ops { 21 51 IRDMA_VCHNL_OP_GET_VER = 0, 22 52 IRDMA_VCHNL_OP_GET_HMC_FCN = 1, 23 53 IRDMA_VCHNL_OP_PUT_HMC_FCN = 2, 54 + IRDMA_VCHNL_OP_GET_REG_LAYOUT = 11, 24 55 IRDMA_VCHNL_OP_GET_RDMA_CAPS = 13, 25 56 }; 26 57 ··· 96 65 bool is_pf; 97 66 }; 98 67 68 + struct irdma_vchnl_reg_info { 69 + u32 reg_offset; 70 + u16 field_cnt; 71 + u16 reg_id; /* High bit of reg_id: bar or page relative */ 72 + }; 73 + 74 + struct irdma_vchnl_reg_field_info { 75 + u8 fld_shift; 76 + u8 fld_bits; 77 + u16 fld_id; 78 + }; 79 + 99 80 struct irdma_vchnl_req { 100 81 struct irdma_vchnl_op_buf *vchnl_msg; 101 82 void *parm; ··· 134 91 int irdma_vchnl_req_get_caps(struct irdma_sc_dev *dev); 135 92 int irdma_vchnl_req_get_resp(struct irdma_sc_dev *dev, 136 93 struct irdma_vchnl_req *vc_req); 94 + int irdma_vchnl_req_get_reg_layout(struct irdma_sc_dev *dev); 137 95 #endif /* IRDMA_VIRTCHNL_H */