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

RDMA/ionic: Register device ops for miscellaneous functionality

Implement idbdev ops for device and port information.

Co-developed-by: Andrew Boyer <andrew.boyer@amd.com>
Signed-off-by: Andrew Boyer <andrew.boyer@amd.com>
Co-developed-by: Allen Hubbe <allen.hubbe@amd.com>
Signed-off-by: Allen Hubbe <allen.hubbe@amd.com>
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
Link: https://patch.msgid.link/20250903061606.4139957-13-abhijit.gangurde@amd.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Abhijit Gangurde and committed by
Leon Romanovsky
2075bbe8 b83c6205

+217
+200
drivers/infiniband/hw/ionic/ionic_ibdev.c
··· 3 3 4 4 #include <linux/module.h> 5 5 #include <linux/printk.h> 6 + #include <linux/pci.h> 7 + #include <linux/irq.h> 6 8 #include <net/addrconf.h> 9 + #include <rdma/ib_addr.h> 10 + #include <rdma/ib_mad.h> 7 11 8 12 #include "ionic_ibdev.h" 9 13 ··· 18 14 MODULE_DESCRIPTION(DRIVER_DESCRIPTION); 19 15 MODULE_LICENSE("GPL"); 20 16 MODULE_IMPORT_NS("NET_IONIC"); 17 + 18 + static int ionic_query_device(struct ib_device *ibdev, 19 + struct ib_device_attr *attr, 20 + struct ib_udata *udata) 21 + { 22 + struct ionic_ibdev *dev = to_ionic_ibdev(ibdev); 23 + struct net_device *ndev; 24 + 25 + ndev = ib_device_get_netdev(ibdev, 1); 26 + addrconf_ifid_eui48((u8 *)&attr->sys_image_guid, ndev); 27 + dev_put(ndev); 28 + attr->max_mr_size = dev->lif_cfg.npts_per_lif * PAGE_SIZE / 2; 29 + attr->page_size_cap = dev->lif_cfg.page_size_supported; 30 + 31 + attr->vendor_id = to_pci_dev(dev->lif_cfg.hwdev)->vendor; 32 + attr->vendor_part_id = to_pci_dev(dev->lif_cfg.hwdev)->device; 33 + 34 + attr->hw_ver = ionic_lif_asic_rev(dev->lif_cfg.lif); 35 + attr->fw_ver = 0; 36 + attr->max_qp = dev->lif_cfg.qp_count; 37 + attr->max_qp_wr = IONIC_MAX_DEPTH; 38 + attr->device_cap_flags = 39 + IB_DEVICE_MEM_WINDOW | 40 + IB_DEVICE_MEM_MGT_EXTENSIONS | 41 + IB_DEVICE_MEM_WINDOW_TYPE_2B | 42 + 0; 43 + attr->max_send_sge = 44 + min(ionic_v1_send_wqe_max_sge(dev->lif_cfg.max_stride, 0, false), 45 + IONIC_SPEC_HIGH); 46 + attr->max_recv_sge = 47 + min(ionic_v1_recv_wqe_max_sge(dev->lif_cfg.max_stride, 0, false), 48 + IONIC_SPEC_HIGH); 49 + attr->max_sge_rd = attr->max_send_sge; 50 + attr->max_cq = dev->lif_cfg.cq_count / dev->lif_cfg.udma_count; 51 + attr->max_cqe = IONIC_MAX_CQ_DEPTH - IONIC_CQ_GRACE; 52 + attr->max_mr = dev->lif_cfg.nmrs_per_lif; 53 + attr->max_pd = IONIC_MAX_PD; 54 + attr->max_qp_rd_atom = IONIC_MAX_RD_ATOM; 55 + attr->max_ee_rd_atom = 0; 56 + attr->max_res_rd_atom = IONIC_MAX_RD_ATOM; 57 + attr->max_qp_init_rd_atom = IONIC_MAX_RD_ATOM; 58 + attr->max_ee_init_rd_atom = 0; 59 + attr->atomic_cap = IB_ATOMIC_GLOB; 60 + attr->masked_atomic_cap = IB_ATOMIC_GLOB; 61 + attr->max_mw = dev->lif_cfg.nmrs_per_lif; 62 + attr->max_mcast_grp = 0; 63 + attr->max_mcast_qp_attach = 0; 64 + attr->max_ah = dev->lif_cfg.nahs_per_lif; 65 + attr->max_fast_reg_page_list_len = dev->lif_cfg.npts_per_lif / 2; 66 + attr->max_pkeys = IONIC_PKEY_TBL_LEN; 67 + 68 + return 0; 69 + } 70 + 71 + static int ionic_query_port(struct ib_device *ibdev, u32 port, 72 + struct ib_port_attr *attr) 73 + { 74 + struct net_device *ndev; 75 + 76 + if (port != 1) 77 + return -EINVAL; 78 + 79 + ndev = ib_device_get_netdev(ibdev, port); 80 + 81 + if (netif_running(ndev) && netif_carrier_ok(ndev)) { 82 + attr->state = IB_PORT_ACTIVE; 83 + attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP; 84 + } else if (netif_running(ndev)) { 85 + attr->state = IB_PORT_DOWN; 86 + attr->phys_state = IB_PORT_PHYS_STATE_POLLING; 87 + } else { 88 + attr->state = IB_PORT_DOWN; 89 + attr->phys_state = IB_PORT_PHYS_STATE_DISABLED; 90 + } 91 + 92 + attr->max_mtu = iboe_get_mtu(ndev->max_mtu); 93 + attr->active_mtu = min(attr->max_mtu, iboe_get_mtu(ndev->mtu)); 94 + attr->gid_tbl_len = IONIC_GID_TBL_LEN; 95 + attr->ip_gids = true; 96 + attr->port_cap_flags = 0; 97 + attr->max_msg_sz = 0x80000000; 98 + attr->pkey_tbl_len = IONIC_PKEY_TBL_LEN; 99 + attr->max_vl_num = 1; 100 + attr->subnet_prefix = 0xfe80000000000000ull; 101 + 102 + dev_put(ndev); 103 + 104 + return ib_get_eth_speed(ibdev, port, 105 + &attr->active_speed, 106 + &attr->active_width); 107 + } 108 + 109 + static enum rdma_link_layer ionic_get_link_layer(struct ib_device *ibdev, 110 + u32 port) 111 + { 112 + return IB_LINK_LAYER_ETHERNET; 113 + } 114 + 115 + static int ionic_query_pkey(struct ib_device *ibdev, u32 port, u16 index, 116 + u16 *pkey) 117 + { 118 + if (port != 1) 119 + return -EINVAL; 120 + 121 + if (index != 0) 122 + return -EINVAL; 123 + 124 + *pkey = IB_DEFAULT_PKEY_FULL; 125 + 126 + return 0; 127 + } 128 + 129 + static int ionic_modify_device(struct ib_device *ibdev, int mask, 130 + struct ib_device_modify *attr) 131 + { 132 + struct ionic_ibdev *dev = to_ionic_ibdev(ibdev); 133 + 134 + if (mask & ~IB_DEVICE_MODIFY_NODE_DESC) 135 + return -EOPNOTSUPP; 136 + 137 + if (mask & IB_DEVICE_MODIFY_NODE_DESC) 138 + memcpy(dev->ibdev.node_desc, attr->node_desc, 139 + IB_DEVICE_NODE_DESC_MAX); 140 + 141 + return 0; 142 + } 143 + 144 + static int ionic_get_port_immutable(struct ib_device *ibdev, u32 port, 145 + struct ib_port_immutable *attr) 146 + { 147 + if (port != 1) 148 + return -EINVAL; 149 + 150 + attr->core_cap_flags = RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP; 151 + 152 + attr->pkey_tbl_len = IONIC_PKEY_TBL_LEN; 153 + attr->gid_tbl_len = IONIC_GID_TBL_LEN; 154 + attr->max_mad_size = IB_MGMT_MAD_SIZE; 155 + 156 + return 0; 157 + } 158 + 159 + static void ionic_get_dev_fw_str(struct ib_device *ibdev, char *str) 160 + { 161 + struct ionic_ibdev *dev = to_ionic_ibdev(ibdev); 162 + 163 + ionic_lif_fw_version(dev->lif_cfg.lif, str, IB_FW_VERSION_NAME_MAX); 164 + } 165 + 166 + static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr, 167 + char *buf) 168 + { 169 + struct ionic_ibdev *dev = 170 + rdma_device_to_drv_device(device, struct ionic_ibdev, ibdev); 171 + 172 + return sysfs_emit(buf, "0x%x\n", ionic_lif_asic_rev(dev->lif_cfg.lif)); 173 + } 174 + static DEVICE_ATTR_RO(hw_rev); 175 + 176 + static ssize_t hca_type_show(struct device *device, 177 + struct device_attribute *attr, char *buf) 178 + { 179 + struct ionic_ibdev *dev = 180 + rdma_device_to_drv_device(device, struct ionic_ibdev, ibdev); 181 + 182 + return sysfs_emit(buf, "%s\n", dev->ibdev.node_desc); 183 + } 184 + static DEVICE_ATTR_RO(hca_type); 185 + 186 + static struct attribute *ionic_rdma_attributes[] = { 187 + &dev_attr_hw_rev.attr, 188 + &dev_attr_hca_type.attr, 189 + NULL 190 + }; 191 + 192 + static const struct attribute_group ionic_rdma_attr_group = { 193 + .attrs = ionic_rdma_attributes, 194 + }; 195 + 196 + static void ionic_disassociate_ucontext(struct ib_ucontext *ibcontext) 197 + { 198 + /* 199 + * Dummy define disassociate_ucontext so that it does not 200 + * wait for user context before cleaning up hw resources. 201 + */ 202 + } 21 203 22 204 static const struct ib_device_ops ionic_dev_ops = { 23 205 .owner = THIS_MODULE, ··· 239 49 .post_recv = ionic_post_recv, 240 50 .poll_cq = ionic_poll_cq, 241 51 .req_notify_cq = ionic_req_notify_cq, 52 + 53 + .query_device = ionic_query_device, 54 + .query_port = ionic_query_port, 55 + .get_link_layer = ionic_get_link_layer, 56 + .query_pkey = ionic_query_pkey, 57 + .modify_device = ionic_modify_device, 58 + .get_port_immutable = ionic_get_port_immutable, 59 + .get_dev_fw_str = ionic_get_dev_fw_str, 60 + .device_group = &ionic_rdma_attr_group, 61 + .disassociate_ucontext = ionic_disassociate_ucontext, 242 62 243 63 INIT_RDMA_OBJ_SIZE(ib_ucontext, ionic_ctx, ibctx), 244 64 INIT_RDMA_OBJ_SIZE(ib_pd, ionic_pd, ibpd),
+5
drivers/infiniband/hw/ionic/ionic_ibdev.h
··· 26 26 #define IONIC_AQ_COUNT 4 27 27 #define IONIC_EQ_ISR_BUDGET 10 28 28 #define IONIC_EQ_WORK_BUDGET 1000 29 + #define IONIC_MAX_RD_ATOM 16 30 + #define IONIC_PKEY_TBL_LEN 1 31 + #define IONIC_GID_TBL_LEN 256 32 + 33 + #define IONIC_SPEC_HIGH 8 29 34 #define IONIC_MAX_PD 1024 30 35 #define IONIC_SPEC_HIGH 8 31 36 #define IONIC_SQCMB_ORDER 5
+10
drivers/infiniband/hw/ionic/ionic_lif_cfg.c
··· 99 99 dev_hold(netdev); 100 100 return netdev; 101 101 } 102 + 103 + void ionic_lif_fw_version(struct ionic_lif *lif, char *str, size_t len) 104 + { 105 + strscpy(str, lif->ionic->idev.dev_info.fw_version, len); 106 + } 107 + 108 + u8 ionic_lif_asic_rev(struct ionic_lif *lif) 109 + { 110 + return lif->ionic->idev.dev_info.asic_rev; 111 + }
+2
drivers/infiniband/hw/ionic/ionic_lif_cfg.h
··· 60 60 61 61 void ionic_fill_lif_cfg(struct ionic_lif *lif, struct ionic_lif_cfg *cfg); 62 62 struct net_device *ionic_lif_netdev(struct ionic_lif *lif); 63 + void ionic_lif_fw_version(struct ionic_lif *lif, char *str, size_t len); 64 + u8 ionic_lif_asic_rev(struct ionic_lif *lif); 63 65 64 66 #endif /* _IONIC_LIF_CFG_H_ */