VirtualBox

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

Last change on this file since 28112 was 26710, checked in by vboxsync, 15 years ago

HostDrivers/solaris: LogFlowFunc.

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