provider.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. /*
  2. * Copyright (c) 2009-2010 Chelsio, Inc. All rights reserved.
  3. *
  4. * This software is available to you under a choice of one of two
  5. * licenses. You may choose to be licensed under the terms of the GNU
  6. * General Public License (GPL) Version 2, available from the file
  7. * COPYING in the main directory of this source tree, or the
  8. * OpenIB.org BSD license below:
  9. *
  10. * Redistribution and use in source and binary forms, with or
  11. * without modification, are permitted provided that the following
  12. * conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above
  15. * copyright notice, this list of conditions and the following
  16. * disclaimer.
  17. *
  18. * - Redistributions in binary form must reproduce the above
  19. * copyright notice, this list of conditions and the following
  20. * disclaimer in the documentation and/or other materials
  21. * provided with the distribution.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. */
  32. #include <linux/module.h>
  33. #include <linux/moduleparam.h>
  34. #include <linux/device.h>
  35. #include <linux/netdevice.h>
  36. #include <linux/etherdevice.h>
  37. #include <linux/delay.h>
  38. #include <linux/errno.h>
  39. #include <linux/list.h>
  40. #include <linux/spinlock.h>
  41. #include <linux/ethtool.h>
  42. #include <linux/rtnetlink.h>
  43. #include <linux/inetdevice.h>
  44. #include <net/addrconf.h>
  45. #include <linux/io.h>
  46. #include <asm/irq.h>
  47. #include <asm/byteorder.h>
  48. #include <rdma/iw_cm.h>
  49. #include <rdma/ib_verbs.h>
  50. #include <rdma/ib_smi.h>
  51. #include <rdma/ib_umem.h>
  52. #include <rdma/ib_user_verbs.h>
  53. #include "iw_cxgb4.h"
  54. static int fastreg_support = 1;
  55. module_param(fastreg_support, int, 0644);
  56. MODULE_PARM_DESC(fastreg_support, "Advertise fastreg support (default=1)");
  57. static void c4iw_dealloc_ucontext(struct ib_ucontext *context)
  58. {
  59. struct c4iw_ucontext *ucontext = to_c4iw_ucontext(context);
  60. struct c4iw_dev *rhp;
  61. struct c4iw_mm_entry *mm, *tmp;
  62. pr_debug("context %p\n", context);
  63. rhp = to_c4iw_dev(ucontext->ibucontext.device);
  64. list_for_each_entry_safe(mm, tmp, &ucontext->mmaps, entry)
  65. kfree(mm);
  66. c4iw_release_dev_ucontext(&rhp->rdev, &ucontext->uctx);
  67. }
  68. static int c4iw_alloc_ucontext(struct ib_ucontext *ucontext,
  69. struct ib_udata *udata)
  70. {
  71. struct ib_device *ibdev = ucontext->device;
  72. struct c4iw_ucontext *context = to_c4iw_ucontext(ucontext);
  73. struct c4iw_dev *rhp = to_c4iw_dev(ibdev);
  74. struct c4iw_alloc_ucontext_resp uresp;
  75. int ret = 0;
  76. struct c4iw_mm_entry *mm = NULL;
  77. pr_debug("ibdev %p\n", ibdev);
  78. c4iw_init_dev_ucontext(&rhp->rdev, &context->uctx);
  79. INIT_LIST_HEAD(&context->mmaps);
  80. spin_lock_init(&context->mmap_lock);
  81. if (udata->outlen < sizeof(uresp) - sizeof(uresp.reserved)) {
  82. pr_err_once("Warning - downlevel libcxgb4 (non-fatal), device status page disabled\n");
  83. rhp->rdev.flags |= T4_STATUS_PAGE_DISABLED;
  84. } else {
  85. mm = kmalloc(sizeof(*mm), GFP_KERNEL);
  86. if (!mm) {
  87. ret = -ENOMEM;
  88. goto err;
  89. }
  90. uresp.status_page_size = PAGE_SIZE;
  91. spin_lock(&context->mmap_lock);
  92. uresp.status_page_key = context->key;
  93. context->key += PAGE_SIZE;
  94. spin_unlock(&context->mmap_lock);
  95. ret = ib_copy_to_udata(udata, &uresp,
  96. sizeof(uresp) - sizeof(uresp.reserved));
  97. if (ret)
  98. goto err_mm;
  99. mm->key = uresp.status_page_key;
  100. mm->addr = virt_to_phys(rhp->rdev.status_page);
  101. mm->len = PAGE_SIZE;
  102. insert_mmap(context, mm);
  103. }
  104. return 0;
  105. err_mm:
  106. kfree(mm);
  107. err:
  108. return ret;
  109. }
  110. static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
  111. {
  112. int len = vma->vm_end - vma->vm_start;
  113. u32 key = vma->vm_pgoff << PAGE_SHIFT;
  114. struct c4iw_rdev *rdev;
  115. int ret = 0;
  116. struct c4iw_mm_entry *mm;
  117. struct c4iw_ucontext *ucontext;
  118. u64 addr;
  119. pr_debug("pgoff 0x%lx key 0x%x len %d\n", vma->vm_pgoff,
  120. key, len);
  121. if (vma->vm_start & (PAGE_SIZE-1))
  122. return -EINVAL;
  123. rdev = &(to_c4iw_dev(context->device)->rdev);
  124. ucontext = to_c4iw_ucontext(context);
  125. mm = remove_mmap(ucontext, key, len);
  126. if (!mm)
  127. return -EINVAL;
  128. addr = mm->addr;
  129. kfree(mm);
  130. if ((addr >= pci_resource_start(rdev->lldi.pdev, 0)) &&
  131. (addr < (pci_resource_start(rdev->lldi.pdev, 0) +
  132. pci_resource_len(rdev->lldi.pdev, 0)))) {
  133. /*
  134. * MA_SYNC register...
  135. */
  136. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  137. ret = io_remap_pfn_range(vma, vma->vm_start,
  138. addr >> PAGE_SHIFT,
  139. len, vma->vm_page_prot);
  140. } else if ((addr >= pci_resource_start(rdev->lldi.pdev, 2)) &&
  141. (addr < (pci_resource_start(rdev->lldi.pdev, 2) +
  142. pci_resource_len(rdev->lldi.pdev, 2)))) {
  143. /*
  144. * Map user DB or OCQP memory...
  145. */
  146. if (addr >= rdev->oc_mw_pa)
  147. vma->vm_page_prot = t4_pgprot_wc(vma->vm_page_prot);
  148. else {
  149. if (!is_t4(rdev->lldi.adapter_type))
  150. vma->vm_page_prot =
  151. t4_pgprot_wc(vma->vm_page_prot);
  152. else
  153. vma->vm_page_prot =
  154. pgprot_noncached(vma->vm_page_prot);
  155. }
  156. ret = io_remap_pfn_range(vma, vma->vm_start,
  157. addr >> PAGE_SHIFT,
  158. len, vma->vm_page_prot);
  159. } else {
  160. /*
  161. * Map WQ or CQ contig dma memory...
  162. */
  163. ret = remap_pfn_range(vma, vma->vm_start,
  164. addr >> PAGE_SHIFT,
  165. len, vma->vm_page_prot);
  166. }
  167. return ret;
  168. }
  169. static int c4iw_deallocate_pd(struct ib_pd *pd, struct ib_udata *udata)
  170. {
  171. struct c4iw_dev *rhp;
  172. struct c4iw_pd *php;
  173. php = to_c4iw_pd(pd);
  174. rhp = php->rhp;
  175. pr_debug("ibpd %p pdid 0x%x\n", pd, php->pdid);
  176. c4iw_put_resource(&rhp->rdev.resource.pdid_table, php->pdid);
  177. mutex_lock(&rhp->rdev.stats.lock);
  178. rhp->rdev.stats.pd.cur--;
  179. mutex_unlock(&rhp->rdev.stats.lock);
  180. return 0;
  181. }
  182. static int c4iw_allocate_pd(struct ib_pd *pd, struct ib_udata *udata)
  183. {
  184. struct c4iw_pd *php = to_c4iw_pd(pd);
  185. struct ib_device *ibdev = pd->device;
  186. u32 pdid;
  187. struct c4iw_dev *rhp;
  188. pr_debug("ibdev %p\n", ibdev);
  189. rhp = (struct c4iw_dev *) ibdev;
  190. pdid = c4iw_get_resource(&rhp->rdev.resource.pdid_table);
  191. if (!pdid)
  192. return -EINVAL;
  193. php->pdid = pdid;
  194. php->rhp = rhp;
  195. if (udata) {
  196. struct c4iw_alloc_pd_resp uresp = {.pdid = php->pdid};
  197. if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
  198. c4iw_deallocate_pd(&php->ibpd, udata);
  199. return -EFAULT;
  200. }
  201. }
  202. mutex_lock(&rhp->rdev.stats.lock);
  203. rhp->rdev.stats.pd.cur++;
  204. if (rhp->rdev.stats.pd.cur > rhp->rdev.stats.pd.max)
  205. rhp->rdev.stats.pd.max = rhp->rdev.stats.pd.cur;
  206. mutex_unlock(&rhp->rdev.stats.lock);
  207. pr_debug("pdid 0x%0x ptr 0x%p\n", pdid, php);
  208. return 0;
  209. }
  210. static int c4iw_query_gid(struct ib_device *ibdev, u32 port, int index,
  211. union ib_gid *gid)
  212. {
  213. struct c4iw_dev *dev;
  214. pr_debug("ibdev %p, port %u, index %d, gid %p\n",
  215. ibdev, port, index, gid);
  216. if (!port)
  217. return -EINVAL;
  218. dev = to_c4iw_dev(ibdev);
  219. memset(&(gid->raw[0]), 0, sizeof(gid->raw));
  220. memcpy(&(gid->raw[0]), dev->rdev.lldi.ports[port-1]->dev_addr, 6);
  221. return 0;
  222. }
  223. static int c4iw_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
  224. struct ib_udata *uhw)
  225. {
  226. struct c4iw_dev *dev;
  227. pr_debug("ibdev %p\n", ibdev);
  228. if (uhw->inlen || uhw->outlen)
  229. return -EINVAL;
  230. dev = to_c4iw_dev(ibdev);
  231. addrconf_addr_eui48((u8 *)&props->sys_image_guid,
  232. dev->rdev.lldi.ports[0]->dev_addr);
  233. props->hw_ver = CHELSIO_CHIP_RELEASE(dev->rdev.lldi.adapter_type);
  234. props->fw_ver = dev->rdev.lldi.fw_vers;
  235. props->device_cap_flags = IB_DEVICE_MEM_WINDOW;
  236. props->kernel_cap_flags = IBK_LOCAL_DMA_LKEY;
  237. if (fastreg_support)
  238. props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
  239. props->page_size_cap = T4_PAGESIZE_MASK;
  240. props->vendor_id = (u32)dev->rdev.lldi.pdev->vendor;
  241. props->vendor_part_id = (u32)dev->rdev.lldi.pdev->device;
  242. props->max_mr_size = T4_MAX_MR_SIZE;
  243. props->max_qp = dev->rdev.lldi.vr->qp.size / 2;
  244. props->max_srq = dev->rdev.lldi.vr->srq.size;
  245. props->max_qp_wr = dev->rdev.hw_queue.t4_max_qp_depth;
  246. props->max_srq_wr = dev->rdev.hw_queue.t4_max_qp_depth;
  247. props->max_send_sge = min(T4_MAX_SEND_SGE, T4_MAX_WRITE_SGE);
  248. props->max_recv_sge = T4_MAX_RECV_SGE;
  249. props->max_srq_sge = T4_MAX_RECV_SGE;
  250. props->max_sge_rd = 1;
  251. props->max_res_rd_atom = dev->rdev.lldi.max_ird_adapter;
  252. props->max_qp_rd_atom = min(dev->rdev.lldi.max_ordird_qp,
  253. c4iw_max_read_depth);
  254. props->max_qp_init_rd_atom = props->max_qp_rd_atom;
  255. props->max_cq = dev->rdev.lldi.vr->qp.size;
  256. props->max_cqe = dev->rdev.hw_queue.t4_max_cq_depth;
  257. props->max_mr = c4iw_num_stags(&dev->rdev);
  258. props->max_pd = T4_MAX_NUM_PD;
  259. props->local_ca_ack_delay = 0;
  260. props->max_fast_reg_page_list_len =
  261. t4_max_fr_depth(dev->rdev.lldi.ulptx_memwrite_dsgl && use_dsgl);
  262. return 0;
  263. }
  264. static int c4iw_query_port(struct ib_device *ibdev, u32 port,
  265. struct ib_port_attr *props)
  266. {
  267. int ret = 0;
  268. pr_debug("ibdev %p\n", ibdev);
  269. ret = ib_get_eth_speed(ibdev, port, &props->active_speed,
  270. &props->active_width);
  271. props->port_cap_flags =
  272. IB_PORT_CM_SUP |
  273. IB_PORT_SNMP_TUNNEL_SUP |
  274. IB_PORT_REINIT_SUP |
  275. IB_PORT_DEVICE_MGMT_SUP |
  276. IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
  277. props->gid_tbl_len = 1;
  278. props->max_msg_sz = -1;
  279. return ret;
  280. }
  281. static ssize_t hw_rev_show(struct device *dev,
  282. struct device_attribute *attr, char *buf)
  283. {
  284. struct c4iw_dev *c4iw_dev =
  285. rdma_device_to_drv_device(dev, struct c4iw_dev, ibdev);
  286. pr_debug("dev 0x%p\n", dev);
  287. return sysfs_emit(
  288. buf, "%d\n",
  289. CHELSIO_CHIP_RELEASE(c4iw_dev->rdev.lldi.adapter_type));
  290. }
  291. static DEVICE_ATTR_RO(hw_rev);
  292. static ssize_t hca_type_show(struct device *dev,
  293. struct device_attribute *attr, char *buf)
  294. {
  295. struct c4iw_dev *c4iw_dev =
  296. rdma_device_to_drv_device(dev, struct c4iw_dev, ibdev);
  297. struct ethtool_drvinfo info;
  298. struct net_device *lldev = c4iw_dev->rdev.lldi.ports[0];
  299. pr_debug("dev 0x%p\n", dev);
  300. lldev->ethtool_ops->get_drvinfo(lldev, &info);
  301. return sysfs_emit(buf, "%s\n", info.driver);
  302. }
  303. static DEVICE_ATTR_RO(hca_type);
  304. static ssize_t board_id_show(struct device *dev, struct device_attribute *attr,
  305. char *buf)
  306. {
  307. struct c4iw_dev *c4iw_dev =
  308. rdma_device_to_drv_device(dev, struct c4iw_dev, ibdev);
  309. pr_debug("dev 0x%p\n", dev);
  310. return sysfs_emit(buf, "%x.%x\n", c4iw_dev->rdev.lldi.pdev->vendor,
  311. c4iw_dev->rdev.lldi.pdev->device);
  312. }
  313. static DEVICE_ATTR_RO(board_id);
  314. enum counters {
  315. IP4INSEGS,
  316. IP4OUTSEGS,
  317. IP4RETRANSSEGS,
  318. IP4OUTRSTS,
  319. IP6INSEGS,
  320. IP6OUTSEGS,
  321. IP6RETRANSSEGS,
  322. IP6OUTRSTS,
  323. NR_COUNTERS
  324. };
  325. static const struct rdma_stat_desc cxgb4_descs[] = {
  326. [IP4INSEGS].name = "ip4InSegs",
  327. [IP4OUTSEGS].name = "ip4OutSegs",
  328. [IP4RETRANSSEGS].name = "ip4RetransSegs",
  329. [IP4OUTRSTS].name = "ip4OutRsts",
  330. [IP6INSEGS].name = "ip6InSegs",
  331. [IP6OUTSEGS].name = "ip6OutSegs",
  332. [IP6RETRANSSEGS].name = "ip6RetransSegs",
  333. [IP6OUTRSTS].name = "ip6OutRsts"
  334. };
  335. static struct rdma_hw_stats *c4iw_alloc_device_stats(struct ib_device *ibdev)
  336. {
  337. BUILD_BUG_ON(ARRAY_SIZE(cxgb4_descs) != NR_COUNTERS);
  338. /* FIXME: these look like port stats */
  339. return rdma_alloc_hw_stats_struct(cxgb4_descs, NR_COUNTERS,
  340. RDMA_HW_STATS_DEFAULT_LIFESPAN);
  341. }
  342. static int c4iw_get_mib(struct ib_device *ibdev,
  343. struct rdma_hw_stats *stats,
  344. u32 port, int index)
  345. {
  346. struct tp_tcp_stats v4, v6;
  347. struct c4iw_dev *c4iw_dev = to_c4iw_dev(ibdev);
  348. cxgb4_get_tcp_stats(c4iw_dev->rdev.lldi.pdev, &v4, &v6);
  349. stats->value[IP4INSEGS] = v4.tcp_in_segs;
  350. stats->value[IP4OUTSEGS] = v4.tcp_out_segs;
  351. stats->value[IP4RETRANSSEGS] = v4.tcp_retrans_segs;
  352. stats->value[IP4OUTRSTS] = v4.tcp_out_rsts;
  353. stats->value[IP6INSEGS] = v6.tcp_in_segs;
  354. stats->value[IP6OUTSEGS] = v6.tcp_out_segs;
  355. stats->value[IP6RETRANSSEGS] = v6.tcp_retrans_segs;
  356. stats->value[IP6OUTRSTS] = v6.tcp_out_rsts;
  357. return stats->num_counters;
  358. }
  359. static struct attribute *c4iw_class_attributes[] = {
  360. &dev_attr_hw_rev.attr,
  361. &dev_attr_hca_type.attr,
  362. &dev_attr_board_id.attr,
  363. NULL
  364. };
  365. static const struct attribute_group c4iw_attr_group = {
  366. .attrs = c4iw_class_attributes,
  367. };
  368. static int c4iw_port_immutable(struct ib_device *ibdev, u32 port_num,
  369. struct ib_port_immutable *immutable)
  370. {
  371. struct ib_port_attr attr;
  372. int err;
  373. immutable->core_cap_flags = RDMA_CORE_PORT_IWARP;
  374. err = ib_query_port(ibdev, port_num, &attr);
  375. if (err)
  376. return err;
  377. immutable->gid_tbl_len = attr.gid_tbl_len;
  378. return 0;
  379. }
  380. static void get_dev_fw_str(struct ib_device *dev, char *str)
  381. {
  382. struct c4iw_dev *c4iw_dev = container_of(dev, struct c4iw_dev,
  383. ibdev);
  384. pr_debug("dev 0x%p\n", dev);
  385. snprintf(str, IB_FW_VERSION_NAME_MAX, "%u.%u.%u.%u",
  386. FW_HDR_FW_VER_MAJOR_G(c4iw_dev->rdev.lldi.fw_vers),
  387. FW_HDR_FW_VER_MINOR_G(c4iw_dev->rdev.lldi.fw_vers),
  388. FW_HDR_FW_VER_MICRO_G(c4iw_dev->rdev.lldi.fw_vers),
  389. FW_HDR_FW_VER_BUILD_G(c4iw_dev->rdev.lldi.fw_vers));
  390. }
  391. static const struct ib_device_ops c4iw_dev_ops = {
  392. .owner = THIS_MODULE,
  393. .driver_id = RDMA_DRIVER_CXGB4,
  394. .uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION,
  395. .alloc_hw_device_stats = c4iw_alloc_device_stats,
  396. .alloc_mr = c4iw_alloc_mr,
  397. .alloc_pd = c4iw_allocate_pd,
  398. .alloc_ucontext = c4iw_alloc_ucontext,
  399. .create_cq = c4iw_create_cq,
  400. .create_qp = c4iw_create_qp,
  401. .create_srq = c4iw_create_srq,
  402. .dealloc_pd = c4iw_deallocate_pd,
  403. .dealloc_ucontext = c4iw_dealloc_ucontext,
  404. .dereg_mr = c4iw_dereg_mr,
  405. .destroy_cq = c4iw_destroy_cq,
  406. .destroy_qp = c4iw_destroy_qp,
  407. .destroy_srq = c4iw_destroy_srq,
  408. .device_group = &c4iw_attr_group,
  409. .fill_res_cq_entry = c4iw_fill_res_cq_entry,
  410. .fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry,
  411. .fill_res_mr_entry = c4iw_fill_res_mr_entry,
  412. .get_dev_fw_str = get_dev_fw_str,
  413. .get_dma_mr = c4iw_get_dma_mr,
  414. .get_hw_stats = c4iw_get_mib,
  415. .get_port_immutable = c4iw_port_immutable,
  416. .iw_accept = c4iw_accept_cr,
  417. .iw_add_ref = c4iw_qp_add_ref,
  418. .iw_connect = c4iw_connect,
  419. .iw_create_listen = c4iw_create_listen,
  420. .iw_destroy_listen = c4iw_destroy_listen,
  421. .iw_get_qp = c4iw_get_qp,
  422. .iw_reject = c4iw_reject_cr,
  423. .iw_rem_ref = c4iw_qp_rem_ref,
  424. .map_mr_sg = c4iw_map_mr_sg,
  425. .mmap = c4iw_mmap,
  426. .modify_qp = c4iw_ib_modify_qp,
  427. .modify_srq = c4iw_modify_srq,
  428. .poll_cq = c4iw_poll_cq,
  429. .post_recv = c4iw_post_receive,
  430. .post_send = c4iw_post_send,
  431. .post_srq_recv = c4iw_post_srq_recv,
  432. .query_device = c4iw_query_device,
  433. .query_gid = c4iw_query_gid,
  434. .query_port = c4iw_query_port,
  435. .query_qp = c4iw_ib_query_qp,
  436. .reg_user_mr = c4iw_reg_user_mr,
  437. .req_notify_cq = c4iw_arm_cq,
  438. INIT_RDMA_OBJ_SIZE(ib_cq, c4iw_cq, ibcq),
  439. INIT_RDMA_OBJ_SIZE(ib_mw, c4iw_mw, ibmw),
  440. INIT_RDMA_OBJ_SIZE(ib_pd, c4iw_pd, ibpd),
  441. INIT_RDMA_OBJ_SIZE(ib_qp, c4iw_qp, ibqp),
  442. INIT_RDMA_OBJ_SIZE(ib_srq, c4iw_srq, ibsrq),
  443. INIT_RDMA_OBJ_SIZE(ib_ucontext, c4iw_ucontext, ibucontext),
  444. };
  445. static int set_netdevs(struct ib_device *ib_dev, struct c4iw_rdev *rdev)
  446. {
  447. int ret;
  448. int i;
  449. for (i = 0; i < rdev->lldi.nports; i++) {
  450. ret = ib_device_set_netdev(ib_dev, rdev->lldi.ports[i],
  451. i + 1);
  452. if (ret)
  453. return ret;
  454. }
  455. return 0;
  456. }
  457. void c4iw_register_device(struct work_struct *work)
  458. {
  459. int ret;
  460. struct uld_ctx *ctx = container_of(work, struct uld_ctx, reg_work);
  461. struct c4iw_dev *dev = ctx->dev;
  462. pr_debug("c4iw_dev %p\n", dev);
  463. addrconf_addr_eui48((u8 *)&dev->ibdev.node_guid,
  464. dev->rdev.lldi.ports[0]->dev_addr);
  465. dev->ibdev.local_dma_lkey = 0;
  466. dev->ibdev.node_type = RDMA_NODE_RNIC;
  467. BUILD_BUG_ON(sizeof(C4IW_NODE_DESC) > IB_DEVICE_NODE_DESC_MAX);
  468. memcpy(dev->ibdev.node_desc, C4IW_NODE_DESC, sizeof(C4IW_NODE_DESC));
  469. dev->ibdev.phys_port_cnt = dev->rdev.lldi.nports;
  470. dev->ibdev.num_comp_vectors = dev->rdev.lldi.nciq;
  471. dev->ibdev.dev.parent = &dev->rdev.lldi.pdev->dev;
  472. memcpy(dev->ibdev.iw_ifname, dev->rdev.lldi.ports[0]->name,
  473. sizeof(dev->ibdev.iw_ifname));
  474. ib_set_device_ops(&dev->ibdev, &c4iw_dev_ops);
  475. ret = set_netdevs(&dev->ibdev, &dev->rdev);
  476. if (ret)
  477. goto err_dealloc_ctx;
  478. dma_set_max_seg_size(&dev->rdev.lldi.pdev->dev, UINT_MAX);
  479. ret = ib_register_device(&dev->ibdev, "cxgb4_%d",
  480. &dev->rdev.lldi.pdev->dev);
  481. if (ret)
  482. goto err_dealloc_ctx;
  483. return;
  484. err_dealloc_ctx:
  485. pr_err("%s - Failed registering iwarp device: %d\n",
  486. pci_name(ctx->lldi.pdev), ret);
  487. c4iw_dealloc(ctx);
  488. return;
  489. }
  490. void c4iw_unregister_device(struct c4iw_dev *dev)
  491. {
  492. pr_debug("c4iw_dev %p\n", dev);
  493. ib_unregister_device(&dev->ibdev);
  494. return;
  495. }