From patchwork Wed Jul 26 11:41:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kalderon, Michal" X-Patchwork-Id: 9864621 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 8D8046038C for ; Wed, 26 Jul 2017 11:43:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 938B028634 for ; Wed, 26 Jul 2017 11:43:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 87CE828745; Wed, 26 Jul 2017 11:43:31 +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 0B1BA2866A for ; Wed, 26 Jul 2017 11:43:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751460AbdGZLn3 (ORCPT ); Wed, 26 Jul 2017 07:43:29 -0400 Received: from mail-sn1nam02on0058.outbound.protection.outlook.com ([104.47.36.58]:64512 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751413AbdGZLn1 (ORCPT ); Wed, 26 Jul 2017 07:43:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=D+7jvZq0/LxgAJCy7QQH5taEyjSV20cFcJN6DeFvzJc=; b=RPLKEfY1D3EZqAhZprJNRzrX7zoqW69kRIaNMKdALO/CbgJhdZAYa9FKl9pWSTRQqlXHamMX1WxfvSVeZDjwyNK4n7pTrRrkV8IIG1LTPVOUNWRslIldpzsvzNN5UFYIvaL7wtPyzaFqV6Q7JO9aDwmtuNGg7PsJv0OJlEnzGJA= Received: from DM5PR07CA0047.namprd07.prod.outlook.com (2603:10b6:3:16::33) by BL2PR07MB2436.namprd07.prod.outlook.com (2a01:111:e400:c754::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1282.10; Wed, 26 Jul 2017 11:43:24 +0000 Received: from BY2FFO11OLC002.protection.gbl (2a01:111:f400:7c0c::193) by DM5PR07CA0047.outlook.office365.com (2603:10b6:3:16::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1282.10 via Frontend Transport; Wed, 26 Jul 2017 11:43:24 +0000 Authentication-Results: spf=none (sender IP is 50.232.66.26) smtp.mailfrom=cavium.com; redhat.com; dkim=none (message not signed) header.d=none; redhat.com; dmarc=none action=none header.from=cavium.com; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) Received: from CAEXCH02.caveonetworks.com (50.232.66.26) by BY2FFO11OLC002.mail.protection.outlook.com (10.1.15.178) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.1240.9 via Frontend Transport; Wed, 26 Jul 2017 11:43:24 +0000 Received: from lb-tlvb-michal.il.qlogic.com.com (10.185.6.89) by CAEXCH02.caveonetworks.com (10.17.4.29) with Microsoft SMTP Server id 14.2.347.0; Wed, 26 Jul 2017 04:43:21 -0700 From: Michal Kalderon To: , , CC: , Michal Kalderon , Ram Amrani , Ariel Elior Subject: [PATCH for-next 7/8] RDMA/qedr: Add iWARP connection management functions Date: Wed, 26 Jul 2017 14:41:56 +0300 Message-ID: <1501069317-16601-8-git-send-email-Michal.Kalderon@cavium.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1501069317-16601-1-git-send-email-Michal.Kalderon@cavium.com> References: <1501069317-16601-1-git-send-email-Michal.Kalderon@cavium.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:50.232.66.26; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(39840400002)(39450400003)(39400400002)(39850400002)(39410400002)(2980300002)(428002)(189002)(199003)(45914002)(54906002)(105586002)(8676002)(50986999)(8936002)(81156014)(2906002)(76176999)(305945005)(356003)(50226002)(81166006)(48376002)(104016004)(50466002)(86362001)(189998001)(2950100002)(72206003)(106466001)(5660300001)(47776003)(36756003)(69596002)(4326008)(5003940100001)(101416001)(77096006)(6666003)(478600001)(38730400002)(107886003)(626005)(2201001); DIR:OUT; SFP:1101; SCL:1; SRVR:BL2PR07MB2436; H:CAEXCH02.caveonetworks.com; FPR:; SPF:None; PTR:50-232-66-26-static.hfc.comcastbusiness.net; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11OLC002; 1:BXkDUPEMFG8Lh+KqU+dMJKbOYoC9yMnUyx3UqyxoJXwq8t6TRh9YZi0Q69BTfGCHLW7mMddKofApSuZa39lqcuS0tNLrCL08EbPE0F0CEhv9VkEoPHRYVK7x6K5jObQS3FXSOEBey00a/7w0FgQ/krNZHKrfB4cTkxBQsqWQ+NqMCtqEPYEo/CFFmORfLZ5qa4pDrW1F75elzDvzuNhzY6A/t+c2MBw2sESJ/koXq4q1cX06f5nrkPtAgHe0Zk0I22qJt7AWiINrV9rV6chFFqMPt3ZFy+y23EeMz71wsYYlAxI6urHh4oCllw/YQ+1TqfEjJhwV3gjp2p06qeFCpUYa4idsgEeSKzKosARDvxJcQCK5vS3XMnVDnkAiwULLYVM8z+ZEnQEXniqy8jCiaLLQHALR4HromX+b4Ywr5zS2Iydl3B37fcv9X18C3DkOsXWZUcKeBUdx/BuWMXtONd0unGPCpUMKBSwxoY1ylS/RGQQ7ae8yHmqy95EE+JKShPHGzLf9cdbV14nMoONI6ceywusZtBZpUnNDbZLYrlBWynutVgMJ76wFGOuIzuXzOVejJuNkCR7vne56N/xhMx430aHZKdrHtEtXqhmSXm6hEv6jQzAofU+PHn5x1s70g2lO3QcgeivEsp6+vEXSswit1/mgE6gE/6O4beFyohInP885Wokv6+y0+95o7XjwrYKZtxJLu2dbp/mzOg4mPMLT4mqbYsH/Cyt5Fm/Nyfw0JffZRcPa6pqwXtjx1njSZkagj9z7/Ino3ReRWxscdIbmfeW4BQ+dotWM4qIv0CtF1PYGfpx7wG+KWiGBldFpaNhtTBS9ve0zKdLHbcRtMA== X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c7495650-030f-4f36-9ee9-08d4d41b8642 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254075)(300000503095)(300135400095)(2017052603031)(201703131423075)(201703031133081)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:BL2PR07MB2436; X-Microsoft-Exchange-Diagnostics: 1; BL2PR07MB2436; 3:doraTMV0MmjCG8/tejG9msfwyqtT/n3+1vUeK/onpyTu3/ehXT4rdp75cKwN+8MHxXJtpjHJkgaYNzWU9puj2Gc7GaZZdME/DwaK6SHKd2LTLAPpqNbbNt/C1PW2RFWL7RkSvHcpb2gENzYubw7Dhu0WT8W3a7KuxMjjGxEXi9AXAQzooAMtwiruuu9mga5vAdz8fQP9gpy+3UgniEWrWDpRX9ytA/D6TMXKZLIXTsskKOp+pDaifa7pcXAu9blLvu7/1qzAKefvcJZOiRlPZS7p7RG8eLVlH/Zt/39KjWLpqr/xNfzwukMpKgOvSCpvSHYR/fmThoAMnNAPSGc76XdGpQ3sD5PRZBTZ4xVpBazkan23H5NtbwMdCLen3z/y/hK7LmKBaywAp3F9xD9xVahf2KIJcjW0ke5CvY84z8wrqHtqj+tknr4vF+EYpQ9BlQAZhZpBZRU5zji6MHyZdbtqfByoPkQxlYCBuPn3xVErTuuTHb2IPy22QbBP2yiLbTjKDtd6r7L2kzn4DlfDoXU4cXh0nYNe9baLZdHW03ErH1EASMhVeVedDMRinw2DA2jz2F5/qdCshfVNtB9ULMVkLlcdTWZVz+NTh1ZSP9kMuFSrQWf7ijfKtufBc037v01XKAUdpeI4ZgYXuaKKtpO5FxBft3YWIOLf1ScvQb1GwsfivUbeDEWbZGDZoFz2gHRunRVIunOtPFumuIxNtFgoa5D/vhhegiRtv8cfhTZSQlu8v5oeneU+0/+jafCU3ijxKKR+kHuyBEGMG/ySHmuj1Ald3eu0Anjk2y8eI3ODBzyEzGkSM8gAtmJS7cTKxRxe77fy6WA+hH3ko/V51LfwRRbRD8aIZtfVv/SZIMaiHIxQEKejYY1rtDzxTl+4jOR5kccoW0cklDOfrfjIFQ== X-MS-TrafficTypeDiagnostic: BL2PR07MB2436: X-Microsoft-Exchange-Diagnostics: 1; BL2PR07MB2436; 25:TmSj3OLyTLAFXS8KEBnYltc1rIliK5tb4O7oSt1j/FpiPMLePxw6dycZlqVzbhKqkUwCxYWLzn4CigJlvd+dx/2LL8axetywdjtri/kBvy0h+13s6oCcdxLHv64eqgSayD9A4EjG1qKqugy+LvhMnTVnyNVo21nEoy6edSI5o3CWOF2CH/LYV1OqXvjBNYVLPxs5gE2OR38rJ/z6/fYkJ//X0a03YQrEk3HRAfnsPiMH8fmo5QaXgCiTgpvIYxIGbi27HzU3uU2MYa2ErUxHY+bMbpq1LDSjlj0UtbRiJ980S+htH8Xfk58D6q3X2kO7yMwbQZCGmqQxmcS6Ch2HY6t39+Ny7X1kQKSDkw9W7rLeQ7IGGRzR1XUmED81Iw/MrCmZTlV6cTOW5vdMxj6491uIOjTCg2lf3mGAnDrFtxYXOTJ30OHobjAvE/8cZbmSEK7sF3PNolFKw9B1f8oLjsNlYQo+2BY9SHZrHJIzmmib1LsL/vlYgDW1xKx8KBj30wle6I76kYsTZV0UDF1To65or77xGJe6Bx87IGFC0N9Bw3fFN+0HmP0tlN5r3rW4qVFnhyrD+4QrYtf86B9q1XM8ooYkRNxtqv9L5Yi+6KMX0xIPd3bYhU16MlHE8CXPDf+9VTj3eSU7iuEuAd7JS/Fa7tq6LEjtsFHlF9ClVJl6ElqYSYp6dW50VZZ0RnNUa98ThUKXcZR+G1rgwDrnw3Vixzg0WIBvN+B+9a7ZLssfxV6kuc5ljKbJIKQgjE9xfWGrdeGPqDhoihMeCSsG3DmlZffHpfu36EUsvJ0UCFhRFGtwFB626KR2JZpBuqo2BQggSR298eL4RN+JiKvWOurRhfUXv8wwkbbpkAqH20VtKFvKxnoEeieGlBR8Wx12xGNqTAZfy7boKu9WI8j2LjZiDZccx4vsoVYwK6wXd jE= X-Microsoft-Exchange-Diagnostics: 1; BL2PR07MB2436; 31:xvp2MPy4X6zaRmgbQl3gGl/wauSROEv2E75k/mYgsypKkqCa2hbdYbjlYjlUOweaL0dDlqGQBf2ztgg0aNufJiLMr1YmLrRRsaHZtc8IXnEtB8ournl2ct1YJItrJf7fUyarpBQJCe+SGZwdEZovreweBQLJ96siuYVSMCmxdEUoYaEqu+lU+RCFJlDfPEd+4sUHIgjlxvy3cm4RPls/9qa0rZJLDEwC1gX5DrKGEcUyfPTGLT7PwVXnIW6xeyxgfWu5Z2m1jWH1MCAqrxh4NG+tE9UjQA51a1A8n+eR4iy35SzxjZAHaICDYfjqPTkWFX2BE/vhWUSFoKsXMTfOWraaA5QAWVC5EFkvSh0SXFAwmBs8RMhuYQs6+uYOX+pijUz2H6b58kuDngR4ic3OZVtuS1C27zM+vko52G1Me2cmLZkHMna9arlizhcQuhivuFjRiBoDI4NtD56Iw4Dl5OO4o/S5FCqFMC6FzmWv0B568B5XrS0sf5Kigxa2lnDzqTO+INt8HTk/iqSm7dgpNZn5xLPfP3PqGzTgPdP5GSnCU3zfY1aRST4ALe00dByIPWAK6XXB+vMrGZ9bMkfbTX8rNK5AjOHf6aFfyYlnNg2timkq/hyt11OjdamlagK0vQiy7E/IX9LjPJiJN0pGnyk6e6W4BiwlyYGrKLzD0BRH5f4RyBX6bxEa5XIFNy7Ma5jlIcVG0vyfmGRgBeBHmA== X-Microsoft-Exchange-Diagnostics: 1; BL2PR07MB2436; 20:GCJVtOxV7oViRFnS60ipyfPiu03i0p0Q3TpWXKmLuFZ9ibBEMacwyYbRs9v9JD6jqKxgqu8Fj0QK2YNG4Izzo+KWL6gVbRbEGukdFua1yx7lB3AafRcgXuzrH0gnr2i/L/AiS8W2U22pjTMXoahXsY4U2E03cAIleY0+epYaSExNcHiyYjdDGOoR+smaOjyDSn2MFko4qZbESwAgl4yAavW34msPjkupPI+TzaFDYGJUchGS8Ki2NkIcheI67umNYoUOTtE+kgq2PHeYMpEUS4tjtmXxvv9ujZlLlhzAfnahsjNUwlzXSMTvEhMQ6CCi75/51PkWZHOb6mC6weuiU5hIxtFL+cB9GmA3+TTTfd2tE3pe6UMJSr1c7cz2b7wzBZ1omCDqkuxgNBFBdCnyrJCU9ow8gVsK4gaFiAP6/Lwc7eSIB9gxIcF9zRRjAc7w1RtQhKvaIOGhipdsUoQTHOMMy/qMhQYvI7k59J99rC4M2aTass0r30FHROvqSZns X-Exchange-Antispam-Report-Test: UriScan:(21532816269658); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(8121501046)(13016025)(5005006)(13018025)(100000703101)(100105400095)(93006095)(93001095)(3002001)(10201501046)(6041248)(20161123555025)(20161123564025)(20161123562025)(20161123560025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:BL2PR07MB2436; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:BL2PR07MB2436; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BL2PR07MB2436; 4:5PfwvepaKzXTU1l+YADKZwh9uIphncipAK0oUJhqo5?= =?us-ascii?Q?6Bbu3dHlvs/qVRXJO/OPidrnQqLxMi0APCmAS7++LC00sxrv8Rtofb05CVVx?= =?us-ascii?Q?asgrp+TGSs+A9VESDH7ixAuKmWvKX9X5ljp5O1xzS8k7X6zUQu9Ta/TOB+Lz?= =?us-ascii?Q?Pws1Q7tFQzN7CULRJS1mwLCks5HjeZFMipTkEw1KTJzAOQ6Rp3nvBdmf2WX/?= =?us-ascii?Q?HheGk5Tje53mhS3DVIj2jD1AZNwf89J6RYmri6yGlyq+pIyVB+tIPDjR8Su+?= =?us-ascii?Q?dvXdUElpMoy+4ZX1AImsMaAjduqIqUmYEyrzsl+4MpHLUnYjX3zGH8zT0uKw?= =?us-ascii?Q?vpEU5rJuLGh6j7oPZcNCRmwIJsYfXDXVarrCwqMbDXwzKr4vev+PqyHtzzvJ?= =?us-ascii?Q?WBBKzi3nhfa2Na6ZcHw0rcWQcnu9NzHF6DWbc3rDXCub8VOvAi6x4VoU6KCu?= =?us-ascii?Q?KJQhEQ7wPuyQXGR3KTHsD6yTh5m3JI00T0/ch9GXA4cCYTGNb+49MffRVSVg?= =?us-ascii?Q?MQa3IvKT6UreBDMus9on6dpbegQ3Yr/kEUkui+2DbReZitmRSdq+PO0/QWbL?= =?us-ascii?Q?uteemv6OSxS5tjWMb5aRSErQogNGdEIXUeu+AAdfFhUEwc1S3w9iA8I5Kvcs?= =?us-ascii?Q?JtPA7AjDE6wJNH6mkmGTCHJDJoiVLcCxb8AQawruK2SFvyo2UyeJalDZf0DO?= =?us-ascii?Q?yC5QHBkvzd2+a3Vdu+2G+ybMQpkfwuNvZJxDweum3EFbBWZZntA2HXsvGRGb?= =?us-ascii?Q?2IQORZD6hcpmkcQ5PqaHoddIAIgsKdP3Dftmd4F2y39fcssvYXZ9utrVEBbi?= =?us-ascii?Q?abMIhgqZ4e/8V+bfijeUxeV15QxNdh4T/z3umuCTB61hJw+eB3LfeecvSn2z?= =?us-ascii?Q?TcQdTu5kYMSvnl8CZNEi3DdJkXcJ//G0XhoiV+0C2ajed55ndd8bGXUQK+IG?= =?us-ascii?Q?bR9bLXh2bSkVODSXV6ZlZNAnYjfJnG3WxH6FROPHFHByh9dQJrJnuPIXsEb4?= =?us-ascii?Q?dbpM6sSxVUJj/9T+nd1Rh8Mjqa4nyM2zdXB5jVPAcpQ1CeM44MUsT7qHIFzY?= =?us-ascii?Q?xsw3QZD4ALgZx84hOra0M9XrzqNse+gxB3eNTTyA0s/hqVNnJzmahEMwtQcv?= =?us-ascii?Q?p7Rud3Ot1kPng8J5UpIP4SQ38ge9EQxBcZOsmscWOMirItrg38kFgZxsb3TQ?= =?us-ascii?Q?+PZPjVzEiI9cri+VwygP5Hz7Ck9hhTDUFTykegGaTISUJeak8e9l7WXg=3D?= =?us-ascii?Q?=3D?= X-Forefront-PRVS: 038002787A X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BL2PR07MB2436; 23:nxdjocnAU7LV9qNqglbVo2grTQVTyu7tn1d3SwDKQ?= =?us-ascii?Q?EO0kLK0wIQcAlQhV3K07hlAwjxAgKBMONh09tP2+A3a+jVWsKe9L94BXhHo1?= =?us-ascii?Q?2QvU1t/IPxMZDj1quvSO8ck1KJCogdAR2lyFtbyLLOIKJiwioP5GAeYSyIrf?= =?us-ascii?Q?eGEZruf1kuKfgtSu2Z04Oku9eAjmzChv1lIg4hro0llnv6ReoQPfx04w78zJ?= =?us-ascii?Q?URQJhVgn83hMuY9i8hSnzYqM68Lfl5W6SEzGu42/iidF/q7V4mte5bjGYA6I?= =?us-ascii?Q?2tlZcb3yxxRXLekEZmQbYqTOEKxb2IMKOqFOmICJWJpyQp42jw63A86J1mI5?= =?us-ascii?Q?QZaZrL6XWX0uD1EsDhFuOtCinrOf0rXNu3zKWPGXtUvuVuZbbSSUNyNEXzxm?= =?us-ascii?Q?Vkc67pBixJ52Z5s9aOLP51VYOUv1r+XFAZkE5VCmVDOFZjZRouwFIBW3gWZ1?= =?us-ascii?Q?lURu0/0wpPqmRo7T2Ev04th3byQPA2i09mPjYxWmVtk1+KaDEpkTEr8/+ME+?= =?us-ascii?Q?RdwQQNtA4JJ64v7Tc43Wu0YYm4OJ1njF/rMSGAvK2ADrxWiDaKGVuaYJqVM9?= =?us-ascii?Q?CaZSnRd7UyFQqiOKlp7zIuiGAwqPcgGCrZ44E/gmsHZYMD0Wrq+wE+DtUwLO?= =?us-ascii?Q?Bx/oPQRg6EcXOgAZHHjVT+jMtFBsohdh2uOLJWgCEjCrF8lm7Za/AsFhfBW8?= =?us-ascii?Q?X+Fq/+ECl4PZp3GYCgJRnWuHCN9vMX8O68UZcsZZsD2nztzh+KYqI411hEy2?= =?us-ascii?Q?0lNGJKK6XxGwS7SqwjjWyZBCUF9Q60fRXtRuntB9uSuXomEi42HOZcb9c9eN?= =?us-ascii?Q?JRu6aRHwFE4AiY6KsRAh4NPtGBu5ozicZDF9EQwypZWEJ9fKbFx1h4Vb4IDV?= =?us-ascii?Q?wiHr3vXL0EWbrtdDaLoxJi/g/T6GeZSrqNKemIiUF3Wlh1xW34/kEp5f9rZj?= =?us-ascii?Q?CTQIi3lJBCqXhGQ34on61i8ZiwGgVfN9cPIHrDBrdQhTdUkW636xl/FCQv5k?= =?us-ascii?Q?6cAyw/EFdDWEPPJjJxOoOSs0N5N34SVVhWO+31Mz9Hscc5Uhboi0UACD9/Uf?= =?us-ascii?Q?Ib7okOetyEtvvK81HQOqoHTju0R2l53SGaA9yCPmrpgsG3MKtoztt/fBsan1?= =?us-ascii?Q?zFO1RQZ8fc=3D?= X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BL2PR07MB2436; 6:m/q6k7rH4ZDT4pA46nEl8gNYG3Mf4obgfNtUuEqVWh?= =?us-ascii?Q?pmmq+dDILQcZsyQ3T2hyKGTQRAalMrZMd/G+ZqelUaIOIZPTktw27lwsAKRI?= =?us-ascii?Q?atF8akazHH40lspHLsE+x91TJnZPoF1qRL222M8ycB60FiFG7vi5yCip9iBQ?= =?us-ascii?Q?z3NOQP50G8dPteYjz9XhbNCl1OkXqKhXbPf/X5U64/Ku6ZOpqOcjiWdAwTp7?= =?us-ascii?Q?k0OM93ViWVLNd038Hh0GGRwIlh4XIwYhnw0Mc5dnt4dUEmihhPvogfqZ/I4b?= =?us-ascii?Q?ksCrgPslsu9g9BRf0i7TP6AtHhjmihYvVf4PZaTvqmiPgB1Dfh1VvIzlWFWh?= =?us-ascii?Q?CtyNT9lb0a1ntQV7QW5jQLVjgAE6Nr6baJ1l3FTNtVLbOaqcFtggoDf2eklG?= =?us-ascii?Q?0iW8/GlRaCxBxSu5jZspfoAABUpOrzw4glUAiOnLmUf7Aa/PEItHxFR8AjRi?= =?us-ascii?Q?ytWFE/4N1wxxHd6liYoZXkh7DU4WSOyygyxS3c/zNaFgFN1UFg6aYvZYXOwa?= =?us-ascii?Q?y0uybLPzx/VM8Ckvru5GvGG6nck1nd5TzoQ64suvAz2jF5XWMkeS8lxeBxl4?= =?us-ascii?Q?BcbwZZr848Nt8uKN7MCAZ8p5fCVABM535VoS3W/EB76Ap+u9/Trl3xjEucm4?= =?us-ascii?Q?MNBE8qODB7voK0cq12XrBWi9gTBr/hFBJkDZ7iZoSdO6MKCrxnDsDvBn2sBp?= =?us-ascii?Q?/JkO3tIuCgRPbdTdBj7rSOAx6nTwL05yJPaQ+hcuTtGvT6RwRTmfSgscka2e?= =?us-ascii?Q?+nOBqOodiz+/Y0iuqe0eMeQIia+qYMk30knhDTheqX8oLPLMjfMtJkzYGB4S?= =?us-ascii?Q?g+CPVUdfZsTtweU9T/Xo5/EPESagpqdeLHWXqfBbTM/nBqSE1ZVhzH/rfPDb?= =?us-ascii?Q?qielhEyc+zbwpmpRDfX+v/nh254NgfUrCl2lqku42ORiwZm2TOJHphrTdm0D?= =?us-ascii?Q?6JaR2GsSuj95JwGMH20Pn7Ypla2nhnRu1nQ/ekIPAVzLO3c/LmMYXq/+V3q4?= =?us-ascii?Q?g=3D?= X-Microsoft-Exchange-Diagnostics: 1; BL2PR07MB2436; 5:LFx8E3vdoa/T67aDLH2888wpyGGEgbJo0s6FQKTz6t9JMDWXEZTZFLlBH7yADiJ+VmOFtJt+Y1JDa1G/Of9WVVJkHiijWJ6LfNiM5b/3xcA85ADHd+bjyXdOr9bWYsW63jD4h+41S/CNnSPI0T6mRc/NSzNyeLoCwzNacRn/jc7fwev7CwGV/1c+1k4ygAKzyWN4J7cIKF/qlzvWZlXDJYL02ujMgr+hINYUEDh1aN3jY2maQP2EGrNXEq70CvrqD0HgkefZbHIhdt5cORTvEpVZe/cppGoINyhZqBG78EpVWZef9El+iDKth4bQnvU0YcS8TaX2wNthXRZwdcy+m4+TXPS+FpSy7IQ+mcKlyEAY6rUhq6yqoYQAHDGhfC9tMYyl5s5gBBKj52yoRJDPyKEabgrPMx2JrwvEA7/Rhc4Zt2F7wiqCw93bn4/1nAAFmGLqr33/zheGNicHTBgTxeL2iO7zxj1L/MoOerQQDAWYaAlsCfBrJLWwG1+ef848; 24:5O9222swcpCClnmGBl1Zxr7KfMTkVwVwjo3j6F7Q/nnW2RSKjGtCicukPh/Z49EDGzSNEo17xmkg0mCDHqNKz7so0NZgG+MDdEAQIQ0P+AI= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BL2PR07MB2436; 7:mNbBoaXIwdMiAkrNW4Q5biCHMD2D3kUgOvBTlA9FZu9xVFEma4kdYaZOeFDHSKJb37PwR5fKt2P9WFDPiNx8pfEue5BgnuEBcpG2uz7BYHugRTz/LhsWvLC2H6cTmflysXIVqFf28WVGft0F/Q51C3fCPdGp9bO/R2WUJlQYg+xGXd/h6vaF1ajXLJCJnOU8nqPuJBFbVdnNXo518Y6qtvTc4nDNYvf/jc308kNM/fEqOH6LVgZp9o2wOHrbZ/nZ4ys+bilwe8M+RZh7sXLMd1h7DP3yP5AoUCp2XB11N28rVhuw1Cd+gO1iEOswHNdWxkYAvMlvCxqgP1kmsF9jwtsJGR0ilpootWNKwdoOuBQ7UDSnsb7qmHLzdf9Od5VlGbiHCw/dn63m4gfsEdA/eqfRYQVQSTcFFe4nqi+TM3meldecrvLEcnFliJKf9vqWXGsBLWkUt2eEav3CmeAQzPXL/jRvn78SUD5EKv6Y9EhUIwzZ/aNSDlg9MGvAeofpEDU9QLZ6DChKuIILw+OYEdwYnGZJw+NBsAyXQ285mL6sm9ZxyRMDV0o6j5QRwhKGrz7N6rvZJVIlMLrpGBcL4pVjU4xyLFeeyJCbBtbnrSMrU6M5YUDj3xdLAsSh1ZIrq3/BECz46yxLbCYX1SVfklKAgjCInEKkH7a3JPJvT+LhJpcvBUcRCG39VZBWNJeww7Z18aR23X7ijxWYCyl7TFnL6zng9eZz4OhJ5IFaIR6lpRs+QPuYfjOOQPY4wjqT2e+/Ml2fbVFdrBAEaIqjTNWyksroXYbgpDPuPkXAJBo= X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jul 2017 11:43:24.5617 (UTC) X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=711e4ccf-2e9b-4bcf-a551-4094005b6194; Ip=[50.232.66.26]; Helo=[CAEXCH02.caveonetworks.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL2PR07MB2436 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 Implements the iWARP connection management functions: connect, accept, create listener and destroy listener Signed-off-by: Michal Kalderon Signed-off-by: Ram Amrani Signed-off-by: Ariel Elior --- drivers/infiniband/hw/qedr/main.c | 11 + drivers/infiniband/hw/qedr/qedr.h | 22 +- drivers/infiniband/hw/qedr/qedr_iw_cm.c | 689 ++++++++++++++++++++++++++++++++ drivers/infiniband/hw/qedr/qedr_iw_cm.h | 12 + drivers/infiniband/hw/qedr/verbs.c | 17 + 5 files changed, 750 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c index 545cea9..c3c60e1 100644 --- a/drivers/infiniband/hw/qedr/main.c +++ b/drivers/infiniband/hw/qedr/main.c @@ -144,6 +144,12 @@ int qedr_iw_register_device(struct qedr_dev *dev) dev->ibdev.iwcm = kzalloc(sizeof(*dev->ibdev.iwcm), GFP_KERNEL); if (!dev->ibdev.iwcm) return -ENOMEM; + + dev->ibdev.iwcm->connect = qedr_iw_connect; + dev->ibdev.iwcm->accept = qedr_iw_accept; + dev->ibdev.iwcm->reject = qedr_iw_reject; + dev->ibdev.iwcm->create_listen = qedr_iw_create_listen; + dev->ibdev.iwcm->destroy_listen = qedr_iw_destroy_listen; dev->ibdev.iwcm->add_ref = qedr_iw_qp_add_ref; dev->ibdev.iwcm->rem_ref = qedr_iw_qp_rem_ref; dev->ibdev.iwcm->get_qp = qedr_iw_get_qp; @@ -295,6 +301,9 @@ static void qedr_free_resources(struct qedr_dev *dev) { int i; + if (IS_IWARP(dev)) + destroy_workqueue(dev->iwarp_wq); + for (i = 0; i < dev->num_cnq; i++) { qedr_free_mem_sb(dev, &dev->sb_array[i], dev->sb_start + i); dev->ops->common->chain_free(dev->cdev, &dev->cnq_array[i].pbl); @@ -322,6 +331,7 @@ static int qedr_alloc_resources(struct qedr_dev *dev) if (IS_IWARP(dev)) { spin_lock_init(&dev->idr_lock); idr_init(&dev->qpidr); + dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq"); } /* Allocate Status blocks for CNQ */ @@ -799,6 +809,7 @@ static int qedr_init_hw(struct qedr_dev *dev) in_params->events = &events; in_params->cq_mode = QED_RDMA_CQ_MODE_32_BITS; in_params->max_mtu = dev->ndev->mtu; + dev->iwarp_max_mtu = dev->ndev->mtu; ether_addr_copy(&in_params->mac_addr[0], dev->ndev->dev_addr); rc = dev->ops->rdma_init(dev->cdev, in_params); diff --git a/drivers/infiniband/hw/qedr/qedr.h b/drivers/infiniband/hw/qedr/qedr.h index ec361cb..61732ca 100644 --- a/drivers/infiniband/hw/qedr/qedr.h +++ b/drivers/infiniband/hw/qedr/qedr.h @@ -59,6 +59,7 @@ #define QEDR_MSG_SQ " SQ" #define QEDR_MSG_QP " QP" #define QEDR_MSG_GSI " GSI" +#define QEDR_MSG_IWARP " IW" #define QEDR_CQ_MAGIC_NUMBER (0x11223344) @@ -166,6 +167,9 @@ struct qedr_dev { enum qed_rdma_type rdma_type; spinlock_t idr_lock; /* Protect qpidr data-structure */ struct idr qpidr; + struct workqueue_struct *iwarp_wq; + u16 iwarp_max_mtu; + unsigned long enet_state; u8 user_dpm_enabled; @@ -345,7 +349,7 @@ enum qedr_qp_err_bitmap { struct qedr_qp { struct ib_qp ibqp; /* must be first */ struct qedr_dev *dev; - + struct qedr_iw_ep *ep; struct qedr_qp_hwq_info sq; struct qedr_qp_hwq_info rq; @@ -403,6 +407,7 @@ struct qedr_qp { struct qedr_userq usq; struct qedr_userq urq; atomic_t refcnt; + bool destroyed; }; struct qedr_ah { @@ -483,6 +488,21 @@ static inline int qedr_get_dmac(struct qedr_dev *dev, return 0; } +struct qedr_iw_listener { + struct qedr_dev *dev; + struct iw_cm_id *cm_id; + int backlog; + void *qed_handle; +}; + +struct qedr_iw_ep { + struct qedr_dev *dev; + struct iw_cm_id *cm_id; + struct qedr_qp *qp; + void *qed_context; + u8 during_connect; +}; + static inline struct qedr_ucontext *get_qedr_ucontext(struct ib_ucontext *ibucontext) { diff --git a/drivers/infiniband/hw/qedr/qedr_iw_cm.c b/drivers/infiniband/hw/qedr/qedr_iw_cm.c index 8811dbc..fe9b2b6 100644 --- a/drivers/infiniband/hw/qedr/qedr_iw_cm.c +++ b/drivers/infiniband/hw/qedr/qedr_iw_cm.c @@ -29,7 +29,696 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +#include +#include +#include +#include +#include +#include +#include #include "qedr.h" +#include "qedr_iw_cm.h" + +static inline void +qedr_fill_sockaddr4(const struct qed_iwarp_cm_info *cm_info, + struct iw_cm_event *event) +{ + struct sockaddr_in *laddr = (struct sockaddr_in *)&event->local_addr; + struct sockaddr_in *raddr = (struct sockaddr_in *)&event->remote_addr; + + laddr->sin_family = AF_INET; + raddr->sin_family = AF_INET; + + laddr->sin_port = htons(cm_info->local_port); + raddr->sin_port = htons(cm_info->remote_port); + + laddr->sin_addr.s_addr = htonl(cm_info->local_ip[0]); + raddr->sin_addr.s_addr = htonl(cm_info->remote_ip[0]); +} + +static inline void +qedr_fill_sockaddr6(const struct qed_iwarp_cm_info *cm_info, + struct iw_cm_event *event) +{ + struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)&event->local_addr; + struct sockaddr_in6 *raddr6 = + (struct sockaddr_in6 *)&event->remote_addr; + int i; + + laddr6->sin6_family = AF_INET6; + raddr6->sin6_family = AF_INET6; + + laddr6->sin6_port = htons(cm_info->local_port); + raddr6->sin6_port = htons(cm_info->remote_port); + + for (i = 0; i < 4; i++) { + laddr6->sin6_addr.in6_u.u6_addr32[i] = + htonl(cm_info->local_ip[i]); + raddr6->sin6_addr.in6_u.u6_addr32[i] = + htonl(cm_info->remote_ip[i]); + } +} + +void +qedr_iw_mpa_request(void *context, struct qed_iwarp_cm_event_params *params) +{ + struct qedr_iw_listener *listener = (struct qedr_iw_listener *)context; + struct qedr_dev *dev = listener->dev; + struct iw_cm_event event; + struct qedr_iw_ep *ep; + + ep = kzalloc(sizeof(*ep), GFP_ATOMIC); + if (!ep) + return; + + ep->dev = dev; + ep->qed_context = params->ep_context; + + memset(&event, 0, sizeof(event)); + event.event = IW_CM_EVENT_CONNECT_REQUEST; + event.status = params->status; + + if (params->cm_info->ip_version == QED_TCP_IPV4) + qedr_fill_sockaddr4(params->cm_info, &event); + else + qedr_fill_sockaddr6(params->cm_info, &event); + + event.provider_data = (void *)ep; + event.private_data = (void *)params->cm_info->private_data; + event.private_data_len = (u8)params->cm_info->private_data_len; + event.ord = params->cm_info->ord; + event.ird = params->cm_info->ird; + + listener->cm_id->event_handler(listener->cm_id, &event); +} + +void +qedr_iw_issue_event(void *context, + struct qed_iwarp_cm_event_params *params, + enum iw_cm_event_type event_type) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + struct iw_cm_event event; + + memset(&event, 0, sizeof(event)); + event.status = params->status; + event.event = event_type; + + if (params->cm_info) { + event.ird = params->cm_info->ird; + event.ord = params->cm_info->ord; + event.private_data_len = params->cm_info->private_data_len; + event.private_data = (void *)params->cm_info->private_data; + } + + if (ep->cm_id) + ep->cm_id->event_handler(ep->cm_id, &event); +} + +void +qedr_iw_close_event(void *context, struct qed_iwarp_cm_event_params *params) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + + if (ep->cm_id) { + qedr_iw_issue_event(context, params, IW_CM_EVENT_CLOSE); + + ep->cm_id->rem_ref(ep->cm_id); + ep->cm_id = NULL; + } +} + +void +qedr_iw_qp_event(void *context, + struct qed_iwarp_cm_event_params *params, + enum ib_event_type ib_event, char *str) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + struct qedr_dev *dev = ep->dev; + struct ib_qp *ibqp = &ep->qp->ibqp; + struct ib_event event; + + DP_NOTICE(dev, "QP error received: %s\n", str); + + if (ibqp->event_handler) { + event.event = ib_event; + event.device = ibqp->device; + event.element.qp = ibqp; + ibqp->event_handler(&event, ibqp->qp_context); + } +} + +struct qedr_discon_work { + struct work_struct work; + struct qedr_iw_ep *ep; + enum qed_iwarp_event_type event; + int status; +}; + +static void qedr_iw_disconnect_worker(struct work_struct *work) +{ + struct qedr_discon_work *dwork = + container_of(work, struct qedr_discon_work, work); + struct qed_rdma_modify_qp_in_params qp_params = { 0 }; + struct qedr_iw_ep *ep = dwork->ep; + struct qedr_dev *dev = ep->dev; + struct qedr_qp *qp = ep->qp; + struct iw_cm_event event; + + if (qp->destroyed) { + kfree(dwork); + qedr_iw_qp_rem_ref(&qp->ibqp); + return; + } + + memset(&event, 0, sizeof(event)); + event.status = dwork->status; + event.event = IW_CM_EVENT_DISCONNECT; + + /* Success means graceful disconnect was requested. modifying + * to SQD is translated to graceful disconnect. O/w reset is sent + */ + if (dwork->status) + qp_params.new_state = QED_ROCE_QP_STATE_ERR; + else + qp_params.new_state = QED_ROCE_QP_STATE_SQD; + + kfree(dwork); + + if (ep->cm_id) + ep->cm_id->event_handler(ep->cm_id, &event); + + SET_FIELD(qp_params.modify_flags, + QED_RDMA_MODIFY_QP_VALID_NEW_STATE, 1); + + dev->ops->rdma_modify_qp(dev->rdma_ctx, qp->qed_qp, &qp_params); + + qedr_iw_qp_rem_ref(&qp->ibqp); +} + +void +qedr_iw_disconnect_event(void *context, + struct qed_iwarp_cm_event_params *params) +{ + struct qedr_discon_work *work; + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + struct qedr_dev *dev = ep->dev; + struct qedr_qp *qp = ep->qp; + + work = kzalloc(sizeof(*work), GFP_ATOMIC); + if (!work) + return; + + qedr_iw_qp_add_ref(&qp->ibqp); + work->ep = ep; + work->event = params->event; + work->status = params->status; + + INIT_WORK(&work->work, qedr_iw_disconnect_worker); + queue_work(dev->iwarp_wq, &work->work); +} + +static void +qedr_iw_passive_complete(void *context, + struct qed_iwarp_cm_event_params *params) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + struct qedr_dev *dev = ep->dev; + + /* We will only reach the following state if MPA_REJECT was called on + * passive. In this case there will be no associated QP. + */ + if ((params->status == -ECONNREFUSED) && (!ep->qp)) { + DP_DEBUG(dev, QEDR_MSG_IWARP, + "PASSIVE connection refused releasing ep...\n"); + kfree(ep); + return; + } + + qedr_iw_issue_event(context, params, IW_CM_EVENT_ESTABLISHED); + + if (params->status < 0) + qedr_iw_close_event(context, params); +} + +int +qedr_iw_mpa_reply(void *context, struct qed_iwarp_cm_event_params *params) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + struct qedr_dev *dev = ep->dev; + struct qed_iwarp_send_rtr_in rtr_in; + + rtr_in.ep_context = params->ep_context; + + return dev->ops->iwarp_send_rtr(dev->rdma_ctx, &rtr_in); +} + +int +qedr_iw_event_handler(void *context, struct qed_iwarp_cm_event_params *params) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + struct qedr_dev *dev = ep->dev; + + switch (params->event) { + case QED_IWARP_EVENT_MPA_REQUEST: + qedr_iw_mpa_request(context, params); + break; + case QED_IWARP_EVENT_ACTIVE_MPA_REPLY: + qedr_iw_mpa_reply(context, params); + break; + case QED_IWARP_EVENT_PASSIVE_COMPLETE: + ep->during_connect = 0; + qedr_iw_passive_complete(context, params); + break; + + case QED_IWARP_EVENT_ACTIVE_COMPLETE: + ep->during_connect = 0; + qedr_iw_issue_event(context, + params, + IW_CM_EVENT_CONNECT_REPLY); + if (params->status < 0) { + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + + ep->cm_id->rem_ref(ep->cm_id); + ep->cm_id = NULL; + } + break; + case QED_IWARP_EVENT_DISCONNECT: + qedr_iw_disconnect_event(context, params); + break; + case QED_IWARP_EVENT_CLOSE: + ep->during_connect = 0; + qedr_iw_close_event(context, params); + break; + case QED_IWARP_EVENT_RQ_EMPTY: + qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL, + "QED_IWARP_EVENT_RQ_EMPTY"); + break; + case QED_IWARP_EVENT_IRQ_FULL: + qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL, + "QED_IWARP_EVENT_IRQ_FULL"); + break; + case QED_IWARP_EVENT_LLP_TIMEOUT: + qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL, + "QED_IWARP_EVENT_LLP_TIMEOUT"); + break; + case QED_IWARP_EVENT_REMOTE_PROTECTION_ERROR: + qedr_iw_qp_event(context, params, IB_EVENT_QP_ACCESS_ERR, + "QED_IWARP_EVENT_REMOTE_PROTECTION_ERROR"); + break; + case QED_IWARP_EVENT_CQ_OVERFLOW: + qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL, + "QED_IWARP_EVENT_CQ_OVERFLOW"); + break; + case QED_IWARP_EVENT_QP_CATASTROPHIC: + qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL, + "QED_IWARP_EVENT_QP_CATASTROPHIC"); + break; + case QED_IWARP_EVENT_LOCAL_ACCESS_ERROR: + qedr_iw_qp_event(context, params, IB_EVENT_QP_ACCESS_ERR, + "QED_IWARP_EVENT_LOCAL_ACCESS_ERROR"); + break; + case QED_IWARP_EVENT_REMOTE_OPERATION_ERROR: + qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL, + "QED_IWARP_EVENT_REMOTE_OPERATION_ERROR"); + break; + case QED_IWARP_EVENT_TERMINATE_RECEIVED: + DP_NOTICE(dev, "Got terminate message\n"); + break; + default: + DP_NOTICE(dev, "Unknown event received %d\n", params->event); + break; + }; + return 0; +} + +static u16 qedr_iw_get_vlan_ipv4(struct qedr_dev *dev, u32 *addr) +{ + struct net_device *ndev; + u16 vlan_id = 0; + + ndev = ip_dev_find(&init_net, htonl(addr[0])); + + if (ndev) { + vlan_id = rdma_vlan_dev_vlan_id(ndev); + dev_put(ndev); + } + if (vlan_id == 0xffff) + vlan_id = 0; + return vlan_id; +} + +static u16 qedr_iw_get_vlan_ipv6(u32 *addr) +{ + struct net_device *ndev = NULL; + struct in6_addr laddr6; + u16 vlan_id = 0; + int i; + + if (!IS_ENABLED(CONFIG_IPV6)) + return vlan_id; + + for (i = 0; i < 4; i++) + laddr6.in6_u.u6_addr32[i] = htonl(addr[i]); + + rcu_read_lock(); + for_each_netdev_rcu(&init_net, ndev) { + if (ipv6_chk_addr(&init_net, &laddr6, ndev, 1)) { + vlan_id = rdma_vlan_dev_vlan_id(ndev); + break; + } + } + + rcu_read_unlock(); + if (vlan_id == 0xffff) + vlan_id = 0; + + return vlan_id; +} + +static int +qedr_addr4_resolve(struct qedr_dev *dev, + struct sockaddr_in *src_in, + struct sockaddr_in *dst_in, u8 *dst_mac) +{ + __be32 src_ip = src_in->sin_addr.s_addr; + __be32 dst_ip = dst_in->sin_addr.s_addr; + struct neighbour *neigh = NULL; + struct rtable *rt = NULL; + int rc = 0; + + rt = ip_route_output(&init_net, dst_ip, src_ip, 0, 0); + if (IS_ERR(rt)) { + DP_ERR(dev, "ip_route_output returned error\n"); + return -EINVAL; + } + + neigh = dst_neigh_lookup(&rt->dst, &dst_ip); + + if (neigh) { + rcu_read_lock(); + if (neigh->nud_state & NUD_VALID) { + ether_addr_copy(dst_mac, neigh->ha); + DP_DEBUG(dev, QEDR_MSG_QP, "mac_addr=[%pM]\n", dst_mac); + } else { + neigh_event_send(neigh, NULL); + } + rcu_read_unlock(); + neigh_release(neigh); + } + + ip_rt_put(rt); + + return rc; +} + +static int +qedr_addr6_resolve(struct qedr_dev *dev, + struct sockaddr_in6 *src_in, + struct sockaddr_in6 *dst_in, u8 *dst_mac) +{ + struct neighbour *neigh = NULL; + struct dst_entry *dst; + struct flowi6 fl6; + int rc = 0; + + memset(&fl6, 0, sizeof(fl6)); + fl6.daddr = dst_in->sin6_addr; + fl6.saddr = src_in->sin6_addr; + + dst = ip6_route_output(&init_net, NULL, &fl6); + + if ((!dst) || dst->error) { + if (dst) { + dst_release(dst); + DP_ERR(dev, + "ip6_route_output returned dst->error = %d\n", + dst->error); + } + return -EINVAL; + } + neigh = dst_neigh_lookup(dst, &dst_in); + + if (neigh) { + rcu_read_lock(); + if (neigh->nud_state & NUD_VALID) { + ether_addr_copy(dst_mac, neigh->ha); + DP_DEBUG(dev, QEDR_MSG_QP, "mac_addr=[%pM]\n", dst_mac); + } else { + neigh_event_send(neigh, NULL); + } + rcu_read_unlock(); + neigh_release(neigh); + } + + dst_release(dst); + + return rc; +} + +int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) +{ + struct qedr_dev *dev = get_qedr_dev(cm_id->device); + struct qed_iwarp_connect_out out_params; + struct qed_iwarp_connect_in in_params; + struct qed_iwarp_cm_info *cm_info; + struct sockaddr_in6 *laddr6; + struct sockaddr_in6 *raddr6; + struct sockaddr_in *laddr; + struct sockaddr_in *raddr; + struct qedr_iw_ep *ep; + struct qedr_qp *qp; + int rc = 0; + int i; + + qp = idr_find(&dev->qpidr, conn_param->qpn); + + laddr = (struct sockaddr_in *)&cm_id->local_addr; + raddr = (struct sockaddr_in *)&cm_id->remote_addr; + laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr; + raddr6 = (struct sockaddr_in6 *)&cm_id->remote_addr; + + DP_DEBUG(dev, QEDR_MSG_IWARP, + "Connect source address: %pISpc, remote address: %pISpc\n", + &cm_id->local_addr, &cm_id->remote_addr); + + if (!laddr->sin_port || !raddr->sin_port) + return -EINVAL; + + ep = kzalloc(sizeof(*ep), GFP_KERNEL); + if (!ep) + return -ENOMEM; + + ep->dev = dev; + ep->qp = qp; + qp->ep = ep; + cm_id->add_ref(cm_id); + ep->cm_id = cm_id; + + in_params.event_cb = qedr_iw_event_handler; + in_params.cb_context = ep; + + cm_info = &in_params.cm_info; + memset(cm_info->local_ip, 0, sizeof(cm_info->local_ip)); + memset(cm_info->remote_ip, 0, sizeof(cm_info->remote_ip)); + + if (cm_id->remote_addr.ss_family == AF_INET) { + cm_info->ip_version = QED_TCP_IPV4; + + cm_info->remote_ip[0] = ntohl(raddr->sin_addr.s_addr); + cm_info->local_ip[0] = ntohl(laddr->sin_addr.s_addr); + cm_info->remote_port = ntohs(raddr->sin_port); + cm_info->local_port = ntohs(laddr->sin_port); + cm_info->vlan = qedr_iw_get_vlan_ipv4(dev, cm_info->local_ip); + + rc = qedr_addr4_resolve(dev, laddr, raddr, + (u8 *)in_params.remote_mac_addr); + + in_params.mss = dev->iwarp_max_mtu - + (sizeof(struct iphdr) + sizeof(struct tcphdr)); + + } else { + in_params.cm_info.ip_version = QED_TCP_IPV6; + + for (i = 0; i < 4; i++) { + cm_info->remote_ip[i] = + ntohl(raddr6->sin6_addr.in6_u.u6_addr32[i]); + cm_info->local_ip[i] = + ntohl(laddr6->sin6_addr.in6_u.u6_addr32[i]); + } + + cm_info->local_port = ntohs(laddr6->sin6_port); + cm_info->remote_port = ntohs(raddr6->sin6_port); + + in_params.mss = dev->iwarp_max_mtu - + (sizeof(struct ipv6hdr) + sizeof(struct tcphdr)); + + cm_info->vlan = qedr_iw_get_vlan_ipv6(cm_info->local_ip); + + rc = qedr_addr6_resolve(dev, laddr6, raddr6, + (u8 *)in_params.remote_mac_addr); + } + if (rc) + goto err; + + DP_DEBUG(dev, QEDR_MSG_IWARP, + "ord = %d ird=%d private_data=%p private_data_len=%d rq_psn=%d\n", + conn_param->ord, conn_param->ird, conn_param->private_data, + conn_param->private_data_len, qp->rq_psn); + + cm_info->ord = conn_param->ord; + cm_info->ird = conn_param->ird; + cm_info->private_data = conn_param->private_data; + cm_info->private_data_len = conn_param->private_data_len; + in_params.qp = qp->qed_qp; + memcpy(in_params.local_mac_addr, dev->ndev->dev_addr, ETH_ALEN); + + ep->during_connect = 1; + rc = dev->ops->iwarp_connect(dev->rdma_ctx, &in_params, &out_params); + if (rc) + goto err; + + return rc; + +err: + cm_id->rem_ref(cm_id); + kfree(ep); + return rc; +} + +int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog) +{ + struct qedr_dev *dev = get_qedr_dev(cm_id->device); + struct qedr_iw_listener *listener; + struct qed_iwarp_listen_in iparams; + struct qed_iwarp_listen_out oparams; + struct sockaddr_in *laddr; + struct sockaddr_in6 *laddr6; + int rc; + int i; + + laddr = (struct sockaddr_in *)&cm_id->local_addr; + laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr; + + DP_DEBUG(dev, QEDR_MSG_IWARP, + "Create Listener address: %pISpc\n", &cm_id->local_addr); + + listener = kzalloc(sizeof(*listener), GFP_KERNEL); + if (!listener) + return -ENOMEM; + + listener->dev = dev; + cm_id->add_ref(cm_id); + listener->cm_id = cm_id; + listener->backlog = backlog; + + iparams.cb_context = listener; + iparams.event_cb = qedr_iw_event_handler; + iparams.max_backlog = backlog; + + if (cm_id->local_addr.ss_family == AF_INET) { + iparams.ip_version = QED_TCP_IPV4; + memset(iparams.ip_addr, 0, sizeof(iparams.ip_addr)); + + iparams.ip_addr[0] = ntohl(laddr->sin_addr.s_addr); + iparams.port = ntohs(laddr->sin_port); + iparams.vlan = qedr_iw_get_vlan_ipv4(dev, iparams.ip_addr); + } else { + iparams.ip_version = QED_TCP_IPV6; + + for (i = 0; i < 4; i++) { + iparams.ip_addr[i] = + ntohl(laddr6->sin6_addr.in6_u.u6_addr32[i]); + } + + iparams.port = ntohs(laddr6->sin6_port); + + iparams.vlan = qedr_iw_get_vlan_ipv6(iparams.ip_addr); + } + rc = dev->ops->iwarp_create_listen(dev->rdma_ctx, &iparams, &oparams); + if (rc) + goto err; + + listener->qed_handle = oparams.handle; + cm_id->provider_data = listener; + return rc; + +err: + cm_id->rem_ref(cm_id); + kfree(listener); + return rc; +} + +int qedr_iw_destroy_listen(struct iw_cm_id *cm_id) +{ + struct qedr_iw_listener *listener = cm_id->provider_data; + struct qedr_dev *dev = get_qedr_dev(cm_id->device); + int rc = 0; + + if (listener->qed_handle) + rc = dev->ops->iwarp_destroy_listen(dev->rdma_ctx, + listener->qed_handle); + + cm_id->rem_ref(cm_id); + return rc; +} + +int qedr_iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)cm_id->provider_data; + struct qedr_dev *dev = ep->dev; + struct qedr_qp *qp; + struct qed_iwarp_accept_in params; + int rc; + + DP_DEBUG(dev, QEDR_MSG_IWARP, "Accept on qpid=%d\n", conn_param->qpn); + + qp = idr_find(&dev->qpidr, conn_param->qpn); + if (!qp) { + DP_ERR(dev, "Invalid QP number %d\n", conn_param->qpn); + return -EINVAL; + } + + ep->qp = qp; + qp->ep = ep; + cm_id->add_ref(cm_id); + ep->cm_id = cm_id; + + params.ep_context = ep->qed_context; + params.cb_context = ep; + params.qp = ep->qp->qed_qp; + params.private_data = conn_param->private_data; + params.private_data_len = conn_param->private_data_len; + params.ird = conn_param->ird; + params.ord = conn_param->ord; + + ep->during_connect = 1; + rc = dev->ops->iwarp_accept(dev->rdma_ctx, ¶ms); + if (rc) + goto err; + + return rc; +err: + ep->during_connect = 0; + cm_id->rem_ref(cm_id); + return rc; +} + +int qedr_iw_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)cm_id->provider_data; + struct qedr_dev *dev = ep->dev; + struct qed_iwarp_reject_in params; + + params.ep_context = ep->qed_context; + params.cb_context = ep; + params.private_data = pdata; + params.private_data_len = pdata_len; + ep->qp = NULL; + + return dev->ops->iwarp_reject(dev->rdma_ctx, ¶ms); +} + void qedr_iw_qp_add_ref(struct ib_qp *ibqp) { struct qedr_qp *qp = get_qedr_qp(ibqp); diff --git a/drivers/infiniband/hw/qedr/qedr_iw_cm.h b/drivers/infiniband/hw/qedr/qedr_iw_cm.h index ea6d17af..08f4b10 100644 --- a/drivers/infiniband/hw/qedr/qedr_iw_cm.h +++ b/drivers/infiniband/hw/qedr/qedr_iw_cm.h @@ -30,6 +30,18 @@ * SOFTWARE. */ #include + +int qedr_iw_connect(struct iw_cm_id *cm_id, + struct iw_cm_conn_param *conn_param); + +int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog); + +int qedr_iw_destroy_listen(struct iw_cm_id *cm_id); + +int qedr_iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param); + +int qedr_iw_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len); + void qedr_iw_qp_add_ref(struct ib_qp *qp); void qedr_iw_qp_rem_ref(struct ib_qp *qp); diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c index bdce96b..7067249 100644 --- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c @@ -2260,6 +2260,23 @@ int qedr_destroy_qp(struct ib_qp *ibqp) /* Change the QP state to ERROR */ qedr_modify_qp(ibqp, &attr, attr_mask, NULL); } + } else { + /* Wait for the connect/accept to complete */ + if (qp->ep) { + int wait_count = 1; + + while (qp->ep->during_connect) { + DP_DEBUG(dev, QEDR_MSG_QP, + "Still in during connect/accept\n"); + + msleep(100); + if (wait_count++ > 200) { + DP_NOTICE(dev, + "during connect timeout\n"); + break; + } + } + } } if (qp->qp_type == IB_QPT_GSI)