From patchwork Tue Jul 12 19:36:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adit Ranadive X-Patchwork-Id: 9226083 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AF1ED60868 for ; Tue, 12 Jul 2016 19:38:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9AAEC2756B for ; Tue, 12 Jul 2016 19:38:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8F1CC27C38; Tue, 12 Jul 2016 19:38:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1D2F027F9E for ; Tue, 12 Jul 2016 19:38:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751678AbcGLTh5 (ORCPT ); Tue, 12 Jul 2016 15:37:57 -0400 Received: from smtp-outbound-1.vmware.com ([208.91.2.12]:59073 "EHLO smtp-outbound-1.vmware.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751669AbcGLThz (ORCPT ); Tue, 12 Jul 2016 15:37:55 -0400 Received: from sc9-mailhost3.vmware.com (sc9-mailhost3.vmware.com [10.113.161.73]) by smtp-outbound-1.vmware.com (Postfix) with ESMTP id 9D5F098427; Tue, 12 Jul 2016 12:37:48 -0700 (PDT) Received: from EX13-CAS-006.vmware.com (smtp-inbound.vmware.com [10.113.191.56]) by sc9-mailhost3.vmware.com (Postfix) with ESMTP id 6744440723; Tue, 12 Jul 2016 12:37:49 -0700 (PDT) Received: from EX13-CAS-002.vmware.com (10.113.191.52) by EX13-MBX-016.vmware.com (10.113.191.36) with Microsoft SMTP Server (TLS) id 15.0.1156.6; Tue, 12 Jul 2016 12:37:49 -0700 Received: from NAM01-BY2-obe.outbound.protection.outlook.com (10.113.170.11) by EX13-CAS-002.vmware.com (10.113.191.52) with Microsoft SMTP Server (TLS) id 15.0.1156.6 via Frontend Transport; Tue, 12 Jul 2016 12:37:49 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=onevmw.onmicrosoft.com; s=selector1-vmware-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=uka9QjQhABmz/BfDGpGSoh5tKRt3KhUQXcbpClGnAf4=; b=LsRoE49qrZiRfXvjq2ND3pQwXuNReHjuxwUmEepw0aMTUhdiMmEkVRTyKBjJP8Uky6b7kx+qSC3RgNAfZJFtC3AVz03/XlIk1cl6YU3XR0wzcq+BuoAstLTtQ/AjIjnCWJpgx4SN1jU0FUfSs6gK6Ez5o6aCVfOUkt+BkEf5vhg= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=aditr@vmware.com; Received: from promb-2s-dhcp95-136.eng.vmware.com (208.91.1.34) by BLUPR0501MB834.namprd05.prod.outlook.com (10.141.251.148) with Microsoft SMTP Server (TLS) id 15.1.539.14; Tue, 12 Jul 2016 19:37:42 +0000 From: Adit Ranadive To: , , CC: Adit Ranadive , , , , Subject: [PATCH v2 12/15] IB/pvrdma: Add functions for Verbs support Date: Tue, 12 Jul 2016 12:36:42 -0700 Message-ID: <1468352205-9137-13-git-send-email-aditr@vmware.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1468352205-9137-1-git-send-email-aditr@vmware.com> References: <1468352205-9137-1-git-send-email-aditr@vmware.com> MIME-Version: 1.0 X-Originating-IP: [208.91.1.34] X-ClientProxiedBy: SN1PR10CA0055.namprd10.prod.outlook.com (10.164.10.151) To BLUPR0501MB834.namprd05.prod.outlook.com (10.141.251.148) X-MS-Office365-Filtering-Correlation-Id: bf2a7059-4923-4f6d-ac0c-08d3aa8bfe97 X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB834; 2:/fNqGWGkKAx/Xdj7UW6NgBPtUhhPW5fKyEku88vpCZASy0TzPA3u56QNWHnbLL77ZsNH9CZzOfoJf9tuHlfNoHpFdF2h14q1l55L8OOMuUMYzAFu0KCM15x+BWZsj6Q50CgjgGlW5qIGHYYSNVMkg9m1Vj6O8DBzchSxaO5WqNm5aDy4hUBqOY0notkb1OBI; 3:8UOjC3nCOX3nXZEubp7klcoPehEEKZrXXjEW1eGTHfzq2cjNEgBPTI2d+Uw4VdQoI/koiGpusf7tOi2XDE/a9GmiYmGKXErI/Sy5YReVIJINbK2XYROo2GZL/fVckarJ; 25:gJiiL9JMb7UaSnCimmy/UGpdKBzALlkKshEHoekUf0eaAqpTH5/v1iGfI6+YqD5YTzb+i+7ZH4tiWfiJzQ6k8pyfRkGgo5EpOCgn/uiQB4OvKNHykhrJvY8p3k14Jj0+gRT4T/deAxUa3+ULtyL9+RaynG8+Uy2NCrP/72vl1eFd5HRmQpl4ulVpfulq+WF1WyqTOSiph+DIJLKh8OzKoh3hOSpANKkWHVlbC2jtDXkFEtk3hbv30ZTrRj2dMATPDJ9g9ZqhUJF07vh/LfYua//LACQfnRVV+TkZ08Tr8U/Wa0TghSvDG3kO4MfTLjwQvzzT2/V1UzC2p9Aghn9+5ms3QifrlqfkutzidIUD6f4a+6godHfAbB+EEK+Wl5C2v6XB68n7HmGs5EJG8tywq8vutezaIzd3Q4TvG8J/XpU= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR0501MB834; X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB834; 31:gwYpgyg6FCbTPCTA+HCk+zn8OSlMpJnXTG/5QPx2DBc3wmM/3Ml6IsmnoNovoXWHocTlm+ExY7qQ1SzEqE4ePirTI1YqsgjNK2vdFo5p44LUglhOwi5s4L9r9/wxNmcPiRGq8s3CZ0DVrI2OfFSR2nVooEbMOekNJtSMIFKzh+MStcDxmzwBHWPKKWZeuZm0rYTZ4d2YvM9jYBwJwfDJkg==; 20:eziB2TP6Nse3UwOlCpaLSEOK8TXj7+ikAwF27r8vGR9gumsJ9vmWdkc8QKJyzsVRu7q0QjY6kO43pHiMDxxYmaRds/bhaseq7cjf14azG7BBA1J6OsOZe0jUpj2QG9NvQVQ8mwVInGpdBkkAF6pmZYyLCQl4vsxq++SY+rckXF435IXfQ1kimVhIrjMdFbx3AfTV4LGow2aEEevDIwOKNgUOgJ/eWmeVMvrvGgNhrZuGUMMXrZ9xT3TahLlW3FIZ; 4:vpRUQz44HQLJVbr8//XQ4gWUyZvQdy1IHmiKVmfyW6d0UrGBtrR6CgOKLBB5LWQkMwaop7r1z5MCAhGpff+MSD6/XAPxB43+DwcML9lF2CGcC8nTIGDXHU33Xyvt1CtxWSqJ5vuQSup3eEFiBMJnZ8vnSir51XCNK4trnkAG+0VM67+6WTWweK4F+x0NcDRwsXEresc/uKpQ7EBF8Fn7BslMEN9y8ytLBTiCRFlLv3Jy3eidugujydatDLpXOjlHEM5vvh4gVoBptZZ7BuYjUHAwDpXcQS1U4y3/Ar29Wh/AUIao2mYxiW5+M2TesjTtVNDcXp68CfzvdrkxZNT1jQ07ZKCaKU+BlW/Lk0nO9V3GHhiW5YLp7yn180U77PFS0q3PtzWMJ+EpTe15yoazqANjQZcVSltw4SpiHNDNCE4BhV4svJ8zGhiJ1LfKubrOokr2xCj9+ lVb7Tt3rAPTz/evo5P/i1pR6prUbIFZuV g= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(61668805478150)(22074186197030); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046); SRVR:BLUPR0501MB834; BCL:0; PCL:0; RULEID:; SRVR:BLUPR0501MB834; X-Forefront-PRVS: 0001227049 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(199003)(189002)(305945005)(7736002)(50226002)(86362001)(4326007)(2906002)(42186005)(7846002)(68736007)(33646002)(229853001)(106356001)(50986999)(586003)(3846002)(2201001)(6116002)(15975445007)(97736004)(81166006)(81156014)(48376002)(5890100001)(36756003)(5003940100001)(19580395003)(19580405001)(47776003)(2950100001)(77096005)(66066001)(50466002)(4001450100002)(4001430100002)(101416001)(92566002)(189998001)(76176999)(105586002)(8676002)(107886002)(5001770100001)(7099028)(2004002); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR0501MB834; H:promb-2s-dhcp95-136.eng.vmware.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: vmware.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR0501MB834; 23:y6OR1mx8++ymif+CBgw54hYBkhljR30RHbwgcjAD?= =?us-ascii?Q?vPSq8kVhB2bALbXGM6fInXDhFjhYY5L3ulDVu0F1OkOcSu8xkfDrhQJ/kM6K?= =?us-ascii?Q?Ux3nGEb8ze08iOuINAXoibb/4da5j+GoMOHeabw+krma8yIWLZQ0KsTVcaEp?= =?us-ascii?Q?HlzmTMLtQzJU/6lUfX3cUHixAucmKgEvoMmoJSFOLsCOvAVRPDO4QjHmlr1k?= =?us-ascii?Q?x8nIzzL7Xtq1N34sF/yzKbCFbnQKj27P79SpmFJK+tkHW9MJuycxHwWE0Bwg?= =?us-ascii?Q?LK+njItHFvCLz+8OhFHjF4fnuNRSlz/68n2UBmvFEFKSyNcrU2wYUj/sjnjj?= =?us-ascii?Q?Fi8Ig0YAjri5ZlmmIdxivBmuZmSwl+6ed6nATsCxA9j6U2O3uDGsIDZ93q9C?= =?us-ascii?Q?EAzVOYE2C9gFdB+ows+zu46RbL7a1ZNm4hfAhHf9x/Xk5b52MCr8TMw9UGFg?= =?us-ascii?Q?EeaFORfyvnckB54eADPrsiaEvNdY4Esg3FKoFR/0hNH3nbsp3mVT+Gvx5Rjr?= =?us-ascii?Q?tkz3fn8vhZdYYf4l8RBi5pGxofLF4qbWE9xw8HCAKV8XSCRAQnYyH/5rz4q4?= =?us-ascii?Q?0nRUwaC1gGI7/0fCatLv4V/cBkhvAC5pRG+8k5kvm6rqlAm11U+89C3SGyhr?= =?us-ascii?Q?MO0D43do3uqWAi9loTx6X5f/EjO9+Ga6xCdNXMt/SxvezyFL8pbFvgem5FZb?= =?us-ascii?Q?16WOoadXUFTjc1BmKZgb3U0hGYgvuxaYjedco9X2pgwP/4t8YMa0tHmD3BqR?= =?us-ascii?Q?uz1AemDf/TsYTxqMruIlDIfG1QMHo2NWoo13rxTIvcCtea2bLUbjVXzPX6jd?= =?us-ascii?Q?qmQy+Nl42VsdKybEVU4Bhn4U0STeMALgzekMUFqhDqOUqX/FUeOxSS3ijqsr?= =?us-ascii?Q?NntIl/HMaEFWiR3yQIr0roq/JdcBzfzuLVPc8l7DL8OAi3s47DM/J2Psu9yq?= =?us-ascii?Q?CYXmgZ9xNnZrB2+FbENyWdCB7GwkDTmzcU769BKNmaANrmBg+FO3Z7057UtP?= =?us-ascii?Q?1AGaQKRSJCVEBXV5tGdSeSBs3z1IcCyIrTSGMZRjOLi8W/MIZS067y3oEdSw?= =?us-ascii?Q?62g58rBMIGWjI2eTomEDa4zfhjY2z83Vfoh6xvDBtPLRX+3FyFJWGZuxhTHv?= =?us-ascii?Q?g6dkUUriwdeaG8xh1FsEn3ZZ7B4CfYGtJgxCBwk7HERrTEpVr25egGVoJSww?= =?us-ascii?Q?l1ZNa+qpM9fr0eCyeBndb+LArdTGYVKPcs/aOsE55vVAjDjDrSFWdDmpfOeD?= =?us-ascii?Q?i7+bdXVIcAXy67xVv60=3D?= X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB834; 6:8HsB/n9EnFM0UjVijdDU1bjTk58wovagwrRqGCnxxeGqpjm5Gx4tKBcoznCRxo2ZT0angCrMw7nWI33e9F3RpsLqmGQ/q+ItD5tJAV0ObUyVJuR6O/tpkXpc5GO/BjYDSv+subWVoRNAot43c0r0bqVseBE4t5BD75kM9H37kCE1/7cNCehbXvXXDnc05DFcir5Cc3Nj8k5vx/a1m77OPpdoCkW4ZwXcHCzxoPJJbavY6wfRuNF1y4tIUpa8OG10pc8R5k+UpVGh8RvWwuXHZ7oGjOPjRCpmx4LX5BPh1MM=; 5:fafEJt16nQUh9R1B+zB7dmuwZOSkbusbbLu2v6JhlLzQ6s+I38DgIu/9NiKjEG/ablKnVFPZcSF4QZqfgY5EGzlETk6BZDqw8fSd3sochu0ip7VLif4ps7vg7tNwQV/1TK1y970LAIuCYtsfDta6Pw==; 24:39r+krl1CiOc59cQ87UqcZ4Brxb5S2izTN4bjeDjzSEVJF9KQrlInfvSQelUPu+mkhB8BH1NOQClNjO5/tKTs/lD2UyA2jbiZ4ydWiXcrBM=; 7:PJcrxcHY3AXnFgXeXpdKB6dJ4O3aAECUTpsRpUcHJFnIV5pLVBIK97YsdgKvut/5LBT/vQN2381TbawI5dYdG5qVD3RP+taHyTB+iLHHgmDYJVN7iba10MX++J2dvQHxP/tvJ8Pt3XwCIIlqRxq6tPneltlQCoz42Vbz96JdsTdMVDJIxFGQGxV9UQKKlZQBfs4bXS8IbxYUPqs6N2kDM2iLxc7pzS+n/xsy7DLD2byf1K3Y011yCulaXFG2qqJ4 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB834; 20:kLTSAqdMuK61nHSXi8hRGGifhyyL3vSOV+g9KeOXgcR9Z78wVbfkXX5PKJB0zAZ9wZ89YByzM6jC/Ak2vgcmVFb8gQRuznnkU/pQj5VyYuRZTWy7LlYS7FYwbVgAopq8cNnlSftxNQT6f9gbmrk5stb0L9g6LCnzzN5LquUzZCI= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jul 2016 19:37:42.7002 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR0501MB834 X-OriginatorOrg: vmware.com Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch implements the remaining Verbs functions registered with the core RDMA stack. Reviewed-by: Jorgen Hansen Reviewed-by: George Zhang Reviewed-by: Aditya Sarwade Reviewed-by: Bryan Tan Signed-off-by: Adit Ranadive --- drivers/infiniband/hw/pvrdma/pvrdma_verbs.c | 593 ++++++++++++++++++++++++++++ drivers/infiniband/hw/pvrdma/pvrdma_verbs.h | 108 +++++ 2 files changed, 701 insertions(+) create mode 100644 drivers/infiniband/hw/pvrdma/pvrdma_verbs.c create mode 100644 drivers/infiniband/hw/pvrdma/pvrdma_verbs.h diff --git a/drivers/infiniband/hw/pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/pvrdma/pvrdma_verbs.c new file mode 100644 index 0000000..bfc5f89 --- /dev/null +++ b/drivers/infiniband/hw/pvrdma/pvrdma_verbs.c @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2012-2016 VMware, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of EITHER the GNU General Public License + * version 2 as published by the Free Software Foundation or the BSD + * 2-Clause License. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License version 2 for more details at + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html. + * + * You should have received a copy of the GNU General Public License + * along with this program available in the file COPYING in the main + * directory of this source tree. + * + * The BSD 2-Clause License + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "pvrdma.h" +#include "pvrdma_user.h" + +/** + * pvrdma_query_device - query device + * @ibdev: the device to query + * @props: the device properties + * @uhw: user data + * + * @return: 0 on success, otherwise negative errno + */ +int pvrdma_query_device(struct ib_device *ibdev, + struct ib_device_attr *props, + struct ib_udata *uhw) +{ + struct pvrdma_dev *dev = to_vdev(ibdev); + + if (uhw->inlen || uhw->outlen) + return -EINVAL; + + memset(props, 0, sizeof(*props)); + + props->fw_ver = dev->dsr->caps.fw_ver; + props->sys_image_guid = dev->dsr->caps.sys_image_guid; + props->max_mr_size = dev->dsr->caps.max_mr_size; + props->page_size_cap = dev->dsr->caps.page_size_cap; + props->vendor_id = dev->dsr->caps.vendor_id; + props->vendor_part_id = dev->pdev->device; + props->hw_ver = dev->dsr->caps.hw_ver; + props->max_qp = dev->dsr->caps.max_qp; + props->max_qp_wr = dev->dsr->caps.max_qp_wr; + props->device_cap_flags = dev->dsr->caps.device_cap_flags; + props->max_sge = dev->dsr->caps.max_sge; + props->max_sge_rd = dev->dsr->caps.max_sge_rd; + props->max_cq = dev->dsr->caps.max_cq; + props->max_cqe = dev->dsr->caps.max_cqe; + props->max_mr = dev->dsr->caps.max_mr; + props->max_pd = dev->dsr->caps.max_pd; + props->max_qp_rd_atom = dev->dsr->caps.max_qp_rd_atom; + props->max_ee_rd_atom = dev->dsr->caps.max_ee_rd_atom; + props->max_res_rd_atom = dev->dsr->caps.max_res_rd_atom; + props->max_qp_init_rd_atom = dev->dsr->caps.max_qp_init_rd_atom; + props->max_ee_init_rd_atom = dev->dsr->caps.max_ee_init_rd_atom; + props->atomic_cap = + dev->dsr->caps.atomic_ops & + (PVRDMA_ATOMIC_OP_COMP_SWAP | PVRDMA_ATOMIC_OP_FETCH_ADD) ? + IB_ATOMIC_HCA : IB_ATOMIC_NONE; + props->masked_atomic_cap = props->atomic_cap; + props->max_ee = dev->dsr->caps.max_ee; + props->max_rdd = dev->dsr->caps.max_rdd; + props->max_mw = dev->dsr->caps.max_mw; + props->max_raw_ipv6_qp = dev->dsr->caps.max_raw_ipv6_qp; + props->max_raw_ethy_qp = dev->dsr->caps.max_raw_ethy_qp; + props->max_mcast_grp = dev->dsr->caps.max_mcast_grp; + props->max_mcast_qp_attach = dev->dsr->caps.max_mcast_qp_attach; + props->max_total_mcast_qp_attach = + dev->dsr->caps.max_total_mcast_qp_attach; + props->max_ah = dev->dsr->caps.max_ah; + props->max_fmr = dev->dsr->caps.max_fmr; + props->max_map_per_fmr = dev->dsr->caps.max_map_per_fmr; + props->max_srq = dev->dsr->caps.max_srq; + props->max_srq_wr = dev->dsr->caps.max_srq_wr; + props->max_srq_sge = dev->dsr->caps.max_srq_sge; + props->max_fast_reg_page_list_len = 0; + props->max_pkeys = dev->dsr->caps.max_pkeys; + props->local_ca_ack_delay = dev->dsr->caps.local_ca_ack_delay; + if ((dev->dsr->caps.bmme_flags & PVRDMA_BMME_FLAG_LOCAL_INV) && + (dev->dsr->caps.bmme_flags & PVRDMA_BMME_FLAG_REMOTE_INV) && + (dev->dsr->caps.bmme_flags & PVRDMA_BMME_FLAG_FAST_REG_WR)) { + props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; + } + + return 0; +} + +/** + * pvrdma_query_port - query device port attributes + * @ibdev: the device to query + * @port: the port number + * @props: the device properties + * + * @return: 0 on success, otherwise negative errno + */ +int pvrdma_query_port(struct ib_device *ibdev, u8 port, + struct ib_port_attr *props) +{ + struct pvrdma_dev *dev = to_vdev(ibdev); + union pvrdma_cmd_req req; + union pvrdma_cmd_resp rsp; + struct pvrdma_cmd_query_port *cmd = &req.query_port; + struct pvrdma_cmd_query_port_resp *resp = &rsp.query_port_resp; + int err; + + memset(cmd, 0, sizeof(*cmd)); + cmd->hdr.cmd = PVRDMA_CMD_QUERY_PORT; + cmd->port_num = port; + + err = pvrdma_cmd_post(dev, &req, true, &rsp); + if (err < 0 || rsp.hdr.ack != PVRDMA_CMD_QUERY_PORT_RESP) { + dev_warn(&dev->pdev->dev, "could not query port\n"); + return -EFAULT; + } + + memset(props, 0, sizeof(*props)); + + props->state = pvrdma_port_state_to_ib(resp->attrs.state); + props->max_mtu = pvrdma_mtu_to_ib(resp->attrs.max_mtu); + props->active_mtu = pvrdma_mtu_to_ib(resp->attrs.active_mtu); + props->gid_tbl_len = resp->attrs.gid_tbl_len; + props->port_cap_flags = + pvrdma_port_cap_flags_to_ib(resp->attrs.port_cap_flags); + props->max_msg_sz = resp->attrs.max_msg_sz; + props->bad_pkey_cntr = resp->attrs.bad_pkey_cntr; + props->qkey_viol_cntr = resp->attrs.qkey_viol_cntr; + props->pkey_tbl_len = resp->attrs.pkey_tbl_len; + props->lid = resp->attrs.lid; + props->sm_lid = resp->attrs.sm_lid; + props->lmc = resp->attrs.lmc; + props->max_vl_num = resp->attrs.max_vl_num; + props->sm_sl = resp->attrs.sm_sl; + props->subnet_timeout = resp->attrs.subnet_timeout; + props->init_type_reply = resp->attrs.init_type_reply; + props->active_width = pvrdma_port_width_to_ib(resp->attrs.active_width); + props->active_speed = pvrdma_port_speed_to_ib(resp->attrs.active_speed); + props->phys_state = resp->attrs.phys_state; + + return 0; +} + +/** + * pvrdma_query_gid - query device gid + * @ibdev: the device to query + * @port: the port number + * @index: the index + * @gid: the device gid value + * + * @return: 0 on success, otherwise negative errno + */ +int pvrdma_query_gid(struct ib_device *ibdev, u8 port, int index, + union ib_gid *gid) +{ + struct pvrdma_dev *dev = to_vdev(ibdev); + + if (index >= dev->dsr->caps.gid_tbl_len) + return -EINVAL; + + memcpy(gid, &dev->sgid_tbl[index], sizeof(union ib_gid)); + + return 0; +} + +/** + * pvrdma_query_pkey - query device port's P_Key table + * @ibdev: the device to query + * @port: the port number + * @index: the index + * @pkey: the device P_Key value + * + * @return: 0 on success, otherwise negative errno + */ +int pvrdma_query_pkey(struct ib_device *ibdev, u8 port, u16 index, + u16 *pkey) +{ + int err = 0; + union pvrdma_cmd_req req; + union pvrdma_cmd_resp rsp; + struct pvrdma_cmd_query_pkey *cmd = &req.query_pkey; + + memset(cmd, 0, sizeof(*cmd)); + cmd->hdr.cmd = PVRDMA_CMD_QUERY_PKEY; + cmd->port_num = port; + cmd->index = index; + + err = pvrdma_cmd_post(to_vdev(ibdev), &req, true, &rsp); + if (err < 0 || rsp.hdr.ack != PVRDMA_CMD_QUERY_PKEY_RESP) { + struct pvrdma_dev *dev = to_vdev(ibdev); + + dev_warn(&dev->pdev->dev, "could not query device pkey\n"); + return -EFAULT; + } + + *pkey = rsp.query_pkey_resp.pkey; + + return 0; +} + +enum rdma_link_layer pvrdma_port_link_layer(struct ib_device *ibdev, + u8 port) +{ + return IB_LINK_LAYER_ETHERNET; +} + +int pvrdma_modify_device(struct ib_device *ibdev, int mask, + struct ib_device_modify *props) +{ + unsigned long flags; + int ret; + + if (mask & ~(IB_DEVICE_MODIFY_SYS_IMAGE_GUID | + IB_DEVICE_MODIFY_NODE_DESC)) { + struct pvrdma_dev *dev = to_vdev(ibdev); + + dev_warn(&dev->pdev->dev, "unsupported device modify mask\n"); + ret = -EOPNOTSUPP; + goto err_out; + } + + if (mask & IB_DEVICE_MODIFY_NODE_DESC) { + spin_lock_irqsave(&to_vdev(ibdev)->desc_lock, flags); + memcpy(ibdev->node_desc, props->node_desc, 64); + spin_unlock_irqrestore(&to_vdev(ibdev)->desc_lock, flags); + } + + if (mask & IB_DEVICE_MODIFY_SYS_IMAGE_GUID) { + mutex_lock(&to_vdev(ibdev)->port_mutex); + to_vdev(ibdev)->sys_image_guid = + cpu_to_be64(props->sys_image_guid); + mutex_unlock(&to_vdev(ibdev)->port_mutex); + } + + return 0; + +err_out: + return ret; +} + +/** + * pvrdma_modify_port - modify device port attributes + * @ibdev: the device to modify + * @port: the port number + * @mask: attributes to modify + * @props: the device properties + * + * @return: 0 on success, otherwise negative errno + */ +int pvrdma_modify_port(struct ib_device *ibdev, u8 port, int mask, + struct ib_port_modify *props) +{ + struct ib_port_attr attr; + struct pvrdma_dev *vdev = to_vdev(ibdev); + int ret; + + mutex_lock(&vdev->port_mutex); + ret = pvrdma_query_port(ibdev, port, &attr); + if (ret) + goto err_out; + + vdev->port_cap_mask |= props->set_port_cap_mask; + vdev->port_cap_mask &= ~props->clr_port_cap_mask; + + if (mask & IB_PORT_SHUTDOWN) + vdev->ib_active = false; + + if (mask & (IB_PORT_INIT_TYPE | IB_PORT_RESET_QKEY_CNTR)) { + ret = -EOPNOTSUPP; + goto err_out; + } + + ret = 0; + +err_out: + mutex_unlock(&vdev->port_mutex); + return ret; +} + +/** + * pvrdma_alloc_ucontext - allocate ucontext + * @ibdev: the IB device + * @udata: user data + * + * @return: the ib_ucontext pointer on success, otherwise errno. + */ +struct ib_ucontext *pvrdma_alloc_ucontext(struct ib_device *ibdev, + struct ib_udata *udata) +{ + struct pvrdma_dev *vdev = to_vdev(ibdev); + struct pvrdma_ucontext *context; + union pvrdma_cmd_req req; + union pvrdma_cmd_resp rsp; + struct pvrdma_cmd_create_uc *cmd = &req.create_uc; + struct pvrdma_cmd_create_uc_resp *resp = &rsp.create_uc_resp; + struct pvrdma_alloc_ucontext_resp uresp; + int ret; + + if (!vdev->ib_active) + return ERR_PTR(-EAGAIN); + + context = kmalloc(sizeof(*context), GFP_KERNEL); + if (!context) + return ERR_PTR(-ENOMEM); + + context->dev = vdev; + ret = pvrdma_uar_alloc(vdev, &context->uar); + if (ret) { + kfree(context); + return ERR_PTR(-ENOMEM); + } + + /* get ctx_handle from host */ + memset(cmd, 0, sizeof(*cmd)); + cmd->pfn = context->uar.pfn; + cmd->hdr.cmd = PVRDMA_CMD_CREATE_UC; + ret = pvrdma_cmd_post(vdev, &req, true, &rsp); + if (ret < 0 || rsp.hdr.ack != PVRDMA_CMD_CREATE_UC_RESP) { + struct pvrdma_dev *dev = to_vdev(ibdev); + + dev_warn(&dev->pdev->dev, "could not create ucontext\n"); + pvrdma_uar_free(vdev, &context->uar); + kfree(context); + return ERR_PTR(-EFAULT); + } + + context->ctx_handle = resp->ctx_handle; + + /* copy back to user */ + uresp.qp_tab_size = vdev->dsr->caps.max_qp; + ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); + if (ret) { + pvrdma_uar_free(vdev, &context->uar); + context->ibucontext.device = ibdev; + pvrdma_dealloc_ucontext(&context->ibucontext); + return ERR_PTR(-EFAULT); + } + + return &context->ibucontext; +} + +/** + * pvrdma_dealloc_ucontext - deallocate ucontext + * @ibcontext: the ucontext + * + * @return: 0 on success, otherwise errno. + */ +int pvrdma_dealloc_ucontext(struct ib_ucontext *ibcontext) +{ + struct pvrdma_ucontext *context = to_vucontext(ibcontext); + union pvrdma_cmd_req req; + union pvrdma_cmd_resp rsp; + struct pvrdma_cmd_destroy_uc *cmd = &req.destroy_uc; + int ret; + + memset(cmd, 0, sizeof(*cmd)); + cmd->hdr.cmd = PVRDMA_CMD_DESTROY_UC; + cmd->ctx_handle = context->ctx_handle; + + ret = pvrdma_cmd_post(context->dev, &req, false, &rsp); + if (ret < 0) { + dev_warn(&context->dev->pdev->dev, + "destroy ucontext failed\n"); + /* Just do it */ + } + pvrdma_uar_free(to_vdev(ibcontext->device), &context->uar); + kfree(context); + + return ret; +} + +/** + * pvrdma_mmap - create mmap region + * @ibcontext: the user context + * @vma: the VMA + * + * @return: 0 on success, otherwise errno. + */ +int pvrdma_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma) +{ + struct pvrdma_ucontext *context = to_vucontext(ibcontext); + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + + dev_dbg(&context->dev->pdev->dev, "create mmap region\n"); + + if ((size != PAGE_SIZE) || (offset & ~PAGE_MASK)) { + dev_warn(&context->dev->pdev->dev, + "invalid params for mmap region\n"); + return -EINVAL; + } + + /* Map UAR to kernel space, VM_LOCKED? */ + vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + if (io_remap_pfn_range(vma, start, context->uar.pfn, size, + vma->vm_page_prot)) + return -EAGAIN; + + return 0; +} + +/** + * pvrdma_alloc_pd - allocate protection domain + * @ibdev: the IB device + * @context: user context + * @udata: user data + * + * @return: the ib_pd protection domain pointer on success, otherwise errno. + */ +struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev, + struct ib_ucontext *context, + struct ib_udata *udata) +{ + struct pvrdma_pd *pd; + struct pvrdma_dev *dev = to_vdev(ibdev); + union pvrdma_cmd_req req; + union pvrdma_cmd_resp rsp; + struct pvrdma_cmd_create_pd *cmd = &req.create_pd; + struct pvrdma_cmd_create_pd_resp *resp = &rsp.create_pd_resp; + int ret; + + /* Check allowed max pds */ + if (!atomic_add_unless(&dev->num_pds, 1, dev->dsr->caps.max_pd)) + return ERR_PTR(-EINVAL); + + pd = kmalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) { + atomic_dec(&dev->num_pds); + return ERR_PTR(-ENOMEM); + } + + pd->priviledged = !context; + + memset(cmd, 0, sizeof(*cmd)); + cmd->hdr.cmd = PVRDMA_CMD_CREATE_PD; + cmd->ctx_handle = (context) ? to_vucontext(context)->ctx_handle : 0; + ret = pvrdma_cmd_post(dev, &req, true, &rsp); + if (ret < 0 || resp->hdr.ack != PVRDMA_CMD_CREATE_PD_RESP) { + dev_warn(&dev->pdev->dev, + "failed to allocate protection domain\n"); + kfree(pd); + atomic_dec(&dev->num_pds); + return ERR_PTR(-EFAULT); + } + + pd->pd_handle = resp->pd_handle; + pd->pdn = resp->pd_handle; + + if (context) { + if (ib_copy_to_udata(udata, &pd->pdn, sizeof(__u32))) { + dev_warn(&dev->pdev->dev, + "failed to copy back protection domain\n"); + pvrdma_dealloc_pd(&pd->ibpd); + atomic_dec(&dev->num_pds); + return ERR_PTR(-EFAULT); + } + } + + /* u32 pd handle */ + return &pd->ibpd; +} + +/** + * pvrdma_dealloc_pd - deallocate protection domain + * @pd: the protection domain to be released + * + * @return: 0 on success, otherwise errno. + */ +int pvrdma_dealloc_pd(struct ib_pd *pd) +{ + struct pvrdma_dev *dev = to_vdev(pd->device); + union pvrdma_cmd_req req; + struct pvrdma_cmd_destroy_pd *cmd = &req.destroy_pd; + int ret; + + memset(cmd, 0, sizeof(*cmd)); + cmd->hdr.cmd = PVRDMA_CMD_DESTROY_PD; + cmd->pd_handle = to_vpd(pd)->pd_handle; + + ret = pvrdma_cmd_post(dev, &req, false, NULL); + if (ret) + dev_warn(&dev->pdev->dev, + "could not dealloc protection domain\n"); + + kfree(to_vpd(pd)); + atomic_dec(&dev->num_pds); + + return 0; +} + +/** + * pvrdma_create_ah - create an address handle + * @pd: the protection domain + * @ah_attr: the attributes of the AH + * + * @return: the ib_ah pointer on success, oterwise errno. + */ +struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) +{ + struct pvrdma_dev *dev = to_vdev(pd->device); + struct pvrdma_ah *ah; + enum rdma_link_layer ll; + + if (!(ah_attr->ah_flags & IB_AH_GRH)) + return ERR_PTR(-EINVAL); + + ll = rdma_port_get_link_layer(pd->device, ah_attr->port_num); + + if (ll != IB_LINK_LAYER_ETHERNET || + rdma_is_multicast_addr((struct in6_addr *)ah_attr->grh.dgid.raw)) + return ERR_PTR(-EINVAL); + + if (!atomic_add_unless(&dev->num_ahs, 1, dev->dsr->caps.max_ah)) + return ERR_PTR(-EINVAL); + + ah = kzalloc(sizeof(*ah), GFP_KERNEL); + if (!ah) { + atomic_dec(&dev->num_ahs); + return ERR_PTR(-ENOMEM); + } + + ah->av.port_pd = to_vpd(pd)->pd_handle | (ah_attr->port_num << 24); + ah->av.src_path_bits = ah_attr->src_path_bits; + ah->av.src_path_bits |= 0x80; + ah->av.gid_index = ah_attr->grh.sgid_index; + ah->av.hop_limit = ah_attr->grh.hop_limit; + ah->av.sl_tclass_flowlabel = (ah_attr->grh.traffic_class << 20) | + ah_attr->grh.flow_label; + memcpy(ah->av.dgid, ah_attr->grh.dgid.raw, 16); + memcpy(ah->av.dmac, ah_attr->dmac, 6); + + ah->ibah.device = pd->device; + ah->ibah.pd = pd; + ah->ibah.uobject = NULL; + + return &ah->ibah; +} + +/** + * pvrdma_destroy_ah - destroy an address handle + * @ah: the address handle to destroyed + * + * @return: 0 on success. + */ +int pvrdma_destroy_ah(struct ib_ah *ah) +{ + struct pvrdma_dev *dev = to_vdev(ah->device); + + kfree(to_vah(ah)); + atomic_dec(&dev->num_ahs); + + return 0; +} diff --git a/drivers/infiniband/hw/pvrdma/pvrdma_verbs.h b/drivers/infiniband/hw/pvrdma/pvrdma_verbs.h new file mode 100644 index 0000000..e52fbe5 --- /dev/null +++ b/drivers/infiniband/hw/pvrdma/pvrdma_verbs.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012-2016 VMware, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of EITHER the GNU General Public License + * version 2 as published by the Free Software Foundation or the BSD + * 2-Clause License. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License version 2 for more details at + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html. + * + * You should have received a copy of the GNU General Public License + * along with this program available in the file COPYING in the main + * directory of this source tree. + * + * The BSD 2-Clause License + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PVRDMA_VERBS_H__ +#define __PVRDMA_VERBS_H__ + +int pvrdma_query_device(struct ib_device *ibdev, + struct ib_device_attr *props, + struct ib_udata *udata); +int pvrdma_query_port(struct ib_device *ibdev, u8 port, + struct ib_port_attr *props); +int pvrdma_query_gid(struct ib_device *ibdev, u8 port, + int index, union ib_gid *gid); +int pvrdma_query_pkey(struct ib_device *ibdev, u8 port, + u16 index, u16 *pkey); +enum rdma_link_layer pvrdma_port_link_layer(struct ib_device *ibdev, + u8 port); +int pvrdma_modify_device(struct ib_device *ibdev, int mask, + struct ib_device_modify *props); +int pvrdma_modify_port(struct ib_device *ibdev, u8 port, + int mask, struct ib_port_modify *props); +int pvrdma_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); +struct ib_ucontext *pvrdma_alloc_ucontext(struct ib_device *ibdev, + struct ib_udata *udata); +int pvrdma_dealloc_ucontext(struct ib_ucontext *context); +struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev, + struct ib_ucontext *context, + struct ib_udata *udata); +int pvrdma_dealloc_pd(struct ib_pd *ibpd); +struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc); +struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, + u64 virt_addr, int access_flags, + struct ib_udata *udata); +int pvrdma_dereg_mr(struct ib_mr *mr); +struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, + u32 max_num_sg); +int pvrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, + int sg_nents, unsigned int *sg_offset); +int pvrdma_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period); +int pvrdma_resize_cq(struct ib_cq *ibcq, int entries, + struct ib_udata *udata); +struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev, + const struct ib_cq_init_attr *attr, + struct ib_ucontext *context, + struct ib_udata *udata); +int pvrdma_resize_cq(struct ib_cq *ibcq, int entries, + struct ib_udata *udata); +int pvrdma_destroy_cq(struct ib_cq *cq); +int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc); +int pvrdma_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags); +struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr); +int pvrdma_destroy_ah(struct ib_ah *ah); +struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); +int pvrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + int attr_mask, struct ib_udata *udata); +int pvrdma_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, + int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr); +int pvrdma_destroy_qp(struct ib_qp *qp); +int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, + struct ib_send_wr **bad_wr); +int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, + struct ib_recv_wr **bad_wr); + +#endif /* __PVRDMA_VERBS_H__ */