From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-BL2-obe.outbound.protection.outlook.com (mail-bl2nam02on0078.outbound.protection.outlook.com [104.47.38.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 08DDD21CEB0FA for ; Mon, 11 Sep 2017 05:14:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=K0ybQ/1VSDjBw10Xzmo/u+YkzbjobUSe/5Dzdol7AC4=; b=PJRkg/PdJw2/1nXXPzRlI5gTtcXLnsEgXlkHGQEDFiCiZjR25UK5dvixU+jQqrt77G13pnNIkc4wrVzeQ4HuH12qzkamTO88HdfJ0Uz7VgeYx4/BGBK22+DkXH9QwDM/dOnvBtMwcPsY1/aP3tHpjJZ3dQAYYD6n/6+cv/USA7A= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; Received: from ubuntu-010236106000.amd.com (165.204.78.1) by SN1PR12MB0158.namprd12.prod.outlook.com (10.162.3.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.35.12; Mon, 11 Sep 2017 12:17:11 +0000 From: Brijesh Singh To: edk2-devel@lists.01.org Cc: Brijesh Singh , Ard Biesheuvel , Jordan Justen , Tom Lendacky , Laszlo Ersek Date: Mon, 11 Sep 2017 07:16:55 -0500 Message-Id: <20170911121657.34992-7-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170911121657.34992-1-brijesh.singh@amd.com> References: <20170911121657.34992-1-brijesh.singh@amd.com> MIME-Version: 1.0 X-Originating-IP: [165.204.78.1] X-ClientProxiedBy: DM3PR12CA0047.namprd12.prod.outlook.com (10.161.151.15) To SN1PR12MB0158.namprd12.prod.outlook.com (10.162.3.145) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0db7671f-824f-4842-0a00-08d4f90f082d X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(48565401081)(300000503095)(300135400095)(2017052603199)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:SN1PR12MB0158; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0158; 3:0OJeG6LH2B8USxezh25xzAkyr2EnEklFTlUG1syCaVXl9nHliBhIwln2E87WrLeF9Lc34lsFiBGgcgTdaCbPOB8KE0pXCiAbfZqvwRX4OMn3hQem0kgxXKGnJj6joiFzvqwU8OLBRSLANyyNhIg/oN2zCpzGcQe+6pImNGGmUHAKQ4l2fTC6M8a1gyNaYwiCUWBVdoPYYgC0A6AeahRTVt9mxuLEJ5zOWXb0ynDowllsv6AXxjz9kIahiyN/pEpO; 25:Cd72b5bpIZRQMEgTpSxm9PyZraIQRfBu3IOCh0kc+s7FwHgdP8bLfCCkN9DREPWVnXQPx4Hpw3DaCM6fvBJUwSqRpYz5gAS+08IY0X3Hv09MLhONl95tIlC1oXJWW5dP0XQMhlUzUE+2w2xdpMdRBtuj7r3DJU66tx1Mv22U/zZM2ii7HITRYKDh0uqOFjwEi8yCb553kF/Lqlq1FekBiPH8u1/LMEFV8oWqOuDAeibxXrs8hgvRCSYWeP0AJxgW+P+jMKSv6NlsxRwb8Bl0upkZFNfKdc3yUX8Sg2Lz7KBLws7eft1GvLoPb92BsW4qi5bVTwR5ptTR9yx/jqivYg==; 31:RyXQS5qHzhNRYVraiA+13nFoQB+0NkrePAxtvWjzj0jbCilpTRzg7EOS0xOcTRAvIGGbX7V63Zk1rluFQ8YsX6A44Mv4l2xLxuSt+ebHLNkxOvS/7krk8p7WAJ1/EEldYjONxjU9iuW7H8d18tUvLrKZ0bf+7zHQekmAuYCY4p5+idSypqlfLHzV7dm7ifR+UcXfv3/aAGB9SvRgvXzwfGp5ih2tOGSFRuHx6ne6SII= X-MS-TrafficTypeDiagnostic: SN1PR12MB0158: X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0158; 20:WPJdIqvT9ND20h6mmUUPqWDwsj5SkAOByl8d1vsCr1DrJlsBruAQvvd5SzDIy/o0HxX/5TnbmHDip/vwrLaGhljjvkRluEC0QsQ5+NroXYqN37oSM1PO3VazaLjpyDzl0exlTY0CbBFguCvXMIWbNtLqVBp3VZQ/MmSRAkx0CEiGmdB7vyWwzCIR3lKfnK5XMcLiRYtyJTShle9jMpJZML38ok3mgGsYo+Qhebdq1woSv6BuTKMi7ATTA8KuSedg0IQsO4zYJf1LqG/5LnbtdHP00crQd9Fz1O0nNfZFSNeVLk6JMMVVGc6zhfOnT1SyJbJ94+lpvqMDvgo8Vw+0UKOgCOzBKFGhk0yP6JJA1jRYu/CA0rKpABsfufZsnBxsG5Oakg0O/dhFPZSinruXL/Zbh2XVFqotQrqRuWWHxYN9eQ0YcG2i8oh9IVFMXDyKielPAOK04367OCfod3otyTd5QL3dMGIBJFbMIhgijhB3PEKfXs2TDSOSwYxXWb37; 4:9+DXScJ88e2RxfJXkyKrrTkE8sDejcXP3VenmtKzM3oQU03z52pGaFholOEcmRxSg+u6zvehAY2ypEbu7uJz1yO0MV1iOMXfS4RNiy5UEB/ONlkL8uUv120WiO3TRZBZlbPwObeRRUTd8kod27FzoZnRCen/R49FgQ6JK5xMY/dZKcTiQnegiXTbDxJD//tQmnXrvhcQ7BCpF5lhdil6OegBXoIWDsyz3+kjSq4y898PO0EDE0zmHs/dzF8ejLe2jZhh7/RSi+7FzgEZEs+odJNwEiXIHvWbdDcWoPYLty3wYpusk4GYEvQ0U+9IARodj0owU+fb0BJbze73gnkD6w== X-Exchange-Antispam-Report-Test: UriScan:(767451399110)(228905959029699); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(100000703101)(100105400095)(3002001)(93006095)(93001095)(10201501046)(6055026)(6041248)(20161123560025)(20161123564025)(20161123558100)(20161123562025)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:SN1PR12MB0158; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:SN1PR12MB0158; X-Forefront-PRVS: 04270EF89C X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(189002)(199003)(110136004)(106356001)(7736002)(105586002)(101416001)(4326008)(53416004)(1076002)(2361001)(2906002)(305945005)(2351001)(5660300001)(189998001)(25786009)(33646002)(50986999)(76176999)(3846002)(6116002)(68736007)(8676002)(478600001)(81156014)(81166006)(42186005)(50466002)(54906002)(6666003)(50226002)(97736004)(48376002)(36756003)(6916009)(2950100002)(8936002)(66066001)(47776003)(86362001)(5003940100001)(6486002)(53936002); DIR:OUT; SFP:1101; SCL:1; SRVR:SN1PR12MB0158; H:ubuntu-010236106000.amd.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN1PR12MB0158; 23:9Hx87qSvPoLnVqpiHzbT6BgQ+X0IZvCKgST9gYN7b?= =?us-ascii?Q?yi9TZHRb0HetM3Y5OsLQHiN4xLXbBQCEnByk1dADwPgQB/W5Gt5dZrqqPMz9?= =?us-ascii?Q?+EUuEoyeLXWQQNfOfr6RBTfUoTQPh84iTIYqGJH1p1W1umcFizYlx49TLOJS?= =?us-ascii?Q?MOoiYYpG9yTZ2ONAFzafGI4HdZGvBDTQE6G1zM0Ygwf+IFCU2imup0Q6cLWm?= =?us-ascii?Q?TMJKTag8JXarhvsQVxUHMCJdYjnXDF7Lnqrvjp4kLUsdZ59hikAhHQ5KjQ4g?= =?us-ascii?Q?YWZPPRtzhXo7oaxHeB8BnUkElup1rYoQVP6GKj6z/cXe6rS/MaXM1G+G12W5?= =?us-ascii?Q?k4Y9xTLNASjbgLrUIeubl5KrPYbQ2rjPR7/Nv7ufBrEMGXpUER/wNmkih52m?= =?us-ascii?Q?rT3wGCIbx2B3OoGVm+GIU+T1v9Rzc8Rf/h613jKRyHV1PrgtxDJ8skB4Nisw?= =?us-ascii?Q?StPTwgAJMG5ZjLPJ9hs5KV/3oahh4Qf0yUs9HmFzi+yJN6yUJ27RegqE1FZs?= =?us-ascii?Q?nz+AdWQSlAOh9WawK7qZ+wnbq3nVdEz+Y4HDjkBhy7vnEh2tg4R0Bs/QVmtR?= =?us-ascii?Q?aFjaa9yVmjzmQPCkYqPA3IzCYSJ9yGZx+ey0zZ8clS4W0tbKdCbcLIu0uHw1?= =?us-ascii?Q?8/w3Btf2lWUQPfAxFrcUIcIjHtB/V+4255gNgrs5x8bnt4oXPtwuIN6foVSW?= =?us-ascii?Q?8GWiNdyqlw5kBSCdabuw4EBAv9E0GSQewd0yYxiahiCaKilSfdZCI7fJ5aTw?= =?us-ascii?Q?Z8aQYHSbscir36Kkjhl3gkZ5XA4xpHORLr9KvaacIsE92dTdnBNr1h4ew3DG?= =?us-ascii?Q?PqxyDzQX1U4/LOMLrLuLaA+mghk0EK7caOxqef6TdD2YMZKPyt+IAXJUEdF+?= =?us-ascii?Q?x0oH6yw8twt67UiDSMFw2YG0nUJChVBzr/NofG0AjFlO7styhgrmzifW2c4k?= =?us-ascii?Q?JDNGWsN1HawGel0QH7tcWVj5u2s8HOpTenjq8bWIlMpNRC/1u9S3ExNnkRDk?= =?us-ascii?Q?TqFPMsxViWkzg/Mg1J4DkkbYTJrWb3zqTvGH0escyugiNewTSGpHhazP4D5p?= =?us-ascii?Q?weW0UVGBshpSwzoqQqMqTNOEUlH?= X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0158; 6:nlRpN5EuK2+RclEjzTuxeVSJZR+IU7UeGDjqnmSM23h0D4AWuQ8exn/PCzUfeJVpBKjGF+quEUHmUngYjV05IxZbDa07ggh/kmPh6NAhDyv1Tiz2z7jOZWtKUMo6e8DjlYeX66qgU40WYhG13dmPfCE8Nk2x5G8EZ3/oFR8l7rDVJm06ZtBwjT8G/yYF/YmXKFXUiclXoZKEsa01DjpnkVk9n4ayCxPGZ5g0sHdNLbQukK/6G0BeEgApTVH0XvCtMqfDr1qnpjTpf5e/FFXqmIh9NW2q6Yp/RjctdbY9znEvO2eFGq5JQ/iKfOtukHC03ITzCu7xqjci/much6Rw/g==; 5:o2Yxdk+Ey3kxwc6Xz3HTtFKhPp0fQdgL6UkB3PA4FwvCXmyzlUoxkD7KhCIZRLWBZZ2tUxLTTG3qK5lKFLc5CQluOsaUnylWca+5+h+d9jMSM1GR6fY2Tw5sVBCmZjV9eBJV6hXoBX1S1KkDRrFTvQ==; 24:lt47uTApLCLcrgxkjjpnRAu2XNFBoBsGnvfMPbbtHrvnWfvTk5CzRVERoe5ABjFfsOnQsnMrycqzx2ZQuW+5WpnHbzQmHTTZXAfFhasm8ok=; 7:TGWWzgxcnpkZL+49X3eRnTiVacbhxjHe2FEEXvPbYXh/q4RR6FbO66N0NdwOYr1INkgEywoQyL+koGB8WULzwQIul+lmFtOAuKW7gQ4mfN0hQ5yFtgMLxBWvFSLWHL6H1OjjtTI1QDPqJizXAX7/4P6kWypoOEPLadjmXEHJSmBPTCtEvseYn9vBVRW/SwM0GYtexSd/gKg50i7hOk8O9kcXS4VLLgYNoScKAXyBfAU= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0158; 20:E7FGG9jOZwKKH89Ll94M3/LUH/AVaut4Bhr9f7jDVmlUnGHazk5BGcIFBakD6sWIZrbf4lDDx+iTgLsVsB58zTCEINASdKbU5ZEA8mRGkSc8/MX1t3XsdhKqrwecolkIcAJShmlTDaW2eppKvDfmt5+8juH/jyK5bKUNVcrNjkL+0n6AG7LEmHqJLYaNgOlts/3sOWxa6GZ1a7PLrIcLOFcrgaQu57zT6UaP2WSo3qVx4BKXFMW+tKs7SVz9WkiV X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Sep 2017 12:17:11.9171 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0158 Subject: [PATCH v2 6/8] OvmfPkg/VirtioNetDxe: add Tx packet map/unmap helper functions X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2017 12:14:18 -0000 Content-Type: text/plain When device is behind IOMMU, driver is require to pass the device address of TxBuf in the Tx VRING. The patch adds helper functions and data structure to map and unmap the TxBuf system physical address to a device address. Since the TxBuf is returned back to caller from VirtioNetGetStatus() hence we use OrderedCollection interface to save the TxBuf system physical to device address mapping. After the TxBuf is succesfully transmitted VirtioNetUnmapTxBuf() does the reverse lookup in OrderedCollection data structure to get the system physical address of TxBuf for a given device address. Cc: Ard Biesheuvel Cc: Jordan Justen Cc: Tom Lendacky Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Brijesh Singh --- OvmfPkg/VirtioNetDxe/VirtioNet.inf | 1 + OvmfPkg/VirtioNetDxe/VirtioNet.h | 32 ++++ OvmfPkg/VirtioNetDxe/SnpInitialize.c | 15 +- OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c | 188 ++++++++++++++++++++ 4 files changed, 235 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.inf b/OvmfPkg/VirtioNetDxe/VirtioNet.inf index a855ad4ac154..9ff6d87e6190 100644 --- a/OvmfPkg/VirtioNetDxe/VirtioNet.inf +++ b/OvmfPkg/VirtioNetDxe/VirtioNet.inf @@ -49,6 +49,7 @@ DebugLib DevicePathLib MemoryAllocationLib + OrderedCollectionLib UefiBootServicesTableLib UefiDriverEntryPoint UefiLib diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.h b/OvmfPkg/VirtioNetDxe/VirtioNet.h index 3f48bcc6b67c..906bec8e88f3 100644 --- a/OvmfPkg/VirtioNetDxe/VirtioNet.h +++ b/OvmfPkg/VirtioNetDxe/VirtioNet.h @@ -26,6 +26,7 @@ #include #include #include +#include #define VNET_SIG SIGNATURE_32 ('V', 'N', 'E', 'T') @@ -100,6 +101,7 @@ typedef struct { VOID *TxSharedReqMap; // VirtioNetInitTx UINT16 TxLastUsed; // VirtioNetInitTx EFI_PHYSICAL_ADDRESS RxBufDeviceBase; // VirtioNetInitRx + ORDERED_COLLECTION *TxBufMapInfoCollection; // VirtioNetInitTx } VNET_DEV; @@ -281,6 +283,36 @@ VirtioNetUninitRing ( ); // +// utility functions to map caller-supplied Tx buffer system physical address +// to a device address and vice versa +// +EFI_STATUS +EFIAPI +VirtioNetMapTxBuf ( + IN VNET_DEV *Dev, + IN UINT16 DescIdx, + IN VOID *Buffer, + IN UINTN NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress + ); + +INTN +EFIAPI +VirtioNetTxMapInfoCompare ( + IN CONST VOID *UserStruct1, + IN CONST VOID *UserStruct2 + ); + +EFI_STATUS +EFIAPI +VirtioNetUnmapTxBuf ( + IN VNET_DEV *Dev, + IN UINT16 DescIdx, + OUT VOID **Buffer, + IN EFI_PHYSICAL_ADDRESS DeviceAddress + ); + +// // event callbacks // VOID diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c index 6cedb406a172..a8ffb9a8a7b1 100644 --- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c +++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c @@ -176,6 +176,15 @@ VirtioNetInitTx ( return EFI_OUT_OF_RESOURCES; } + Dev->TxBufMapInfoCollection = OrderedCollectionInit ( + VirtioNetTxMapInfoCompare, + VirtioNetTxMapInfoCompare + ); + if (Dev->TxBufMapInfoCollection == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto FreeTxFreeStack; + } + // // Allocate TxSharedReq header and map with BusMasterCommonBuffer so that it // can be accessed equally by both processor and device. @@ -186,7 +195,7 @@ VirtioNetInitTx ( &TxSharedReqBuffer ); if (EFI_ERROR (Status)) { - goto FreeTxFreeStack; + goto UninitMapInfoCollection; } ZeroMem (TxSharedReqBuffer, sizeof *Dev->TxSharedReq); @@ -267,6 +276,10 @@ FreeTxSharedReqBuffer: EFI_SIZE_TO_PAGES (sizeof *(Dev->TxSharedReq)), TxSharedReqBuffer ); + +UninitMapInfoCollection: + OrderedCollectionUninit (Dev->TxBufMapInfoCollection); + FreeTxFreeStack: FreePool (Dev->TxFreeStack); diff --git a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c index 2ec3dc385a9f..dafb538b4b5a 100644 --- a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c +++ b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c @@ -18,6 +18,17 @@ #include "VirtioNet.h" +// +// The user structure for the ordered collection that will track the mapping +// info of the packets queued in TxRing +// +typedef struct { + UINT16 DescIdx; + VOID *Buffer; + EFI_PHYSICAL_ADDRESS DeviceAddress; + VOID *BufMap; +} TX_BUF_MAP_INFO; + /** Release RX and TX resources on the boundary of the EfiSimpleNetworkInitialized state. @@ -54,6 +65,20 @@ VirtioNetShutdownTx ( IN OUT VNET_DEV *Dev ) { + ORDERED_COLLECTION_ENTRY *Entry, *Entry2; + TX_BUF_MAP_INFO *TxBufMapInfo; + + for (Entry = OrderedCollectionMin (Dev->TxBufMapInfoCollection); + Entry != NULL; + Entry = Entry2) { + Entry2 = OrderedCollectionNext (Entry); + TxBufMapInfo = (TX_BUF_MAP_INFO *)Entry2; + Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, TxBufMapInfo->BufMap); + FreePool (TxBufMapInfo); + OrderedCollectionDelete (Dev->TxBufMapInfoCollection, Entry, NULL); + } + OrderedCollectionUninit (Dev->TxBufMapInfoCollection); + Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxSharedReqMap); Dev->VirtIo->FreeSharedPages ( Dev->VirtIo, @@ -83,3 +108,166 @@ VirtioNetUninitRing ( Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, RingMap); VirtioRingUninit (Dev->VirtIo, Ring); } + + +/** + Map Caller-supplied TxBuf buffer to the device-mapped address + + @param[in] Dev The VNET_DEV driver instance which wants to + map the Tx packet. + @param[in] DescIdx VRING descriptor index which will point to + the device address + @param[in] Buffer The system physical address of TxBuf + @param[in] NumberOfBytes Number of bytes to map + @param[out] DeviceAddress The resulting device address for the bus + master access. + + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to + a lack of resources. + @retval EFI_INVALID_PARAMETER The VRING descriptor index is already mapped. +*/ +EFI_STATUS +EFIAPI +VirtioNetMapTxBuf ( + IN VNET_DEV *Dev, + IN UINT16 DescIdx, + IN VOID *Buffer, + IN UINTN NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress + ) +{ + EFI_STATUS Status; + TX_BUF_MAP_INFO *TxBufMapInfo; + EFI_PHYSICAL_ADDRESS Address; + VOID *Mapping; + ORDERED_COLLECTION_ENTRY *Entry; + + TxBufMapInfo = AllocatePool (sizeof (*TxBufMapInfo)); + if (TxBufMapInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = VirtioMapAllBytesInSharedBuffer ( + Dev->VirtIo, + VirtioOperationBusMasterRead, + Buffer, + NumberOfBytes, + &Address, + &Mapping + ); + if (EFI_ERROR (Status)) { + goto FreeTxBufMapInfo; + } + + TxBufMapInfo->DescIdx = DescIdx; + TxBufMapInfo->Buffer = Buffer; + TxBufMapInfo->DeviceAddress = Address; + TxBufMapInfo->BufMap = Mapping; + + Status = OrderedCollectionInsert ( + Dev->TxBufMapInfoCollection, + &Entry, + TxBufMapInfo + ); + switch (Status) { + case RETURN_OUT_OF_RESOURCES: + Status = EFI_OUT_OF_RESOURCES; + goto UnmapTxBufBuffer; + case RETURN_ALREADY_STARTED: + Status = EFI_INVALID_PARAMETER; + goto UnmapTxBufBuffer; + default: + ASSERT (Status == RETURN_SUCCESS); + break; + } + + ASSERT (OrderedCollectionUserStruct (Entry) == TxBufMapInfo); + + *DeviceAddress = Address; + + return EFI_SUCCESS; + +UnmapTxBufBuffer: + Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping); + +FreeTxBufMapInfo: + FreePool (TxBufMapInfo); + return Status; +} + +/** + Unmap (aka reverse mapping) device mapped TxBuf buffer to the system + physical address + + @param[in] Dev The VNET_DEV driver instance which wants to + map the Tx packet. + @param[in] DescIdx VRING descriptor index which point to + the device address + @param[out] Buffer The system physical address of TxBuf + @param[out] DeviceAddress The device address for the TxBuf + + @retval EFI_INVALID_PARAMETER The VRING descriptor index is not mapped +*/ +EFI_STATUS +EFIAPI +VirtioNetUnmapTxBuf ( + IN VNET_DEV *Dev, + IN UINT16 DescIdx, + OUT VOID **Buffer, + IN EFI_PHYSICAL_ADDRESS DeviceAddress + ) +{ + TX_BUF_MAP_INFO StandaloneKey; + ORDERED_COLLECTION_ENTRY *Entry; + TX_BUF_MAP_INFO *UserStruct; + VOID *Ptr; + EFI_STATUS Status; + + StandaloneKey.DescIdx = DescIdx; + Entry = OrderedCollectionFind (Dev->TxBufMapInfoCollection, &StandaloneKey); + if (Entry == NULL) { + return EFI_INVALID_PARAMETER; + } + + OrderedCollectionDelete (Dev->TxBufMapInfoCollection, Entry, &Ptr); + + UserStruct = Ptr; + ASSERT (UserStruct->DescIdx == DescIdx); + + *Buffer = UserStruct->Buffer; + Status = Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, UserStruct->BufMap); + FreePool (UserStruct); + + return Status; +} + +/** + Comparator function for two user structures. + + @param[in] UserStruct1 Pointer to the first user structure. + + @param[in] UserStruct2 Pointer to the second user structure. + + @retval <0 If UserStruct1 compares less than UserStruct2. + + @retval 0 If UserStruct1 compares equal to UserStruct2. + + @retval >0 If UserStruct1 compares greater than UserStruct2. +*/ +INTN +EFIAPI +VirtioNetTxMapInfoCompare ( + IN CONST VOID *UserStruct1, + IN CONST VOID *UserStruct2 + ) +{ + CONST TX_BUF_MAP_INFO *MapInfo1; + CONST TX_BUF_MAP_INFO *MapInfo2; + + MapInfo1 = UserStruct1; + MapInfo2 = UserStruct2; + + return MapInfo1->DescIdx < MapInfo2->DescIdx ? -1 : + MapInfo1->DescIdx > MapInfo2->DescIdx ? 1 : + 0; +} -- 2.9.4