VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/DrvDedicatedNic.cpp@ 97441

Last change on this file since 97441 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.4 KB
Line 
1/* $Id: DrvDedicatedNic.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * DrvDedicatedNic - Experimental network driver for using a dedicated (V)NIC.
4 */
5
6/*
7 * Copyright (C) 2010-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DEFAULT
33#include <VBox/log.h>
34#include <VBox/vmm/pdmcritsect.h>
35#include <VBox/vmm/pdmdrv.h>
36#include <VBox/vmm/pdmnetifs.h>
37#include <VBox/vmm/pdmnetinline.h>
38#include <VBox/intnet.h>
39#include <VBox/intnetinline.h>
40
41#include <iprt/asm.h>
42#include <iprt/assert.h>
43#include <iprt/mem.h>
44#include <iprt/path.h>
45#include <iprt/string.h>
46#include <iprt/thread.h>
47#include <iprt/uuid.h>
48
49#include "VBoxDD.h"
50
51
52/*********************************************************************************************************************************
53* Structures and Typedefs *
54*********************************************************************************************************************************/
55/**
56 * Instance data for the dedicated (V)NIC driver.
57 *
58 * @implements PDMINETWORKUP
59 */
60typedef struct DRVDEDICATEDNIC
61{
62 /** The network interface. */
63 PDMINETWORKUP INetworkUpR3;
64 /** The network interface. */
65 R3PTRTYPE(PPDMINETWORKDOWN) pIAboveNet;
66 /** The network config interface.
67 * Can (in theory at least) be NULL. */
68 R3PTRTYPE(PPDMINETWORKCONFIG) pIAboveConfigR3;
69 /** Pointer to the driver instance. */
70 PPDMDRVINSR3 pDrvInsR3;
71 /** Ring-3 base interface for the ring-0 context. */
72 PDMIBASER0 IBaseR0;
73 /** Ring-3 base interface for the raw-mode context. */
74 PDMIBASERC IBaseRC;
75 RTR3PTR R3PtrAlignment;
76
77
78 /** The network interface for the ring-0 context. */
79 PDMINETWORKUPR0 INetworkUpR0;
80 /** Pointer to the driver instance. */
81 PPDMDRVINSR0 pDrvInsR0;
82 RTR0PTR R0PtrAlignment;
83
84 /** The interface we're talking to. */
85 R0PTRTYPE(PINTNETTRUNKIFPORT) pIfPortR0;
86 /** Set if the link is up, clear if its down. */
87 bool fLinkDown;
88 /** Set if the current transmit operation is done the XMIT thread. If clear,
89 * we assume its an EMT. */
90 bool fXmitOnXmitThread;
91 /** The name of the interface that we're connected to. */
92 char szIfName[128 + 8 - 2];
93
94 /** Critical section serializing transmission. */
95 PDMCRITSECT XmitLock;
96 /** The transmit scatter gather buffer (ring-3 -> ring-0). */
97 PDMSCATTERGATHER XmitSg;
98 /** The transmit GSO context (when applicable). */
99 PDMNETWORKGSO XmitGso;
100 /** The transmit buffer (ring-3 -> ring-0). */
101 uint8_t abXmitBuf[_64K];
102
103 /** The receive scatter gather buffer. */
104 PDMSCATTERGATHER RecvSg;
105 /** The receive buffer (ring-0 -> ring-3). */
106 uint8_t abRecvBuf[_64K];
107
108} DRVDEDICATEDNIC;
109/** Pointer to the instance data for the dedicated (V)NIC driver. */
110typedef DRVDEDICATEDNIC *PDRVDEDICATEDNIC;
111
112/**
113 * Ring-0 operations.
114 */
115typedef enum DRVDEDICATEDNICR0OP
116{
117 /** Invalid zero value.. */
118 DRVDEDICATEDNICR0OP_INVALID = 0,
119 /** Initialize the connection to the NIC. */
120 DRVDEDICATEDNICR0OP_INIT,
121 /** Terminate the connection to the NIC. */
122 DRVDEDICATEDNICR0OP_TERM,
123 /** Suspend the operation. */
124 DRVDEDICATEDNICR0OP_SUSPEND,
125 /** Resume the operation. */
126 DRVDEDICATEDNICR0OP_RESUME,
127 /** Wait for and do receive work.
128 * We do this in ring-0 instead of ring-3 to save 1-2 buffer copies and
129 * unnecessary context switching. */
130 DRVDEDICATEDNICR0OP_RECV,
131 /** Wait for and do transmit work.
132 * We do this in ring-0 instead of ring-3 to save 1-2 buffer copies and
133 * unnecessary context switching. */
134 DRVDEDICATEDNICR0OP_SEND,
135 /** Changes the promiscuousness of the interface (guest point of view). */
136 DRVDEDICATEDNICR0OP_PROMISC,
137 /** End of the valid operations. */
138 DRVDEDICATEDNICR0OP_END,
139 /** The usual 32-bit hack. */
140 DRVDEDICATEDNICR0OP_32BIT_HACK = 0x7fffffff
141} DRVDEDICATEDNICR0OP;
142
143
144
145#ifdef IN_RING0
146
147/**
148 * @interface_method_impl{FNPDMDRVREQHANDLERR0}
149 */
150PDMBOTHCBDECL(int) drvR0DedicatedNicReqHandler(PPDMDRVINS pDrvIns, uint32_t uOperation, uint64_t u64Arg)
151{
152 RT_NOREF_PV(pDrvIns); RT_NOREF_PV(u64Arg);
153 switch ((DRVDEDICATEDNICR0OP)uOperation)
154 {
155 case DRVDEDICATEDNICR0OP_INIT:
156 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqInit(pDrvIns, u64Arg);
157
158 case DRVDEDICATEDNICR0OP_TERM:
159 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqTerm(pDrvIns);
160
161 case DRVDEDICATEDNICR0OP_SUSPEND:
162 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqSuspend(pDrvIns);
163
164 case DRVDEDICATEDNICR0OP_RESUME:
165 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqResume(pDrvIns);
166
167 case DRVDEDICATEDNICR0OP_RECV:
168 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqRecv(pDrvIns);
169
170 case DRVDEDICATEDNICR0OP_SEND:
171 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqSend(pDrvIns);
172
173 case DRVDEDICATEDNICR0OP_PROMISC:
174 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqPromisc(pDrvIns, !!u64Arg);
175
176 case DRVDEDICATEDNICR0OP_END:
177 default:
178 return VERR_INVALID_FUNCTION;
179 }
180}
181
182#endif /* IN_RING0 */
183
184
185
186#if 0 /* currently unused */
187
188/* -=-=-=-=- PDMINETWORKUP -=-=-=-=- */
189
190/**
191 * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit}
192 */
193PDMBOTHCBDECL(int) drvDedicatedNicUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
194{
195 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
196 int rc = PDMCritSectTryEnter(&pThis->XmitLock);
197 if (RT_SUCCESS(rc))
198 ASMAtomicUoWriteBool(&pThis->fXmitOnXmitThread, fOnWorkerThread);
199 return rc;
200}
201
202
203/**
204 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
205 */
206PDMBOTHCBDECL(int) drvDedicatedNicUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
207 PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
208{
209 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
210 Assert(PDMCritSectIsOwner(&pThis->XmitLock));
211
212 /*
213 * If the net is down, we can return immediately.
214 */
215 if (pThis->fLinkDown)
216 return VERR_NET_DOWN;
217
218#ifdef IN_RING0
219 /** @todo Ask the driver for a buffer, atomically if we're called on EMT. */
220 RT_NOREF_PV(cbMin); RT_NOREF_PV(pGso); RT_NOREF_PV(ppSgBuf);
221 return VERR_TRY_AGAIN;
222
223#else /* IN_RING3 */
224 /*
225 * Are we busy or is the request too big?
226 */
227 if (RT_UNLIKELY((pThis->XmitSg.fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC))
228 return VERR_TRY_AGAIN;
229 if (cbMin > sizeof(pThis->abXmitBuf))
230 return VERR_NO_MEMORY;
231
232 /*
233 * Initialize the S/G buffer and return.
234 */
235 pThis->XmitSg.fFlags = PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1;
236 pThis->XmitSg.cbUsed = 0;
237 pThis->XmitSg.cbAvailable = sizeof(pThis->abXmitBuf);
238 pThis->XmitSg.pvAllocator = NULL;
239 if (!pGso)
240 {
241 pThis->XmitSg.pvUser = NULL;
242 pThis->XmitGso.u8Type = PDMNETWORKGSOTYPE_INVALID;
243 }
244 else
245 {
246 pThis->XmitSg.pvUser = &pThis->XmitGso;
247 pThis->XmitGso = *pGso;
248 }
249 pThis->XmitSg.cSegs = 1;
250 pThis->XmitSg.aSegs[0].cbSeg = pThis->XmitSg.cbAvailable;
251 pThis->XmitSg.aSegs[0].pvSeg = &pThis->abXmitBuf[0];
252
253# if 0 /* poison */
254 memset(pThis->XmitSg.aSegs[0].pvSeg, 'F', pThis->XmitSg.aSegs[0].cbSeg);
255# endif
256
257 *ppSgBuf = &pThis->XmitSg;
258 return VINF_SUCCESS;
259#endif /* IN_RING3 */
260}
261
262
263/**
264 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
265 */
266PDMBOTHCBDECL(int) drvDedicatedNicUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
267{
268#ifdef VBOX_STRICT
269 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
270 Assert(pSgBuf->fFlags == (PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1));
271 Assert(pSgBuf->cbUsed <= pSgBuf->cbAvailable);
272 Assert(PDMCritSectIsOwner(&pThis->XmitLock));
273#else
274 RT_NOREF1(pInterface);
275#endif
276
277 if (pSgBuf)
278 {
279#ifdef IN_RING0
280 // ...
281#else
282 Assert(pSgBuf == &pThis->XmitSg);
283 Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC);
284 pSgBuf->fFlags = 0;
285#endif
286 }
287
288 return VINF_SUCCESS;
289}
290
291
292/**
293 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
294 */
295PDMBOTHCBDECL(int) drvDedicatedNicUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
296{
297 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
298 STAM_PROFILE_START(&pThis->StatTransmit, a);
299
300 AssertPtr(pSgBuf);
301 Assert(pSgBuf->fFlags == (PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1));
302 Assert(pSgBuf->cbUsed <= pSgBuf->cbAvailable);
303#ifdef IN_RING0
304 Assert(pSgBuf == &pThis->XmitSg);
305#endif
306 Assert(PDMCritSectIsOwner(&pThis->XmitLock));
307
308#ifdef IN_RING0
309 /*
310 * Tell the driver to send the packet.
311 */
312 RT_NOREF_PV(pThis); RT_NOREF_PV(pSgBuf); RT_NOREF_PV(fOnWorkerThread);
313 return VERR_INTERNAL_ERROR_4;
314
315#else /* IN_RING3 */
316 NOREF(fOnWorkerThread);
317
318 /*
319 * Call ring-0 to start the transfer.
320 */
321 int rc = PDMDrvHlpCallR0(pThis->pDrvInsR3, DRVDEDICATEDNICR0OP_SEND, pSgBuf->cbUsed);
322 if (RT_FAILURE(rc) && rc != VERR_NET_DOWN)
323 rc = VERR_NET_NO_BUFFER_SPACE;
324 pSgBuf->fFlags = 0;
325 return rc;
326#endif /* IN_RING3 */
327}
328
329
330/**
331 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
332 */
333PDMBOTHCBDECL(void) drvDedicatedNicUp_EndXmit(PPDMINETWORKUP pInterface)
334{
335 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
336 ASMAtomicUoWriteBool(&pThis->fXmitOnXmitThread, false);
337 PDMCritSectLeave(&pThis->XmitLock);
338}
339
340
341/**
342 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
343 */
344PDMBOTHCBDECL(void) drvDedicatedNicUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
345{
346 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
347 /** @todo enable/disable promiscuous mode (should be easy) */
348 NOREF(pThis); RT_NOREF_PV(fPromiscuous);
349}
350
351#endif /* unused */
352#ifdef IN_RING3
353# if 0 /* currently unused */
354
355/**
356 * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged}
357 */
358static DECLCALLBACK(void) drvR3DedicatedNicUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
359{
360 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
361 bool fLinkDown;
362 switch (enmLinkState)
363 {
364 case PDMNETWORKLINKSTATE_DOWN:
365 case PDMNETWORKLINKSTATE_DOWN_RESUME:
366 fLinkDown = true;
367 break;
368 default:
369 AssertMsgFailed(("enmLinkState=%d\n", enmLinkState));
370 case PDMNETWORKLINKSTATE_UP:
371 fLinkDown = false;
372 break;
373 }
374 LogFlow(("drvR3DedicatedNicUp_NotifyLinkChanged: enmLinkState=%d %d->%d\n", enmLinkState, pThis->fLinkDown, fLinkDown));
375 ASMAtomicWriteBool(&pThis->fLinkDown, fLinkDown);
376}
377
378
379/* -=-=-=-=- PDMIBASER0 -=-=-=-=- */
380
381/**
382 * @interface_method_impl{PDMIBASER0,pfnQueryInterface}
383 */
384static DECLCALLBACK(RTR0PTR) drvR3DedicatedNicIBaseR0_QueryInterface(PPDMIBASER0 pInterface, const char *pszIID)
385{
386 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, IBaseR0);
387 PDMIBASER0_RETURN_INTERFACE(pThis->pDrvInsR3, pszIID, PDMINETWORKUP, &pThis->INetworkUpR0);
388 return NIL_RTR0PTR;
389}
390
391
392/* -=-=-=-=- PDMIBASE -=-=-=-=- */
393
394/**
395 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
396 */
397static DECLCALLBACK(void *) drvR3DedicatedNicIBase_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
398{
399 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
400 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
401
402 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
403 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASER0, &pThis->IBaseR0);
404 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUpR3);
405 return NULL;
406}
407
408# endif /* Currently unused */
409
410
411/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
412
413/**
414 * @interface_method_impl{PDMDRVREG,pfnPowerOff}
415 */
416static DECLCALLBACK(void) drvR3DedicatedNicPowerOff(PPDMDRVINS pDrvIns)
417{
418 LogFlow(("drvR3DedicatedNicPowerOff\n"));
419 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_SUSPEND, 0);
420 AssertRC(rc);
421}
422
423
424/**
425 * @interface_method_impl{PDMDRVREG,pfnResume}
426 */
427static DECLCALLBACK(void) drvR3DedicatedNicResume(PPDMDRVINS pDrvIns)
428{
429 LogFlow(("drvR3DedicatedNicPowerResume\n"));
430 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_RESUME, 0);
431 AssertRC(rc);
432}
433
434
435/**
436 * @interface_method_impl{PDMDRVREG,pfnSuspend}
437 */
438static DECLCALLBACK(void) drvR3DedicatedNicSuspend(PPDMDRVINS pDrvIns)
439{
440 LogFlow(("drvR3DedicatedNicPowerSuspend\n"));
441 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_SUSPEND, 0);
442 AssertRC(rc);
443}
444
445
446/**
447 * @interface_method_impl{PDMDRVREG,pfnPowerOn}
448 */
449static DECLCALLBACK(void) drvR3DedicatedNicPowerOn(PPDMDRVINS pDrvIns)
450{
451 LogFlow(("drvR3DedicatedNicPowerOn\n"));
452 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_RESUME, 0);
453 AssertRC(rc);
454}
455
456
457/**
458 * @interface_method_impl{PDMDRVREG,pfnDestruct}
459 */
460static DECLCALLBACK(void) drvR3DedicatedNicDestruct(PPDMDRVINS pDrvIns)
461{
462 LogFlow(("drvR3DedicatedNicDestruct\n"));
463 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
464 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
465
466 if (pThis->pIfPortR0)
467 {
468 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_TERM, 0);
469 AssertRC(rc);;
470 }
471}
472
473
474/**
475 * @interface_method_impl{PDMDRVREG,pfnConstruct}
476 */
477static DECLCALLBACK(int) drvR3DedicatedNicConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
478{
479 RT_NOREF(pCfg, fFlags);
480 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
481 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
482
483 /*
484 * Init the static parts.
485 */
486 pThis->pDrvInsR3 = pDrvIns;
487 pThis->pDrvInsR0 = PDMDRVINS_2_R0PTR(pDrvIns);
488#if 0
489 pThis->hRecvThread = NIL_RTTHREAD;
490 pThis->hRecvEvt = NIL_RTSEMEVENT;
491 pThis->pXmitThread = NULL;
492 pThis->hXmitEvt = NIL_SUPSEMEVENT;
493 pThis->pSupDrvSession = PDMDrvHlpGetSupDrvSession(pDrvIns);
494 pThis->hSgCache = NIL_RTMEMCACHE;
495 pThis->enmRecvState = RECVSTATE_SUSPENDED;
496 pThis->fActivateEarlyDeactivateLate = false;
497 /* IBase* */
498 pDrvIns->IBase.pfnQueryInterface = drvR3DedicatedNicIBase_QueryInterface;
499 pThis->IBaseR0.pfnQueryInterface = drvR3DedicatedNicIBaseR0_QueryInterface;
500 pThis->IBaseRC.pfnQueryInterface = drvR3DedicatedNicIBaseRC_QueryInterface;
501 /* INetworkUp */
502 pThis->INetworkUpR3.pfnBeginXmit = drvDedicatedNic_BeginXmit;
503 pThis->INetworkUpR3.pfnAllocBuf = drvDedicatedNic_AllocBuf;
504 pThis->INetworkUpR3.pfnFreeBuf = drvDedicatedNic_FreeBuf;
505 pThis->INetworkUpR3.pfnSendBuf = drvDedicatedNic_SendBuf;
506 pThis->INetworkUpR3.pfnEndXmit = drvDedicatedNic_EndXmit;
507 pThis->INetworkUpR3.pfnSetPromiscuousMode = drvDedicatedNic_SetPromiscuousMode;
508 pThis->INetworkUpR3.pfnNotifyLinkChanged = drvR3DedicatedNicUp_NotifyLinkChanged;
509#endif
510
511 /** @todo
512 * Need to create a generic way of calling into the ring-0 side of the driver so
513 * we can initialize the thing as well as send and receive. Hmm ... the
514 * sending could be done more efficiently from a ring-0 kernel thread actually
515 * (saves context switching and 1-2 copy operations). Ditto for receive, except
516 * we need to tie the thread to the process or we cannot access the guest ram so
517 * easily.
518 */
519
520 return VERR_NOT_IMPLEMENTED;
521}
522
523
524
525/**
526 * Internal networking transport driver registration record.
527 */
528const PDMDRVREG g_DrvDedicatedNic =
529{
530 /* u32Version */
531 PDM_DRVREG_VERSION,
532 /* szName */
533 "DedicatedNic",
534 /* szRCMod */
535 "",
536 /* szR0Mod */
537 "VBoxDDR0.r0",
538 /* pszDescription */
539 "Dedicated (V)NIC Driver",
540 /* fFlags */
541 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DRVREG_FLAGS_R0,
542 /* fClass. */
543 PDM_DRVREG_CLASS_NETWORK,
544 /* cMaxInstances */
545 ~0U,
546 /* cbInstance */
547 sizeof(DRVDEDICATEDNIC),
548 /* pfnConstruct */
549 drvR3DedicatedNicConstruct,
550 /* pfnDestruct */
551 drvR3DedicatedNicDestruct,
552 /* pfnRelocate */
553 NULL,
554 /* pfnIOCtl */
555 NULL,
556 /* pfnPowerOn */
557 drvR3DedicatedNicPowerOn,
558 /* pfnReset */
559 NULL,
560 /* pfnSuspend */
561 drvR3DedicatedNicSuspend,
562 /* pfnResume */
563 drvR3DedicatedNicResume,
564 /* pfnAttach */
565 NULL,
566 /* pfnDetach */
567 NULL,
568 /* pfnPowerOff */
569 drvR3DedicatedNicPowerOff,
570 /* pfnSoftReset */
571 NULL,
572 /* u32EndVersion */
573 PDM_DRVREG_VERSION
574};
575
576#endif /* IN_RING3 */
577
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette