VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxNetAdp/solaris/VBoxNetAdp-solaris.c@ 30084

Last change on this file since 30084 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.4 KB
Line 
1/* $Id: VBoxNetAdp-solaris.c 28800 2010-04-27 08:22:32Z vboxsync $ */
2/** @file
3 * VBoxNetAdapter - Network Adapter Driver (Host), Solaris Specific Code.
4 */
5
6/*
7 * Copyright (C) 2009 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#define LOG_GROUP LOG_GROUP_NET_ADP_DRV
22#include <VBox/log.h>
23#include <VBox/err.h>
24#include <VBox/version.h>
25#include <iprt/assert.h>
26#include <iprt/semaphore.h>
27#include <iprt/initterm.h>
28#include <iprt/assert.h>
29#include <iprt/mem.h>
30#include <iprt/rand.h>
31
32#include <sys/types.h>
33#include <sys/dlpi.h>
34#include <sys/types.h>
35#include <sys/param.h>
36#include <sys/stat.h>
37#include <sys/stream.h>
38#include <sys/stropts.h>
39#include <sys/strsun.h>
40#include <sys/modctl.h>
41#include <sys/ddi.h>
42#include <sys/sunddi.h>
43#include <sys/sunldi.h>
44#include <sys/gld.h>
45
46#include "../VBoxNetAdpInternal.h"
47
48/*******************************************************************************
49* Defined Constants And Macros *
50*******************************************************************************/
51#define DEVICE_NAME "vboxnet"
52/** The module descriptions as seen in 'modinfo'. */
53#define DEVICE_DESC_DRV "VirtualBox NetAdp"
54#define VBOXNETADP_MTU 1500
55
56#if defined(DEBUG_ramshankar)
57# undef LogFlowFunc
58# define LogFlowFunc LogRel
59# undef Log
60# define Log LogRel
61# undef LogFlow
62# define LogFlow LogRel
63#endif
64
65static int VBoxNetAdpSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
66static int VBoxNetAdpSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
67
68/**
69 * Streams: module info.
70 */
71static struct module_info g_VBoxNetAdpSolarisModInfo =
72{
73 0x0dd, /* module id */
74 DEVICE_NAME,
75 0, /* min. packet size */
76 INFPSZ, /* max. packet size */
77 0, /* hi-water mark */
78 0 /* lo-water mark */
79};
80
81/**
82 * Streams: read queue hooks.
83 */
84static struct qinit g_VBoxNetAdpSolarisReadQ =
85{
86 NULL, /* read */
87 gld_rsrv,
88 gld_open,
89 gld_close,
90 NULL, /* admin (reserved) */
91 &g_VBoxNetAdpSolarisModInfo,
92 NULL /* module stats */
93};
94
95/**
96 * Streams: write queue hooks.
97 */
98static struct qinit g_VBoxNetAdpSolarisWriteQ =
99{
100 gld_wput,
101 gld_wsrv,
102 NULL, /* open */
103 NULL, /* close */
104 NULL, /* admin (reserved) */
105 &g_VBoxNetAdpSolarisModInfo,
106 NULL /* module stats */
107};
108
109/**
110 * Streams: IO stream tab.
111 */
112static struct streamtab g_VBoxNetAdpSolarisStreamTab =
113{
114 &g_VBoxNetAdpSolarisReadQ,
115 &g_VBoxNetAdpSolarisWriteQ,
116 NULL, /* muxread init */
117 NULL /* muxwrite init */
118};
119
120/**
121 * cb_ops: driver char/block entry points
122 */
123static struct cb_ops g_VBoxNetAdpSolarisCbOps =
124{
125 nulldev, /* cb open */
126 nulldev, /* cb close */
127 nodev, /* b strategy */
128 nodev, /* b dump */
129 nodev, /* b print */
130 nodev, /* cb read */
131 nodev, /* cb write */
132 nodev, /* cb ioctl */
133 nodev, /* c devmap */
134 nodev, /* c mmap */
135 nodev, /* c segmap */
136 nochpoll, /* c poll */
137 ddi_prop_op, /* property ops */
138 &g_VBoxNetAdpSolarisStreamTab,
139 D_MP, /* compat. flag */
140 CB_REV /* revision */
141};
142
143/**
144 * dev_ops: driver entry/exit and other ops.
145 */
146static struct dev_ops g_VBoxNetAdpSolarisDevOps =
147{
148 DEVO_REV, /* driver build revision */
149 0, /* ref count */
150 gld_getinfo,
151 nulldev, /* identify */
152 nulldev, /* probe */
153 VBoxNetAdpSolarisAttach,
154 VBoxNetAdpSolarisDetach,
155 nodev, /* reset */
156 &g_VBoxNetAdpSolarisCbOps,
157 (struct bus_ops *)0,
158 nodev /* power */
159};
160
161/**
162 * modldrv: export driver specifics to kernel
163 */
164static struct modldrv g_VBoxNetAdpSolarisDriver =
165{
166 &mod_driverops, /* extern from kernel */
167 DEVICE_DESC_DRV " " VBOX_VERSION_STRING "r" RT_XSTR(VBOX_SVN_REV),
168 &g_VBoxNetAdpSolarisDevOps
169};
170
171/**
172 * modlinkage: export install/remove/info to the kernel
173 */
174static struct modlinkage g_VBoxNetAdpSolarisModLinkage =
175{
176 MODREV_1, /* loadable module system revision */
177 {
178 &g_VBoxNetAdpSolarisDriver, /* adapter streams driver framework */
179 NULL /* terminate array of linkage structures */
180 }
181};
182
183
184/*******************************************************************************
185* Global Variables *
186*******************************************************************************/
187/** The default ethernet broadcast address */
188static uchar_t achBroadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
189
190/**
191 * vboxnetadp_state_t: per-instance data
192 */
193typedef struct vboxnetadp_state_t
194{
195 dev_info_t *pDip; /* device info. */
196 RTMAC FactoryMac; /* default 'factory' MAC address */
197 RTMAC CurrentMac; /* current MAC address */
198} vboxnetadp_state_t;
199
200
201/*******************************************************************************
202* Internal Functions *
203*******************************************************************************/
204static int vboxNetAdpSolarisGenerateMac(PRTMAC pMac);
205static int vboxNetAdpSolarisSetMacAddress(gld_mac_info_t *pMacInfo, unsigned char *pszMacAddr);
206static int vboxNetAdpSolarisSend(gld_mac_info_t *pMacInfo, mblk_t *pMsg);
207static int vboxNetAdpSolarisStub(gld_mac_info_t *pMacInfo);
208static int vboxNetAdpSolarisSetPromisc(gld_mac_info_t *pMacInfo, int fPromisc);
209static int vboxNetAdpSolarisSetMulticast(gld_mac_info_t *pMacInfo, unsigned char *pMulticastAddr, int fMulticast);
210
211
212/**
213 * Kernel entry points
214 */
215int _init(void)
216{
217 LogFlowFunc((DEVICE_NAME ":_init\n"));
218
219 /*
220 * Prevent module autounloading.
221 */
222 modctl_t *pModCtl = mod_getctl(&g_VBoxNetAdpSolarisModLinkage);
223 if (pModCtl)
224 pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
225 else
226 LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
227
228 /*
229 * Initialize IPRT.
230 */
231 int rc = RTR0Init(0);
232 if (RT_SUCCESS(rc))
233 {
234 rc = mod_install(&g_VBoxNetAdpSolarisModLinkage);
235 if (!rc)
236 return rc;
237
238 LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
239 RTR0Term();
240 }
241 else
242 LogRel((DEVICE_NAME ":failed to initialize IPRT (rc=%d)\n", rc));
243
244 return RTErrConvertToErrno(rc);
245}
246
247
248int _fini(void)
249{
250 LogFlowFunc((DEVICE_NAME ":_fini\n"));
251
252 /*
253 * Undo the work done during start (in reverse order).
254 */
255 RTR0Term();
256
257 return mod_remove(&g_VBoxNetAdpSolarisModLinkage);
258}
259
260
261int _info(struct modinfo *pModInfo)
262{
263 LogFlowFunc((DEVICE_NAME ":_info\n"));
264
265 int rc = mod_info(&g_VBoxNetAdpSolarisModLinkage, pModInfo);
266
267 LogFlow((DEVICE_NAME ":_info returns %d\n", rc));
268 return rc;
269}
270
271
272/**
273 * Attach entry point, to attach a device to the system or resume it.
274 *
275 * @param pDip The module structure instance.
276 * @param enmCmd Operation type (attach/resume).
277 *
278 * @returns corresponding solaris error code.
279 */
280static int VBoxNetAdpSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
281{
282 LogFlowFunc((DEVICE_NAME ":VBoxNetAdpSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
283
284 int rc = -1;
285 switch (enmCmd)
286 {
287 case DDI_ATTACH:
288 {
289 gld_mac_info_t *pMacInfo = gld_mac_alloc(pDip);
290 if (pMacInfo)
291 {
292 vboxnetadp_state_t *pState = RTMemAllocZ(sizeof(vboxnetadp_state_t));
293 if (pState)
294 {
295 pState->pDip = pDip;
296
297 /*
298 * Setup GLD MAC layer registeration info.
299 */
300 pMacInfo->gldm_reset = vboxNetAdpSolarisStub;
301 pMacInfo->gldm_start = vboxNetAdpSolarisStub;
302 pMacInfo->gldm_stop = vboxNetAdpSolarisStub;
303 pMacInfo->gldm_set_mac_addr = vboxNetAdpSolarisSetMacAddress;
304 pMacInfo->gldm_set_multicast = vboxNetAdpSolarisSetMulticast;
305 pMacInfo->gldm_set_promiscuous = vboxNetAdpSolarisSetPromisc;
306 pMacInfo->gldm_send = vboxNetAdpSolarisSend;
307 pMacInfo->gldm_intr = NULL;
308 pMacInfo->gldm_get_stats = NULL;
309 pMacInfo->gldm_ioctl = NULL;
310 pMacInfo->gldm_ident = DEVICE_NAME;
311 pMacInfo->gldm_type = DL_ETHER;
312 pMacInfo->gldm_minpkt = 0;
313 pMacInfo->gldm_maxpkt = VBOXNETADP_MTU;
314
315 AssertCompile(sizeof(RTMAC) == ETHERADDRL);
316
317 pMacInfo->gldm_addrlen = ETHERADDRL;
318 pMacInfo->gldm_saplen = -2;
319 pMacInfo->gldm_broadcast_addr = achBroadcastAddr;
320 pMacInfo->gldm_ppa = ddi_get_instance(pState->pDip);
321 pMacInfo->gldm_devinfo = pState->pDip;
322 pMacInfo->gldm_private = (caddr_t)pState;
323
324 /*
325 * We use a semi-random MAC addresses similar to a guest NIC's MAC address
326 * as the default factory address of the interface.
327 */
328 rc = vboxNetAdpSolarisGenerateMac(&pState->FactoryMac);
329 if (RT_SUCCESS(rc))
330 {
331 bcopy(&pState->FactoryMac, &pState->CurrentMac, sizeof(RTMAC));
332 pMacInfo->gldm_vendor_addr = (unsigned char *)&pState->FactoryMac;
333
334 /*
335 * Now try registering our GLD with the MAC layer.
336 * Registeration can fail on some S10 versions when the MTU size is more than 1500.
337 * When we implement jumbo frames we should probably retry with MTU 1500 for S10.
338 */
339 rc = gld_register(pDip, (char *)ddi_driver_name(pDip), pMacInfo);
340 if (rc == DDI_SUCCESS)
341 {
342 ddi_report_dev(pDip);
343 return DDI_SUCCESS;
344 }
345 else
346 LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to register GLD. rc=%d\n", rc));
347 }
348 else
349 LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to generate mac address.rc=%d\n"));
350
351 RTMemFree(pState);
352 }
353 else
354 LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to alloc state.\n"));
355
356 gld_mac_free(pMacInfo);
357 }
358 else
359 LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to alloc mac structure.\n"));
360 return DDI_FAILURE;
361 }
362
363 case DDI_RESUME:
364 {
365 /* Nothing to do here... */
366 return DDI_SUCCESS;
367 }
368
369 /* case DDI_PM_RESUME: */
370 default:
371 return DDI_FAILURE;
372 }
373}
374
375
376/**
377 * Detach entry point, to detach a device to the system or suspend it.
378 *
379 * @param pDip The module structure instance.
380 * @param enmCmd Operation type (detach/suspend).
381 *
382 * @returns corresponding solaris error code.
383 */
384static int VBoxNetAdpSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
385{
386 LogFlowFunc((DEVICE_NAME ":VBoxNetAdpSolarisDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
387
388 switch (enmCmd)
389 {
390 case DDI_DETACH:
391 {
392 /*
393 * Unregister and clean up.
394 */
395 gld_mac_info_t *pMacInfo = ddi_get_driver_private(pDip);
396 if (pMacInfo)
397 {
398 vboxnetadp_state_t *pState = (vboxnetadp_state_t *)pMacInfo->gldm_private;
399 if (pState)
400 {
401 int rc = gld_unregister(pMacInfo);
402 if (rc == DDI_SUCCESS)
403 {
404 gld_mac_free(pMacInfo);
405 RTMemFree(pState);
406 return DDI_SUCCESS;
407 }
408 else
409 LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to unregister GLD from MAC layer.rc=%d\n", rc));
410 }
411 else
412 LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to get internal state.\n"));
413 }
414 else
415 LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to get driver private GLD data.\n"));
416
417 return DDI_FAILURE;
418 }
419
420 case DDI_RESUME:
421 {
422 /* Nothing to do here... */
423 return DDI_SUCCESS;
424 }
425
426 /* case DDI_SUSPEND: */
427 /* case DDI_HOTPLUG_DETACH: */
428 default:
429 return DDI_FAILURE;
430 }
431}
432
433
434static int vboxNetAdpSolarisGenerateMac(PRTMAC pMac)
435{
436 pMac->au8[0] = 0x08;
437 pMac->au8[1] = 0x00;
438 pMac->au8[2] = 0x27;
439 RTRandBytes(&pMac->au8[3], 3);
440 LogFlow((DEVICE_NAME ":VBoxNetAdpSolarisGenerateMac Generated %.*Rhxs\n", sizeof(RTMAC), &pMac));
441 return VINF_SUCCESS;
442}
443
444
445static int vboxNetAdpSolarisSetMacAddress(gld_mac_info_t *pMacInfo, unsigned char *pszMacAddr)
446{
447 vboxnetadp_state_t *pState = (vboxnetadp_state_t *)pMacInfo->gldm_private;
448 if (pState)
449 {
450 bcopy(pszMacAddr, &pState->CurrentMac, sizeof(RTMAC));
451 LogFlow((DEVICE_NAME ":vboxNetAdpSolarisSetMacAddress updated MAC %.*Rhxs\n", sizeof(RTMAC), &pState->CurrentMac));
452 return GLD_SUCCESS;
453 }
454 else
455 LogRel((DEVICE_NAME ":vboxNetAdpSolarisSetMacAddress failed to get internal state.\n"));
456 return GLD_FAILURE;
457}
458
459
460static int vboxNetAdpSolarisSend(gld_mac_info_t *pMacInfo, mblk_t *pMsg)
461{
462 freemsg(pMsg);
463 return GLD_SUCCESS;
464}
465
466
467static int vboxNetAdpSolarisStub(gld_mac_info_t *pMacInfo)
468{
469 return GLD_SUCCESS;
470}
471
472
473static int vboxNetAdpSolarisSetMulticast(gld_mac_info_t *pMacInfo, unsigned char *pMulticastAddr, int fMulticast)
474{
475 return GLD_SUCCESS;
476}
477
478
479static int vboxNetAdpSolarisSetPromisc(gld_mac_info_t *pMacInfo, int fPromisc)
480{
481 /* Host requesting promiscuous intnet connection... */
482 return GLD_SUCCESS;
483}
484
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