From patchwork Mon Sep 12 04:49:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adit Ranadive X-Patchwork-Id: 9325715 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 502256048B for ; Mon, 12 Sep 2016 04:52:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 43C1328ACC for ; Mon, 12 Sep 2016 04:52:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 383DB28B06; Mon, 12 Sep 2016 04:52:01 +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=unavailable 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 BC61B28ACC for ; Mon, 12 Sep 2016 04:51:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932712AbcILEvw (ORCPT ); Mon, 12 Sep 2016 00:51:52 -0400 Received: from ex13-edg-ou-001.vmware.com ([208.91.0.189]:38044 "EHLO EX13-EDG-OU-001.vmware.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756474AbcILEuc (ORCPT ); Mon, 12 Sep 2016 00:50:32 -0400 Received: from sc9-mailhost2.vmware.com (10.113.161.72) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Sun, 11 Sep 2016 21:50:17 -0700 Received: from EX13-CAS-005.vmware.com (smtp-inbound.vmware.com [10.113.191.55]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id 8273DB04DB; Sun, 11 Sep 2016 21:50:28 -0700 (PDT) Received: from EX13-CAS-003.vmware.com (10.113.191.53) by EX13-MBX-010.vmware.com (10.113.191.30) with Microsoft SMTP Server (TLS) id 15.0.1156.6; Sun, 11 Sep 2016 21:50:28 -0700 Received: from NAM03-BY2-obe.outbound.protection.outlook.com (10.113.170.11) by EX13-CAS-003.vmware.com (10.113.191.53) with Microsoft SMTP Server (TLS) id 15.0.1156.6 via Frontend Transport; Sun, 11 Sep 2016 21:50:27 -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=D2yjY4Q/i0crnQ4gPpaY58qtFUHiF4Yp7zQ6WzdN/9U=; b=lhLGj4TB6SAc0QpEAu90m6X8SGByvBGtQr9HxlsOAfiLQk3Sij2sSdz1BZCYxaTlPmp2V8DczREI68dcjARIHPDGSPIUOOgMhAShAO0JW9m6F1TGvOAs7J69XGM+Y93VTJO2jj5Ck1rF/hYnkdXF7mb8+EnJE4XHMjh2sKiLn8c= Authentication-Results: redhat.com; dkim=none (message not signed) header.d=none; redhat.com; dmarc=none action=none header.from=vmware.com; Received: from promb-2s-dhcp95-136.eng.vmware.com (208.91.1.34) by BLUPR0501MB836.namprd05.prod.outlook.com (10.141.251.150) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.619.3; Mon, 12 Sep 2016 04:50:25 +0000 From: Adit Ranadive To: , , CC: Adit Ranadive , , , , , , Subject: [PATCH v4 05/16] IB/pvrdma: Add functions for Verbs support Date: Sun, 11 Sep 2016 21:49:15 -0700 Message-ID: <1473655766-31628-6-git-send-email-aditr@vmware.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1473655766-31628-1-git-send-email-aditr@vmware.com> References: <1473655766-31628-1-git-send-email-aditr@vmware.com> MIME-Version: 1.0 X-Originating-IP: [208.91.1.34] X-ClientProxiedBy: BY2PR04CA052.namprd04.prod.outlook.com (10.141.249.170) To BLUPR0501MB836.namprd05.prod.outlook.com (10.141.251.150) X-MS-Office365-Filtering-Correlation-Id: fc3089f0-85e0-4517-4a88-08d3dac85067 X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB836; 2:3RfCakr72yoCoISvwnftZbYXZ2ZDElJTCIrgQq76PH3NXvjvb9+UL3xlUzA824faE3by2yK/0jxQ96mz+5nVtQ99k1rTwUhIFrJAEgucOUyAvL7Ju4bJcOlDveiNoq6BHGXeOyFWN4HQQN1qjZaqTg+pfVlFS6ubOWW8q8StkUw9ICbU0hpebLYryqLpilVy; 3:otiunonNWCzNzNWAFM1i1vH5LAjO9RRbehueHPkrld7Qdrd5YpCs8ubJMPubFESM6h+hEsvVUJuOY6b+X/A7sGLPazR6qL5gRMYNh6pXA/dP8o4UTIt560qJeFAVT2ii X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR0501MB836; X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB836; 25:fyHVj4A3B/gNB62Yk5b0iS7+epApvT6fFey7fhZlu0mpY0mV1DJcBvbi+3ER+H9uCljedX6mHpyyeLGXiV+E61mUmMkFb9y7Wz6Qt0EYf4CnroWF0at6IgGAIm6MeqZ6cUgUsx81lfV7Ti8+0Cqexy5PQwVrCv633kHTGHYe9t6J54tJ4mUiPZhzWyAzPmVo1vXlD5e5aTsqewZcZXKRMeCv9VFjF6eewCxJSpvHDE/UbyeiEo5wJ8Dy8B8J222T3zp4RNgrBMcrwIv2HQgW5+J7ULD3aesAuZ9hAQtqfMlt36O3IC7ic31L/RlXeNVhQ0/iT9BHcWPpBdUPyhSOz98bFPt1O9frmgMVWRw7cZzWvAyWW6qXHnykc69DR0rF7KnU1kZBPvEhpUYopgwgLszfKupTAOHcE77rn1Z9mpjZqx5X9x5SNUj3od29illWX6Urqiqb0hcHx9ECMVJZlyA5ci/WKExqC6oOzZhch+WBlva6ZDp8xnBiO+WQjxwK4T9x7B/EhLqUPJqbBe+VeV2tAGBHoS7HK5i2JcNMVcfbcCz6OQ2eyJ31ejiC11HyBPX61H24wcUTL0lohXJwQxpK42mMjvNVe6mYtcZNDzJ91OXvk8Co8z9+9Ov0kHMG11wV+9Hgnh3+bzP7spdNHNrLr0+t1i8gGMasyr5cGs6WOghdmHkAEw2PvQPRU2Q6O0Q/yfQg/GQ4o6EsrGORv8kv0ibIXzrDOLpETfQL2IYo7+pm+CpqKsOAKBk8uYuzKByPzzaQrcDlyTxrgoNOwlEbmLLdbSq1HG4WvjtcM1SRCD3u9wnDR7LSc7Jaxy6l1xPYk0y3H4NAkDSYzNnlyA== X-LD-Processed: b39138ca-3cee-4b4a-a4d6-cd83d9dd62f0,ExtAddr X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB836; 31:CRE5u/Mg53Yf86PGYE53kTEQ9INktl+j0aYqhaPg0iVwPghoAwCver/LUPybEGHZVzMBJaCpjuGmuY+hFDbGxZxhittJ5VJGGj8LjrP+HnvWQaCS0faxaeKKSigY1u1XB1Ugnr0/gj7H+QSlNAivUzGgs9tcoo/2PWIyYz7pYioDlHMeN8N80eDGE7vDiN9aIpPtLdm29iyPhxnhB1i0pcLNSU3ahkoVfQ7jpvu86ZQ=; 20:RrHJzJ7MsWNrtYlGdpINNTbby/ULlghML45r4orzM/IYcDi/P8bKzsbndjcS/BAPaUPnyIE6Y3jvsZa0/ewKJzRpI1STIbj1hoFpzUKbF/wse7vvrYQQPmaricZd+K8o3md1me9FEMdD/uwnIAFeH9mumzyL7rxC20hOnxWICYRyd+7Z56cUYQ+CxpR1rlYVMAi47nklwYQDSY5eBBnPEY87C8aAl4tpX1g10ura91kyl475mH/xf/MLDYECTsBa3c4JkVFpuBJ2HoTo+Rkr+dy4nR959BqgR++F1JlyFq+J2enpa4JseLAlRC6qrSl7DzsedvUElzNmNywOAr1+S6dEg943s86f8jF8G0b+frPEOpA6qSDMpu9sjCZzZvcFYpgTQa1ZoMT/9kgrTedAa7VxKu8XGCXv1t6dNvoVCOddSkaQ7tExq0e1vH5JvfXGYSfVNL/d5HWn/lBHc0zxn8gCgxlMROKj4+E1LnLkPG9fInm7DloZJaH2Lt0Ko43y X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(61668805478150)(22074186197030); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046); SRVR:BLUPR0501MB836; BCL:0; PCL:0; RULEID:; SRVR:BLUPR0501MB836; X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB836; 4:g2w4uxdqzsrc+E2GDwvIomiq8r5T1pgYCk2ARljjygkiEx+42DNVHOPJ8sa3yPRfjDd1Qy3hVdO0znvKdxjHreUOR6LZamojrtNPpa0ktBRfmNJ3wvhy5U6x5zMSOT32xGMsx55iQ9nHc/Xb2vw2LXqBvUWYc8xcINSU8oEIPY9qG+hZCPPm4jbOrwGXlpXRn2kAfshVcu4vbXTp9OysHYd11CwxrM/aCceZpvDjjiXJzzHjvhGi2gdPZtsvcaAxQ7ZAjcKiJGQAwuhZ1TVj5qorz7Iq5vBuy11bz7PXiOH1bL5vGyl6M+qAfMMX69/kb7oS1BoPfkvOqitF/BzyEFUDNO+Wc9fQVZTmOM8tovlwmqryuxfIFz/OjPwnRGuMCEyF8EI5GQpbNPFAm2pjtAMrrkZEympx6RSafyiS6WYU3nNbceof+7YK81xDtcF9WMkvpDjG+r3uI0baPXj3LXFJkeggCLK65QctNLWUNYqGMumpTHLYNUrKI0RwOa+z X-Forefront-PRVS: 006339698F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(66066001)(107886002)(4001430100002)(5003940100001)(36756003)(47776003)(189998001)(4001450100002)(87386001)(86362001)(5890100001)(48376002)(2201001)(50466002)(2906002)(50226002)(8676002)(81166006)(586003)(4326007)(7846002)(5660300001)(305945005)(42186005)(76176999)(7736002)(50986999)(6116002)(3846002)(15975445007)(4001520100001)(5001770100001)(19580405001)(33646002)(92566002)(19580395003)(2950100001)(77096005)(229853001)(7099028)(5001760100003)(2004002); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR0501MB836; H:promb-2s-dhcp95-136.eng.vmware.com; FPR:; SPF:None; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR0501MB836; 23:kj6CLbW2TFB5XAU1y1sDEYQGbfcFVE6Natde9pCC?= =?us-ascii?Q?jZO1M7uSkxHU/Zf2Oa85Gv9+iRwbiGu5qesM5f1fpV9eEdta8Qqtp4BFIP3e?= =?us-ascii?Q?tPgYtvKQSJa/1yp6rcf5rQLPpecjU6nO/j8UIF0Tr9EHHwv1e7i4CfC72GBj?= =?us-ascii?Q?U8XL0SMdf3+Vv8DZ4+RhTsdOKrA2Wpd0lWLpE/p/5fVduPDKeoRequdMeB/0?= =?us-ascii?Q?g8SQZo5NxBVsphJu/NiZkzG7Z2ptPtWYQPjx+CJGNSsY4hoEFkPmN0IwL0pJ?= =?us-ascii?Q?uy7BuC+/wdPxLO+Ds41EJy8H9sgcC6oib/A35xYtuAANZecQFAqczSRuFx97?= =?us-ascii?Q?kK2Fw5XFg7Q6w/1NN4BnTKMvXkpTHlPeTqXCT8DwtWwTNTlQrnqEhIvvS0uY?= =?us-ascii?Q?arV6TH+FJujmI8DeGO4ZfHJSOkG9qFWF3oX5fw1OzKc5XzvJzV38Ejhy85QL?= =?us-ascii?Q?TmzuKFtoDuq5BdIxbLH6M21hMlOvHWCuxJUcPVWoORoB1sHUIjJzOhrfsgKs?= =?us-ascii?Q?SL15Yx/orWhFaPiduUvKzfI33r7Frzr8SAgM2P9/LSPBNO1JWAqygvYEiE4M?= =?us-ascii?Q?6PZTkdij30VRjrSaYvFcA11XOMs9/c46z5Ru2nqvuz2GM8ohkXzKonloiwI9?= =?us-ascii?Q?EiSXHOSqFMy4/ttGJRzBOwDc81W83XoAexzz3WrXxcdiSXWlJRR5gpf91H2w?= =?us-ascii?Q?kal/M4pwlKMAVewP2sbVKzMz+6jHT9fggOmS0vDX/Oqm8Dl8GwfsDSPs7PVq?= =?us-ascii?Q?mJEj6JyLWLbpcIvCQdy/iiJkedM++TEGPEY9chmPrW0A1FHvWaQs0xfGYLN1?= =?us-ascii?Q?ZEp4uybyDnpOX70twRAtmqVPI1WI5EDSmhJW6/AB0jqMT3mENNzTRhT/tPAN?= =?us-ascii?Q?rpGdTYXAevVumv8DWEOPwKwZm0+C8QQhBivMGNFMxN3zF0/g+illda48u0Lo?= =?us-ascii?Q?Q8B1XqT8iVLVdkLXQ15KnMl+Zvr8r9Ktpt7pwE6InE3KFcm0hhqTdE30GcRn?= =?us-ascii?Q?CSj2O4y/ysFReZrkxMnZML7fEM6QddnDu6O5aqvU5yaDTIMlHceq0NcEN+cf?= =?us-ascii?Q?sCGhKbmqtowVPA4f/k+A4DiukhoAwPbjJ5CGEPInkOfjMPOgWdWAgq2I32VI?= =?us-ascii?Q?Vk40PTwBD+ToFCyfrmTAett83L/42vSQiMHDL2GCTJNCz2RU8PGz7A=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB836; 6:sOsgX+Kj+hMTceCCzcIx/r2c8wMohMKXC6OoKZ/SbctNwn5fkKJ7DfSZ4/1CwKu28oR0yi19MM0FiDcVVS3jPXFC3kMIMssxgW/zAr64z6nYiuyT3MLYDyZqZ2Nc7c1hThE2d+B1F6uf6ItXCM1UEXmrrW5Ub0GbU2P14bmZ9olPT/GC8Qk9DQUbaeZOeN7S61VwsLLqAra0I13VfBL8gxjcKJjZ0e/3pE5/TqO6ifgawlS4fGQY3BP6c4FD0icsmQoHBmssmOLFQJsaM0xuyPDuz7xBMXBcU1QSie/sGeQ=; 5:7+tjdDXF1A4Mgp5iWZFROHTNyboj6A0fFWZTtrWoJ3mdslu/2MmFFDM3ihyiwOLX1NKTm00dOxlyPAVZlWNdQuTDOgPALObE2jL7miAq77pDp5IO0PpaaPWD1hLdZeb+1P6hYbMv+YSad3Ef1A6Ykw==; 24:GUXLIEekmyaRQ23goIbRCkL2PNQVixDM7mxF0TZMabEkX7nWVWI4MXUMlFmQAstb7vgixbmsyp9B19QukL6dYB/UBCiJE5Gofup/f7hNdKc=; 7:ob+2XGgNbDc2ljyTiHNjqIRCMBlHWsmfb4RUsRLk35R95fee/LJYhky5aWyUWLqkykkY/ECEo+/ZdWnKCxGPt4Pwl/TBy7oEnb0WFiNkM80KrKZPgJHXa02p+I37yizT+ohYXQyLlDvwExvZ/aFSoKZc+fi52wgMjCEGrnUYdW+9EHcAr642MrgJBpSw5N9MMGrpP/3dNwbsjDMqFnIrJnQDdPA7T52xP47972wYz1Y9AmpHd0svPmW8ksLe2doY SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BLUPR0501MB836; 20:+LFCd+JDaceIM7jaByi2mm/jKcdWkxDt8MHrTHu2XWWfkONR9vdv8FfkYNNeMD6/cddcLK8B+ajiyLZ6dSqYPFtPnm3Mshumx4gv6wLaWHbcIUovHCh6iJqxCHb1MMxRP5+YCfMbntcVc/uh97ttysUR3cp9yalj8mm1EvvgEK4= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Sep 2016 04:50:25.4523 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR0501MB836 Received-SPF: None (EX13-EDG-OU-001.vmware.com: aditr@vmware.com does not designate permitted sender hosts) 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 --- Changes v3->v4: - Renamed priviledged -> privileged. - Added error numbers for command errors. - Removed unnecessary goto in modify_device. - Moved pd allocation to after command execution. - Removed an incorrect atomic_dec. --- drivers/infiniband/hw/pvrdma/pvrdma_verbs.c | 611 ++++++++++++++++++++++++++++ drivers/infiniband/hw/pvrdma/pvrdma_verbs.h | 108 +++++ 2 files changed, 719 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..3805611 --- /dev/null +++ b/drivers/infiniband/hw/pvrdma/pvrdma_verbs.c @@ -0,0 +1,611 @@ +/* + * 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, &rsp); + if (err < 0) { + dev_warn(&dev->pdev->dev, "could not query port, error: %d\n", + err); + return err; + } else if (rsp.hdr.ack != PVRDMA_CMD_QUERY_PORT_RESP) { + dev_err(&dev->pdev->dev, "unknown response for 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, &rsp); + if (err < 0) { + dev_warn(&to_vdev(ibdev)->pdev->dev, + "could not query pkey, error: %d\n", err); + return err; + } else if (rsp.hdr.ack != PVRDMA_CMD_QUERY_PKEY_RESP) { + dev_err(&to_vdev(ibdev)->pdev->dev, + "unknown response for query 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; + + if (mask & ~(IB_DEVICE_MODIFY_SYS_IMAGE_GUID | + IB_DEVICE_MODIFY_NODE_DESC)) { + dev_warn(&to_vdev(ibdev)->pdev->dev, + "unsupported device modify mask %#x\n", mask); + return -EOPNOTSUPP; + } + + 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; +} + +/** + * 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 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 out; + } + + ret = 0; + +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; + void *ptr; + + 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, &rsp); + if (ret < 0) { + dev_warn(&vdev->pdev->dev, + "could not create ucontext, error: %d\n", ret); + ptr = ERR_PTR(ret); + goto err; + } else if (rsp.hdr.ack != PVRDMA_CMD_CREATE_UC_RESP) { + dev_err(&vdev->pdev->dev, + "unknown response for create ucontext\n"); + ptr = ERR_PTR(-EFAULT); + goto err; + } + + 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; + +err: + pvrdma_uar_free(vdev, &context->uar); + kfree(context); + return ptr; +} + +/** + * 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; + 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, NULL); + if (ret < 0) + dev_warn(&context->dev->pdev->dev, + "destroy ucontext failed, error: %d\n", ret); + + /* Free the UAR even if the device command failed */ + 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; + void *ptr; + + /* Check allowed max pds */ + if (!atomic_add_unless(&dev->num_pds, 1, dev->dsr->caps.max_pd)) + return ERR_PTR(-EINVAL); + + 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, &rsp); + if (ret < 0) { + dev_warn(&dev->pdev->dev, + "failed to allocate protection domain, error: %d\n", + ret); + ptr = ERR_PTR(ret); + goto err; + } else if (resp->hdr.ack != PVRDMA_CMD_CREATE_PD_RESP) { + dev_warn(&dev->pdev->dev, + "unknown response for allocate protection domain\n"); + ptr = ERR_PTR(-EFAULT); + goto err; + } + + pd = kmalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) { + ptr = ERR_PTR(-ENOMEM); + goto err; + } + + pd->privileged = !context; + 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); + return ERR_PTR(-EFAULT); + } + } + + /* u32 pd handle */ + return &pd->ibpd; + +err: + atomic_dec(&dev->num_pds); + return ptr; +} + +/** + * 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, NULL); + if (ret) + dev_warn(&dev->pdev->dev, + "could not dealloc protection domain, error: %d\n", + ret); + + 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, otherwise 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__ */