VirtualBox

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

Last change on this file since 25270 was 25181, checked in by vboxsync, 15 years ago

Fix warnings.

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