18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright (c) 2009-2010 Chelsio, Inc. All rights reserved.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two
58c2ecf20Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
68c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
78c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the
88c2ecf20Sopenharmony_ci * OpenIB.org BSD license below:
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
118c2ecf20Sopenharmony_ci *     without modification, are permitted provided that the following
128c2ecf20Sopenharmony_ci *     conditions are met:
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci *      - Redistributions of source code must retain the above
158c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
168c2ecf20Sopenharmony_ci *        disclaimer.
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
198c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
208c2ecf20Sopenharmony_ci *        disclaimer in the documentation and/or other materials
218c2ecf20Sopenharmony_ci *        provided with the distribution.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
248c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
258c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
268c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
278c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
288c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
298c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
308c2ecf20Sopenharmony_ci * SOFTWARE.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci#include <linux/module.h>
338c2ecf20Sopenharmony_ci#include <linux/moduleparam.h>
348c2ecf20Sopenharmony_ci#include <linux/device.h>
358c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
368c2ecf20Sopenharmony_ci#include <linux/etherdevice.h>
378c2ecf20Sopenharmony_ci#include <linux/delay.h>
388c2ecf20Sopenharmony_ci#include <linux/errno.h>
398c2ecf20Sopenharmony_ci#include <linux/list.h>
408c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
418c2ecf20Sopenharmony_ci#include <linux/ethtool.h>
428c2ecf20Sopenharmony_ci#include <linux/rtnetlink.h>
438c2ecf20Sopenharmony_ci#include <linux/inetdevice.h>
448c2ecf20Sopenharmony_ci#include <linux/io.h>
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#include <asm/irq.h>
478c2ecf20Sopenharmony_ci#include <asm/byteorder.h>
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci#include <rdma/iw_cm.h>
508c2ecf20Sopenharmony_ci#include <rdma/ib_verbs.h>
518c2ecf20Sopenharmony_ci#include <rdma/ib_smi.h>
528c2ecf20Sopenharmony_ci#include <rdma/ib_umem.h>
538c2ecf20Sopenharmony_ci#include <rdma/ib_user_verbs.h>
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#include "iw_cxgb4.h"
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic int fastreg_support = 1;
588c2ecf20Sopenharmony_cimodule_param(fastreg_support, int, 0644);
598c2ecf20Sopenharmony_ciMODULE_PARM_DESC(fastreg_support, "Advertise fastreg support (default=1)");
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cistatic void c4iw_dealloc_ucontext(struct ib_ucontext *context)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	struct c4iw_ucontext *ucontext = to_c4iw_ucontext(context);
648c2ecf20Sopenharmony_ci	struct c4iw_dev *rhp;
658c2ecf20Sopenharmony_ci	struct c4iw_mm_entry *mm, *tmp;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	pr_debug("context %p\n", context);
688c2ecf20Sopenharmony_ci	rhp = to_c4iw_dev(ucontext->ibucontext.device);
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	list_for_each_entry_safe(mm, tmp, &ucontext->mmaps, entry)
718c2ecf20Sopenharmony_ci		kfree(mm);
728c2ecf20Sopenharmony_ci	c4iw_release_dev_ucontext(&rhp->rdev, &ucontext->uctx);
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_cistatic int c4iw_alloc_ucontext(struct ib_ucontext *ucontext,
768c2ecf20Sopenharmony_ci			       struct ib_udata *udata)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	struct ib_device *ibdev = ucontext->device;
798c2ecf20Sopenharmony_ci	struct c4iw_ucontext *context = to_c4iw_ucontext(ucontext);
808c2ecf20Sopenharmony_ci	struct c4iw_dev *rhp = to_c4iw_dev(ibdev);
818c2ecf20Sopenharmony_ci	struct c4iw_alloc_ucontext_resp uresp;
828c2ecf20Sopenharmony_ci	int ret = 0;
838c2ecf20Sopenharmony_ci	struct c4iw_mm_entry *mm = NULL;
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	pr_debug("ibdev %p\n", ibdev);
868c2ecf20Sopenharmony_ci	c4iw_init_dev_ucontext(&rhp->rdev, &context->uctx);
878c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&context->mmaps);
888c2ecf20Sopenharmony_ci	spin_lock_init(&context->mmap_lock);
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	if (udata->outlen < sizeof(uresp) - sizeof(uresp.reserved)) {
918c2ecf20Sopenharmony_ci		pr_err_once("Warning - downlevel libcxgb4 (non-fatal), device status page disabled\n");
928c2ecf20Sopenharmony_ci		rhp->rdev.flags |= T4_STATUS_PAGE_DISABLED;
938c2ecf20Sopenharmony_ci	} else {
948c2ecf20Sopenharmony_ci		mm = kmalloc(sizeof(*mm), GFP_KERNEL);
958c2ecf20Sopenharmony_ci		if (!mm) {
968c2ecf20Sopenharmony_ci			ret = -ENOMEM;
978c2ecf20Sopenharmony_ci			goto err;
988c2ecf20Sopenharmony_ci		}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci		uresp.status_page_size = PAGE_SIZE;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci		spin_lock(&context->mmap_lock);
1038c2ecf20Sopenharmony_ci		uresp.status_page_key = context->key;
1048c2ecf20Sopenharmony_ci		context->key += PAGE_SIZE;
1058c2ecf20Sopenharmony_ci		spin_unlock(&context->mmap_lock);
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci		ret = ib_copy_to_udata(udata, &uresp,
1088c2ecf20Sopenharmony_ci				       sizeof(uresp) - sizeof(uresp.reserved));
1098c2ecf20Sopenharmony_ci		if (ret)
1108c2ecf20Sopenharmony_ci			goto err_mm;
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci		mm->key = uresp.status_page_key;
1138c2ecf20Sopenharmony_ci		mm->addr = virt_to_phys(rhp->rdev.status_page);
1148c2ecf20Sopenharmony_ci		mm->len = PAGE_SIZE;
1158c2ecf20Sopenharmony_ci		insert_mmap(context, mm);
1168c2ecf20Sopenharmony_ci	}
1178c2ecf20Sopenharmony_ci	return 0;
1188c2ecf20Sopenharmony_cierr_mm:
1198c2ecf20Sopenharmony_ci	kfree(mm);
1208c2ecf20Sopenharmony_cierr:
1218c2ecf20Sopenharmony_ci	return ret;
1228c2ecf20Sopenharmony_ci}
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
1258c2ecf20Sopenharmony_ci{
1268c2ecf20Sopenharmony_ci	int len = vma->vm_end - vma->vm_start;
1278c2ecf20Sopenharmony_ci	u32 key = vma->vm_pgoff << PAGE_SHIFT;
1288c2ecf20Sopenharmony_ci	struct c4iw_rdev *rdev;
1298c2ecf20Sopenharmony_ci	int ret = 0;
1308c2ecf20Sopenharmony_ci	struct c4iw_mm_entry *mm;
1318c2ecf20Sopenharmony_ci	struct c4iw_ucontext *ucontext;
1328c2ecf20Sopenharmony_ci	u64 addr;
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	pr_debug("pgoff 0x%lx key 0x%x len %d\n", vma->vm_pgoff,
1358c2ecf20Sopenharmony_ci		 key, len);
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	if (vma->vm_start & (PAGE_SIZE-1))
1388c2ecf20Sopenharmony_ci		return -EINVAL;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	rdev = &(to_c4iw_dev(context->device)->rdev);
1418c2ecf20Sopenharmony_ci	ucontext = to_c4iw_ucontext(context);
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	mm = remove_mmap(ucontext, key, len);
1448c2ecf20Sopenharmony_ci	if (!mm)
1458c2ecf20Sopenharmony_ci		return -EINVAL;
1468c2ecf20Sopenharmony_ci	addr = mm->addr;
1478c2ecf20Sopenharmony_ci	kfree(mm);
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	if ((addr >= pci_resource_start(rdev->lldi.pdev, 0)) &&
1508c2ecf20Sopenharmony_ci	    (addr < (pci_resource_start(rdev->lldi.pdev, 0) +
1518c2ecf20Sopenharmony_ci		    pci_resource_len(rdev->lldi.pdev, 0)))) {
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci		/*
1548c2ecf20Sopenharmony_ci		 * MA_SYNC register...
1558c2ecf20Sopenharmony_ci		 */
1568c2ecf20Sopenharmony_ci		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1578c2ecf20Sopenharmony_ci		ret = io_remap_pfn_range(vma, vma->vm_start,
1588c2ecf20Sopenharmony_ci					 addr >> PAGE_SHIFT,
1598c2ecf20Sopenharmony_ci					 len, vma->vm_page_prot);
1608c2ecf20Sopenharmony_ci	} else if ((addr >= pci_resource_start(rdev->lldi.pdev, 2)) &&
1618c2ecf20Sopenharmony_ci		   (addr < (pci_resource_start(rdev->lldi.pdev, 2) +
1628c2ecf20Sopenharmony_ci		    pci_resource_len(rdev->lldi.pdev, 2)))) {
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci		/*
1658c2ecf20Sopenharmony_ci		 * Map user DB or OCQP memory...
1668c2ecf20Sopenharmony_ci		 */
1678c2ecf20Sopenharmony_ci		if (addr >= rdev->oc_mw_pa)
1688c2ecf20Sopenharmony_ci			vma->vm_page_prot = t4_pgprot_wc(vma->vm_page_prot);
1698c2ecf20Sopenharmony_ci		else {
1708c2ecf20Sopenharmony_ci			if (!is_t4(rdev->lldi.adapter_type))
1718c2ecf20Sopenharmony_ci				vma->vm_page_prot =
1728c2ecf20Sopenharmony_ci					t4_pgprot_wc(vma->vm_page_prot);
1738c2ecf20Sopenharmony_ci			else
1748c2ecf20Sopenharmony_ci				vma->vm_page_prot =
1758c2ecf20Sopenharmony_ci					pgprot_noncached(vma->vm_page_prot);
1768c2ecf20Sopenharmony_ci		}
1778c2ecf20Sopenharmony_ci		ret = io_remap_pfn_range(vma, vma->vm_start,
1788c2ecf20Sopenharmony_ci					 addr >> PAGE_SHIFT,
1798c2ecf20Sopenharmony_ci					 len, vma->vm_page_prot);
1808c2ecf20Sopenharmony_ci	} else {
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci		/*
1838c2ecf20Sopenharmony_ci		 * Map WQ or CQ contig dma memory...
1848c2ecf20Sopenharmony_ci		 */
1858c2ecf20Sopenharmony_ci		ret = remap_pfn_range(vma, vma->vm_start,
1868c2ecf20Sopenharmony_ci				      addr >> PAGE_SHIFT,
1878c2ecf20Sopenharmony_ci				      len, vma->vm_page_prot);
1888c2ecf20Sopenharmony_ci	}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	return ret;
1918c2ecf20Sopenharmony_ci}
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_cistatic int c4iw_deallocate_pd(struct ib_pd *pd, struct ib_udata *udata)
1948c2ecf20Sopenharmony_ci{
1958c2ecf20Sopenharmony_ci	struct c4iw_dev *rhp;
1968c2ecf20Sopenharmony_ci	struct c4iw_pd *php;
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	php = to_c4iw_pd(pd);
1998c2ecf20Sopenharmony_ci	rhp = php->rhp;
2008c2ecf20Sopenharmony_ci	pr_debug("ibpd %p pdid 0x%x\n", pd, php->pdid);
2018c2ecf20Sopenharmony_ci	c4iw_put_resource(&rhp->rdev.resource.pdid_table, php->pdid);
2028c2ecf20Sopenharmony_ci	mutex_lock(&rhp->rdev.stats.lock);
2038c2ecf20Sopenharmony_ci	rhp->rdev.stats.pd.cur--;
2048c2ecf20Sopenharmony_ci	mutex_unlock(&rhp->rdev.stats.lock);
2058c2ecf20Sopenharmony_ci	return 0;
2068c2ecf20Sopenharmony_ci}
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_cistatic int c4iw_allocate_pd(struct ib_pd *pd, struct ib_udata *udata)
2098c2ecf20Sopenharmony_ci{
2108c2ecf20Sopenharmony_ci	struct c4iw_pd *php = to_c4iw_pd(pd);
2118c2ecf20Sopenharmony_ci	struct ib_device *ibdev = pd->device;
2128c2ecf20Sopenharmony_ci	u32 pdid;
2138c2ecf20Sopenharmony_ci	struct c4iw_dev *rhp;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	pr_debug("ibdev %p\n", ibdev);
2168c2ecf20Sopenharmony_ci	rhp = (struct c4iw_dev *) ibdev;
2178c2ecf20Sopenharmony_ci	pdid =  c4iw_get_resource(&rhp->rdev.resource.pdid_table);
2188c2ecf20Sopenharmony_ci	if (!pdid)
2198c2ecf20Sopenharmony_ci		return -EINVAL;
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	php->pdid = pdid;
2228c2ecf20Sopenharmony_ci	php->rhp = rhp;
2238c2ecf20Sopenharmony_ci	if (udata) {
2248c2ecf20Sopenharmony_ci		struct c4iw_alloc_pd_resp uresp = {.pdid = php->pdid};
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci		if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
2278c2ecf20Sopenharmony_ci			c4iw_deallocate_pd(&php->ibpd, udata);
2288c2ecf20Sopenharmony_ci			return -EFAULT;
2298c2ecf20Sopenharmony_ci		}
2308c2ecf20Sopenharmony_ci	}
2318c2ecf20Sopenharmony_ci	mutex_lock(&rhp->rdev.stats.lock);
2328c2ecf20Sopenharmony_ci	rhp->rdev.stats.pd.cur++;
2338c2ecf20Sopenharmony_ci	if (rhp->rdev.stats.pd.cur > rhp->rdev.stats.pd.max)
2348c2ecf20Sopenharmony_ci		rhp->rdev.stats.pd.max = rhp->rdev.stats.pd.cur;
2358c2ecf20Sopenharmony_ci	mutex_unlock(&rhp->rdev.stats.lock);
2368c2ecf20Sopenharmony_ci	pr_debug("pdid 0x%0x ptr 0x%p\n", pdid, php);
2378c2ecf20Sopenharmony_ci	return 0;
2388c2ecf20Sopenharmony_ci}
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_cistatic int c4iw_query_gid(struct ib_device *ibdev, u8 port, int index,
2418c2ecf20Sopenharmony_ci			  union ib_gid *gid)
2428c2ecf20Sopenharmony_ci{
2438c2ecf20Sopenharmony_ci	struct c4iw_dev *dev;
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci	pr_debug("ibdev %p, port %d, index %d, gid %p\n",
2468c2ecf20Sopenharmony_ci		 ibdev, port, index, gid);
2478c2ecf20Sopenharmony_ci	if (!port)
2488c2ecf20Sopenharmony_ci		return -EINVAL;
2498c2ecf20Sopenharmony_ci	dev = to_c4iw_dev(ibdev);
2508c2ecf20Sopenharmony_ci	memset(&(gid->raw[0]), 0, sizeof(gid->raw));
2518c2ecf20Sopenharmony_ci	memcpy(&(gid->raw[0]), dev->rdev.lldi.ports[port-1]->dev_addr, 6);
2528c2ecf20Sopenharmony_ci	return 0;
2538c2ecf20Sopenharmony_ci}
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_cistatic int c4iw_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
2568c2ecf20Sopenharmony_ci			     struct ib_udata *uhw)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	struct c4iw_dev *dev;
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	pr_debug("ibdev %p\n", ibdev);
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	if (uhw->inlen || uhw->outlen)
2648c2ecf20Sopenharmony_ci		return -EINVAL;
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	dev = to_c4iw_dev(ibdev);
2678c2ecf20Sopenharmony_ci	memcpy(&props->sys_image_guid, dev->rdev.lldi.ports[0]->dev_addr, 6);
2688c2ecf20Sopenharmony_ci	props->hw_ver = CHELSIO_CHIP_RELEASE(dev->rdev.lldi.adapter_type);
2698c2ecf20Sopenharmony_ci	props->fw_ver = dev->rdev.lldi.fw_vers;
2708c2ecf20Sopenharmony_ci	props->device_cap_flags = dev->device_cap_flags;
2718c2ecf20Sopenharmony_ci	props->page_size_cap = T4_PAGESIZE_MASK;
2728c2ecf20Sopenharmony_ci	props->vendor_id = (u32)dev->rdev.lldi.pdev->vendor;
2738c2ecf20Sopenharmony_ci	props->vendor_part_id = (u32)dev->rdev.lldi.pdev->device;
2748c2ecf20Sopenharmony_ci	props->max_mr_size = T4_MAX_MR_SIZE;
2758c2ecf20Sopenharmony_ci	props->max_qp = dev->rdev.lldi.vr->qp.size / 2;
2768c2ecf20Sopenharmony_ci	props->max_srq = dev->rdev.lldi.vr->srq.size;
2778c2ecf20Sopenharmony_ci	props->max_qp_wr = dev->rdev.hw_queue.t4_max_qp_depth;
2788c2ecf20Sopenharmony_ci	props->max_srq_wr = dev->rdev.hw_queue.t4_max_qp_depth;
2798c2ecf20Sopenharmony_ci	props->max_send_sge = min(T4_MAX_SEND_SGE, T4_MAX_WRITE_SGE);
2808c2ecf20Sopenharmony_ci	props->max_recv_sge = T4_MAX_RECV_SGE;
2818c2ecf20Sopenharmony_ci	props->max_srq_sge = T4_MAX_RECV_SGE;
2828c2ecf20Sopenharmony_ci	props->max_sge_rd = 1;
2838c2ecf20Sopenharmony_ci	props->max_res_rd_atom = dev->rdev.lldi.max_ird_adapter;
2848c2ecf20Sopenharmony_ci	props->max_qp_rd_atom = min(dev->rdev.lldi.max_ordird_qp,
2858c2ecf20Sopenharmony_ci				    c4iw_max_read_depth);
2868c2ecf20Sopenharmony_ci	props->max_qp_init_rd_atom = props->max_qp_rd_atom;
2878c2ecf20Sopenharmony_ci	props->max_cq = dev->rdev.lldi.vr->qp.size;
2888c2ecf20Sopenharmony_ci	props->max_cqe = dev->rdev.hw_queue.t4_max_cq_depth;
2898c2ecf20Sopenharmony_ci	props->max_mr = c4iw_num_stags(&dev->rdev);
2908c2ecf20Sopenharmony_ci	props->max_pd = T4_MAX_NUM_PD;
2918c2ecf20Sopenharmony_ci	props->local_ca_ack_delay = 0;
2928c2ecf20Sopenharmony_ci	props->max_fast_reg_page_list_len =
2938c2ecf20Sopenharmony_ci		t4_max_fr_depth(dev->rdev.lldi.ulptx_memwrite_dsgl && use_dsgl);
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	return 0;
2968c2ecf20Sopenharmony_ci}
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_cistatic int c4iw_query_port(struct ib_device *ibdev, u8 port,
2998c2ecf20Sopenharmony_ci			   struct ib_port_attr *props)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	int ret = 0;
3028c2ecf20Sopenharmony_ci	pr_debug("ibdev %p\n", ibdev);
3038c2ecf20Sopenharmony_ci	ret = ib_get_eth_speed(ibdev, port, &props->active_speed,
3048c2ecf20Sopenharmony_ci			       &props->active_width);
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	props->port_cap_flags =
3078c2ecf20Sopenharmony_ci	    IB_PORT_CM_SUP |
3088c2ecf20Sopenharmony_ci	    IB_PORT_SNMP_TUNNEL_SUP |
3098c2ecf20Sopenharmony_ci	    IB_PORT_REINIT_SUP |
3108c2ecf20Sopenharmony_ci	    IB_PORT_DEVICE_MGMT_SUP |
3118c2ecf20Sopenharmony_ci	    IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
3128c2ecf20Sopenharmony_ci	props->gid_tbl_len = 1;
3138c2ecf20Sopenharmony_ci	props->max_msg_sz = -1;
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	return ret;
3168c2ecf20Sopenharmony_ci}
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_cistatic ssize_t hw_rev_show(struct device *dev,
3198c2ecf20Sopenharmony_ci			   struct device_attribute *attr, char *buf)
3208c2ecf20Sopenharmony_ci{
3218c2ecf20Sopenharmony_ci	struct c4iw_dev *c4iw_dev =
3228c2ecf20Sopenharmony_ci			rdma_device_to_drv_device(dev, struct c4iw_dev, ibdev);
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	pr_debug("dev 0x%p\n", dev);
3258c2ecf20Sopenharmony_ci	return sprintf(buf, "%d\n",
3268c2ecf20Sopenharmony_ci		       CHELSIO_CHIP_RELEASE(c4iw_dev->rdev.lldi.adapter_type));
3278c2ecf20Sopenharmony_ci}
3288c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(hw_rev);
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_cistatic ssize_t hca_type_show(struct device *dev,
3318c2ecf20Sopenharmony_ci			     struct device_attribute *attr, char *buf)
3328c2ecf20Sopenharmony_ci{
3338c2ecf20Sopenharmony_ci	struct c4iw_dev *c4iw_dev =
3348c2ecf20Sopenharmony_ci			rdma_device_to_drv_device(dev, struct c4iw_dev, ibdev);
3358c2ecf20Sopenharmony_ci	struct ethtool_drvinfo info;
3368c2ecf20Sopenharmony_ci	struct net_device *lldev = c4iw_dev->rdev.lldi.ports[0];
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	pr_debug("dev 0x%p\n", dev);
3398c2ecf20Sopenharmony_ci	lldev->ethtool_ops->get_drvinfo(lldev, &info);
3408c2ecf20Sopenharmony_ci	return sprintf(buf, "%s\n", info.driver);
3418c2ecf20Sopenharmony_ci}
3428c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(hca_type);
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_cistatic ssize_t board_id_show(struct device *dev, struct device_attribute *attr,
3458c2ecf20Sopenharmony_ci			     char *buf)
3468c2ecf20Sopenharmony_ci{
3478c2ecf20Sopenharmony_ci	struct c4iw_dev *c4iw_dev =
3488c2ecf20Sopenharmony_ci			rdma_device_to_drv_device(dev, struct c4iw_dev, ibdev);
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci	pr_debug("dev 0x%p\n", dev);
3518c2ecf20Sopenharmony_ci	return sprintf(buf, "%x.%x\n", c4iw_dev->rdev.lldi.pdev->vendor,
3528c2ecf20Sopenharmony_ci		       c4iw_dev->rdev.lldi.pdev->device);
3538c2ecf20Sopenharmony_ci}
3548c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(board_id);
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_cienum counters {
3578c2ecf20Sopenharmony_ci	IP4INSEGS,
3588c2ecf20Sopenharmony_ci	IP4OUTSEGS,
3598c2ecf20Sopenharmony_ci	IP4RETRANSSEGS,
3608c2ecf20Sopenharmony_ci	IP4OUTRSTS,
3618c2ecf20Sopenharmony_ci	IP6INSEGS,
3628c2ecf20Sopenharmony_ci	IP6OUTSEGS,
3638c2ecf20Sopenharmony_ci	IP6RETRANSSEGS,
3648c2ecf20Sopenharmony_ci	IP6OUTRSTS,
3658c2ecf20Sopenharmony_ci	NR_COUNTERS
3668c2ecf20Sopenharmony_ci};
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_cistatic const char * const names[] = {
3698c2ecf20Sopenharmony_ci	[IP4INSEGS] = "ip4InSegs",
3708c2ecf20Sopenharmony_ci	[IP4OUTSEGS] = "ip4OutSegs",
3718c2ecf20Sopenharmony_ci	[IP4RETRANSSEGS] = "ip4RetransSegs",
3728c2ecf20Sopenharmony_ci	[IP4OUTRSTS] = "ip4OutRsts",
3738c2ecf20Sopenharmony_ci	[IP6INSEGS] = "ip6InSegs",
3748c2ecf20Sopenharmony_ci	[IP6OUTSEGS] = "ip6OutSegs",
3758c2ecf20Sopenharmony_ci	[IP6RETRANSSEGS] = "ip6RetransSegs",
3768c2ecf20Sopenharmony_ci	[IP6OUTRSTS] = "ip6OutRsts"
3778c2ecf20Sopenharmony_ci};
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_cistatic struct rdma_hw_stats *c4iw_alloc_stats(struct ib_device *ibdev,
3808c2ecf20Sopenharmony_ci					      u8 port_num)
3818c2ecf20Sopenharmony_ci{
3828c2ecf20Sopenharmony_ci	BUILD_BUG_ON(ARRAY_SIZE(names) != NR_COUNTERS);
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci	if (port_num != 0)
3858c2ecf20Sopenharmony_ci		return NULL;
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci	return rdma_alloc_hw_stats_struct(names, NR_COUNTERS,
3888c2ecf20Sopenharmony_ci					  RDMA_HW_STATS_DEFAULT_LIFESPAN);
3898c2ecf20Sopenharmony_ci}
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_cistatic int c4iw_get_mib(struct ib_device *ibdev,
3928c2ecf20Sopenharmony_ci			struct rdma_hw_stats *stats,
3938c2ecf20Sopenharmony_ci			u8 port, int index)
3948c2ecf20Sopenharmony_ci{
3958c2ecf20Sopenharmony_ci	struct tp_tcp_stats v4, v6;
3968c2ecf20Sopenharmony_ci	struct c4iw_dev *c4iw_dev = to_c4iw_dev(ibdev);
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_ci	cxgb4_get_tcp_stats(c4iw_dev->rdev.lldi.pdev, &v4, &v6);
3998c2ecf20Sopenharmony_ci	stats->value[IP4INSEGS] = v4.tcp_in_segs;
4008c2ecf20Sopenharmony_ci	stats->value[IP4OUTSEGS] = v4.tcp_out_segs;
4018c2ecf20Sopenharmony_ci	stats->value[IP4RETRANSSEGS] = v4.tcp_retrans_segs;
4028c2ecf20Sopenharmony_ci	stats->value[IP4OUTRSTS] = v4.tcp_out_rsts;
4038c2ecf20Sopenharmony_ci	stats->value[IP6INSEGS] = v6.tcp_in_segs;
4048c2ecf20Sopenharmony_ci	stats->value[IP6OUTSEGS] = v6.tcp_out_segs;
4058c2ecf20Sopenharmony_ci	stats->value[IP6RETRANSSEGS] = v6.tcp_retrans_segs;
4068c2ecf20Sopenharmony_ci	stats->value[IP6OUTRSTS] = v6.tcp_out_rsts;
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci	return stats->num_counters;
4098c2ecf20Sopenharmony_ci}
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_cistatic struct attribute *c4iw_class_attributes[] = {
4128c2ecf20Sopenharmony_ci	&dev_attr_hw_rev.attr,
4138c2ecf20Sopenharmony_ci	&dev_attr_hca_type.attr,
4148c2ecf20Sopenharmony_ci	&dev_attr_board_id.attr,
4158c2ecf20Sopenharmony_ci	NULL
4168c2ecf20Sopenharmony_ci};
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_cistatic const struct attribute_group c4iw_attr_group = {
4198c2ecf20Sopenharmony_ci	.attrs = c4iw_class_attributes,
4208c2ecf20Sopenharmony_ci};
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_cistatic int c4iw_port_immutable(struct ib_device *ibdev, u8 port_num,
4238c2ecf20Sopenharmony_ci			       struct ib_port_immutable *immutable)
4248c2ecf20Sopenharmony_ci{
4258c2ecf20Sopenharmony_ci	struct ib_port_attr attr;
4268c2ecf20Sopenharmony_ci	int err;
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci	immutable->core_cap_flags = RDMA_CORE_PORT_IWARP;
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci	err = ib_query_port(ibdev, port_num, &attr);
4318c2ecf20Sopenharmony_ci	if (err)
4328c2ecf20Sopenharmony_ci		return err;
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci	immutable->gid_tbl_len = attr.gid_tbl_len;
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci	return 0;
4378c2ecf20Sopenharmony_ci}
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_cistatic void get_dev_fw_str(struct ib_device *dev, char *str)
4408c2ecf20Sopenharmony_ci{
4418c2ecf20Sopenharmony_ci	struct c4iw_dev *c4iw_dev = container_of(dev, struct c4iw_dev,
4428c2ecf20Sopenharmony_ci						 ibdev);
4438c2ecf20Sopenharmony_ci	pr_debug("dev 0x%p\n", dev);
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci	snprintf(str, IB_FW_VERSION_NAME_MAX, "%u.%u.%u.%u",
4468c2ecf20Sopenharmony_ci		 FW_HDR_FW_VER_MAJOR_G(c4iw_dev->rdev.lldi.fw_vers),
4478c2ecf20Sopenharmony_ci		 FW_HDR_FW_VER_MINOR_G(c4iw_dev->rdev.lldi.fw_vers),
4488c2ecf20Sopenharmony_ci		 FW_HDR_FW_VER_MICRO_G(c4iw_dev->rdev.lldi.fw_vers),
4498c2ecf20Sopenharmony_ci		 FW_HDR_FW_VER_BUILD_G(c4iw_dev->rdev.lldi.fw_vers));
4508c2ecf20Sopenharmony_ci}
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_cistatic const struct ib_device_ops c4iw_dev_ops = {
4538c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
4548c2ecf20Sopenharmony_ci	.driver_id = RDMA_DRIVER_CXGB4,
4558c2ecf20Sopenharmony_ci	.uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION,
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_ci	.alloc_hw_stats = c4iw_alloc_stats,
4588c2ecf20Sopenharmony_ci	.alloc_mr = c4iw_alloc_mr,
4598c2ecf20Sopenharmony_ci	.alloc_mw = c4iw_alloc_mw,
4608c2ecf20Sopenharmony_ci	.alloc_pd = c4iw_allocate_pd,
4618c2ecf20Sopenharmony_ci	.alloc_ucontext = c4iw_alloc_ucontext,
4628c2ecf20Sopenharmony_ci	.create_cq = c4iw_create_cq,
4638c2ecf20Sopenharmony_ci	.create_qp = c4iw_create_qp,
4648c2ecf20Sopenharmony_ci	.create_srq = c4iw_create_srq,
4658c2ecf20Sopenharmony_ci	.dealloc_mw = c4iw_dealloc_mw,
4668c2ecf20Sopenharmony_ci	.dealloc_pd = c4iw_deallocate_pd,
4678c2ecf20Sopenharmony_ci	.dealloc_ucontext = c4iw_dealloc_ucontext,
4688c2ecf20Sopenharmony_ci	.dereg_mr = c4iw_dereg_mr,
4698c2ecf20Sopenharmony_ci	.destroy_cq = c4iw_destroy_cq,
4708c2ecf20Sopenharmony_ci	.destroy_qp = c4iw_destroy_qp,
4718c2ecf20Sopenharmony_ci	.destroy_srq = c4iw_destroy_srq,
4728c2ecf20Sopenharmony_ci	.fill_res_cq_entry = c4iw_fill_res_cq_entry,
4738c2ecf20Sopenharmony_ci	.fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry,
4748c2ecf20Sopenharmony_ci	.fill_res_mr_entry = c4iw_fill_res_mr_entry,
4758c2ecf20Sopenharmony_ci	.get_dev_fw_str = get_dev_fw_str,
4768c2ecf20Sopenharmony_ci	.get_dma_mr = c4iw_get_dma_mr,
4778c2ecf20Sopenharmony_ci	.get_hw_stats = c4iw_get_mib,
4788c2ecf20Sopenharmony_ci	.get_port_immutable = c4iw_port_immutable,
4798c2ecf20Sopenharmony_ci	.iw_accept = c4iw_accept_cr,
4808c2ecf20Sopenharmony_ci	.iw_add_ref = c4iw_qp_add_ref,
4818c2ecf20Sopenharmony_ci	.iw_connect = c4iw_connect,
4828c2ecf20Sopenharmony_ci	.iw_create_listen = c4iw_create_listen,
4838c2ecf20Sopenharmony_ci	.iw_destroy_listen = c4iw_destroy_listen,
4848c2ecf20Sopenharmony_ci	.iw_get_qp = c4iw_get_qp,
4858c2ecf20Sopenharmony_ci	.iw_reject = c4iw_reject_cr,
4868c2ecf20Sopenharmony_ci	.iw_rem_ref = c4iw_qp_rem_ref,
4878c2ecf20Sopenharmony_ci	.map_mr_sg = c4iw_map_mr_sg,
4888c2ecf20Sopenharmony_ci	.mmap = c4iw_mmap,
4898c2ecf20Sopenharmony_ci	.modify_qp = c4iw_ib_modify_qp,
4908c2ecf20Sopenharmony_ci	.modify_srq = c4iw_modify_srq,
4918c2ecf20Sopenharmony_ci	.poll_cq = c4iw_poll_cq,
4928c2ecf20Sopenharmony_ci	.post_recv = c4iw_post_receive,
4938c2ecf20Sopenharmony_ci	.post_send = c4iw_post_send,
4948c2ecf20Sopenharmony_ci	.post_srq_recv = c4iw_post_srq_recv,
4958c2ecf20Sopenharmony_ci	.query_device = c4iw_query_device,
4968c2ecf20Sopenharmony_ci	.query_gid = c4iw_query_gid,
4978c2ecf20Sopenharmony_ci	.query_port = c4iw_query_port,
4988c2ecf20Sopenharmony_ci	.query_qp = c4iw_ib_query_qp,
4998c2ecf20Sopenharmony_ci	.reg_user_mr = c4iw_reg_user_mr,
5008c2ecf20Sopenharmony_ci	.req_notify_cq = c4iw_arm_cq,
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	INIT_RDMA_OBJ_SIZE(ib_cq, c4iw_cq, ibcq),
5038c2ecf20Sopenharmony_ci	INIT_RDMA_OBJ_SIZE(ib_mw, c4iw_mw, ibmw),
5048c2ecf20Sopenharmony_ci	INIT_RDMA_OBJ_SIZE(ib_pd, c4iw_pd, ibpd),
5058c2ecf20Sopenharmony_ci	INIT_RDMA_OBJ_SIZE(ib_srq, c4iw_srq, ibsrq),
5068c2ecf20Sopenharmony_ci	INIT_RDMA_OBJ_SIZE(ib_ucontext, c4iw_ucontext, ibucontext),
5078c2ecf20Sopenharmony_ci};
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_cistatic int set_netdevs(struct ib_device *ib_dev, struct c4iw_rdev *rdev)
5108c2ecf20Sopenharmony_ci{
5118c2ecf20Sopenharmony_ci	int ret;
5128c2ecf20Sopenharmony_ci	int i;
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->lldi.nports; i++) {
5158c2ecf20Sopenharmony_ci		ret = ib_device_set_netdev(ib_dev, rdev->lldi.ports[i],
5168c2ecf20Sopenharmony_ci					   i + 1);
5178c2ecf20Sopenharmony_ci		if (ret)
5188c2ecf20Sopenharmony_ci			return ret;
5198c2ecf20Sopenharmony_ci	}
5208c2ecf20Sopenharmony_ci	return 0;
5218c2ecf20Sopenharmony_ci}
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_civoid c4iw_register_device(struct work_struct *work)
5248c2ecf20Sopenharmony_ci{
5258c2ecf20Sopenharmony_ci	int ret;
5268c2ecf20Sopenharmony_ci	struct uld_ctx *ctx = container_of(work, struct uld_ctx, reg_work);
5278c2ecf20Sopenharmony_ci	struct c4iw_dev *dev = ctx->dev;
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	pr_debug("c4iw_dev %p\n", dev);
5308c2ecf20Sopenharmony_ci	memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid));
5318c2ecf20Sopenharmony_ci	memcpy(&dev->ibdev.node_guid, dev->rdev.lldi.ports[0]->dev_addr, 6);
5328c2ecf20Sopenharmony_ci	dev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW;
5338c2ecf20Sopenharmony_ci	if (fastreg_support)
5348c2ecf20Sopenharmony_ci		dev->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
5358c2ecf20Sopenharmony_ci	dev->ibdev.local_dma_lkey = 0;
5368c2ecf20Sopenharmony_ci	dev->ibdev.uverbs_cmd_mask =
5378c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
5388c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
5398c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
5408c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
5418c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
5428c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_REG_MR) |
5438c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
5448c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
5458c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
5468c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
5478c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) |
5488c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
5498c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
5508c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_QUERY_QP) |
5518c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_POLL_CQ) |
5528c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
5538c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_POST_SEND) |
5548c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_POST_RECV) |
5558c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) |
5568c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) |
5578c2ecf20Sopenharmony_ci	    (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
5588c2ecf20Sopenharmony_ci	dev->ibdev.node_type = RDMA_NODE_RNIC;
5598c2ecf20Sopenharmony_ci	BUILD_BUG_ON(sizeof(C4IW_NODE_DESC) > IB_DEVICE_NODE_DESC_MAX);
5608c2ecf20Sopenharmony_ci	memcpy(dev->ibdev.node_desc, C4IW_NODE_DESC, sizeof(C4IW_NODE_DESC));
5618c2ecf20Sopenharmony_ci	dev->ibdev.phys_port_cnt = dev->rdev.lldi.nports;
5628c2ecf20Sopenharmony_ci	dev->ibdev.num_comp_vectors =  dev->rdev.lldi.nciq;
5638c2ecf20Sopenharmony_ci	dev->ibdev.dev.parent = &dev->rdev.lldi.pdev->dev;
5648c2ecf20Sopenharmony_ci
5658c2ecf20Sopenharmony_ci	memcpy(dev->ibdev.iw_ifname, dev->rdev.lldi.ports[0]->name,
5668c2ecf20Sopenharmony_ci	       sizeof(dev->ibdev.iw_ifname));
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci	rdma_set_device_sysfs_group(&dev->ibdev, &c4iw_attr_group);
5698c2ecf20Sopenharmony_ci	ib_set_device_ops(&dev->ibdev, &c4iw_dev_ops);
5708c2ecf20Sopenharmony_ci	ret = set_netdevs(&dev->ibdev, &dev->rdev);
5718c2ecf20Sopenharmony_ci	if (ret)
5728c2ecf20Sopenharmony_ci		goto err_dealloc_ctx;
5738c2ecf20Sopenharmony_ci	dma_set_max_seg_size(&dev->rdev.lldi.pdev->dev, UINT_MAX);
5748c2ecf20Sopenharmony_ci	ret = ib_register_device(&dev->ibdev, "cxgb4_%d",
5758c2ecf20Sopenharmony_ci				 &dev->rdev.lldi.pdev->dev);
5768c2ecf20Sopenharmony_ci	if (ret)
5778c2ecf20Sopenharmony_ci		goto err_dealloc_ctx;
5788c2ecf20Sopenharmony_ci	return;
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_cierr_dealloc_ctx:
5818c2ecf20Sopenharmony_ci	pr_err("%s - Failed registering iwarp device: %d\n",
5828c2ecf20Sopenharmony_ci	       pci_name(ctx->lldi.pdev), ret);
5838c2ecf20Sopenharmony_ci	c4iw_dealloc(ctx);
5848c2ecf20Sopenharmony_ci	return;
5858c2ecf20Sopenharmony_ci}
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_civoid c4iw_unregister_device(struct c4iw_dev *dev)
5888c2ecf20Sopenharmony_ci{
5898c2ecf20Sopenharmony_ci	pr_debug("c4iw_dev %p\n", dev);
5908c2ecf20Sopenharmony_ci	ib_unregister_device(&dev->ibdev);
5918c2ecf20Sopenharmony_ci	return;
5928c2ecf20Sopenharmony_ci}
593