15084Sjohnlev /*
25084Sjohnlev * CDDL HEADER START
35084Sjohnlev *
45084Sjohnlev * The contents of this file are subject to the terms of the
55084Sjohnlev * Common Development and Distribution License (the "License").
65084Sjohnlev * You may not use this file except in compliance with the License.
75084Sjohnlev *
85084Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95084Sjohnlev * or http://www.opensolaris.org/os/licensing.
105084Sjohnlev * See the License for the specific language governing permissions
115084Sjohnlev * and limitations under the License.
125084Sjohnlev *
135084Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each
145084Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155084Sjohnlev * If applicable, add the following below this CDDL HEADER, with the
165084Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying
175084Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner]
185084Sjohnlev *
195084Sjohnlev * CDDL HEADER END
205084Sjohnlev */
215084Sjohnlev
225084Sjohnlev /*
23*7656SSherry.Moore@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
245084Sjohnlev * Use is subject to license terms.
255084Sjohnlev */
265084Sjohnlev
275084Sjohnlev
285084Sjohnlev /*
295084Sjohnlev * Xen network backend - ioemu version.
305084Sjohnlev *
315084Sjohnlev * HVM guest domains use an emulated network device (typically the
325084Sjohnlev * rtl8139) to access the physical network via IO emulation running in
335084Sjohnlev * a backend domain (generally domain 0).
345084Sjohnlev *
355084Sjohnlev * The IO emulation code sends and receives packets using DLPI, usually
365084Sjohnlev * through a virtual NIC (vnic).
375084Sjohnlev *
385084Sjohnlev * The creation of the relevant vnic to correspond to the network interface
395084Sjohnlev * in the guest domain requires the use of 'hotplug' scripts in the backend
405084Sjohnlev * domain. This driver ensures that the hotplug scripts are run when
415084Sjohnlev * such guest domains are created.
425084Sjohnlev *
435084Sjohnlev * It is used as a result of the 'compatible' property associated with
445084Sjohnlev * IO emulated devices. See /etc/driver_aliases and common/xen/os/xvdi.c.
455084Sjohnlev */
465084Sjohnlev
475084Sjohnlev #ifdef DEBUG
485084Sjohnlev #define XNBE_DEBUG 1
495084Sjohnlev #endif /* DEBUG */
505084Sjohnlev
515084Sjohnlev #include <sys/types.h>
525084Sjohnlev #include <sys/conf.h>
535084Sjohnlev #include <sys/sunddi.h>
545084Sjohnlev #include <sys/modctl.h>
555084Sjohnlev #include <xen/sys/xendev.h>
565084Sjohnlev #ifdef XNBE_DEBUG
575084Sjohnlev #include <sys/cmn_err.h>
585084Sjohnlev #endif /* XNBE_DEBUG */
595084Sjohnlev
605084Sjohnlev #ifdef XNBE_DEBUG
615084Sjohnlev int xnbe_debug = 0;
625084Sjohnlev #endif /* XNBE_DEBUG */
635084Sjohnlev
645084Sjohnlev static int
xnbe_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)655084Sjohnlev xnbe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
665084Sjohnlev {
675084Sjohnlev #ifdef XNBE_DEBUG
685084Sjohnlev if (xnbe_debug > 0)
695084Sjohnlev cmn_err(CE_NOTE, "xnbe_attach: dip 0x%p, cmd %d",
705084Sjohnlev (void *)dip, cmd);
715084Sjohnlev #endif /* XNBE_DEBUG */
725084Sjohnlev
735084Sjohnlev switch (cmd) {
745084Sjohnlev case DDI_ATTACH:
755084Sjohnlev break;
765084Sjohnlev case DDI_RESUME:
775084Sjohnlev return (DDI_SUCCESS);
785084Sjohnlev default:
795084Sjohnlev return (DDI_FAILURE);
805084Sjohnlev }
815084Sjohnlev
825084Sjohnlev (void) xvdi_post_event(dip, XEN_HP_ADD);
835084Sjohnlev
845084Sjohnlev return (DDI_SUCCESS);
855084Sjohnlev }
865084Sjohnlev
875084Sjohnlev static int
xnbe_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)885084Sjohnlev xnbe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
895084Sjohnlev {
905084Sjohnlev #ifdef XNBE_DEBUG
915084Sjohnlev if (xnbe_debug > 0)
925084Sjohnlev cmn_err(CE_NOTE, "detach: dip 0x%p, cmd %d",
935084Sjohnlev (void *)dip, cmd);
945084Sjohnlev #endif /* XNBE_DEBUG */
955084Sjohnlev
965084Sjohnlev switch (cmd) {
975084Sjohnlev case DDI_DETACH:
985084Sjohnlev return (DDI_SUCCESS);
995084Sjohnlev case DDI_SUSPEND:
1005084Sjohnlev return (DDI_SUCCESS);
1015084Sjohnlev default:
1025084Sjohnlev return (DDI_FAILURE);
1035084Sjohnlev }
1045084Sjohnlev }
1055084Sjohnlev
1065084Sjohnlev static struct cb_ops cb_ops = {
1075084Sjohnlev nulldev, /* open */
1085084Sjohnlev nulldev, /* close */
1095084Sjohnlev nodev, /* strategy */
1105084Sjohnlev nodev, /* print */
1115084Sjohnlev nodev, /* dump */
1125084Sjohnlev nodev, /* read */
1135084Sjohnlev nodev, /* write */
1145084Sjohnlev nodev, /* ioctl */
1155084Sjohnlev nodev, /* devmap */
1165084Sjohnlev nodev, /* mmap */
1175084Sjohnlev nodev, /* segmap */
1185084Sjohnlev nochpoll, /* poll */
1195084Sjohnlev ddi_prop_op, /* cb_prop_op */
1205084Sjohnlev 0, /* streamtab */
1215084Sjohnlev D_NEW | D_MP | D_64BIT /* Driver compatibility flag */
1225084Sjohnlev };
1235084Sjohnlev
1245084Sjohnlev static struct dev_ops ops = {
1255084Sjohnlev DEVO_REV, /* devo_rev */
1265084Sjohnlev 0, /* devo_refcnt */
1275084Sjohnlev nulldev, /* devo_getinfo */
1285084Sjohnlev nulldev, /* devo_identify */
1295084Sjohnlev nulldev, /* devo_probe */
1305084Sjohnlev xnbe_attach, /* devo_attach */
1315084Sjohnlev xnbe_detach, /* devo_detach */
1325084Sjohnlev nodev, /* devo_reset */
1335084Sjohnlev &cb_ops, /* devo_cb_ops */
1345084Sjohnlev (struct bus_ops *)0, /* devo_bus_ops */
135*7656SSherry.Moore@Sun.COM NULL, /* devo_power */
136*7656SSherry.Moore@Sun.COM ddi_quiesce_not_needed, /* devo_quiesce */
1375084Sjohnlev };
1385084Sjohnlev
1395084Sjohnlev static struct modldrv modldrv = {
140*7656SSherry.Moore@Sun.COM &mod_driverops, "xnbe driver", &ops,
1415084Sjohnlev };
1425084Sjohnlev
1435084Sjohnlev static struct modlinkage modlinkage = {
1445084Sjohnlev MODREV_1, &modldrv, NULL
1455084Sjohnlev };
1465084Sjohnlev
1475084Sjohnlev int
_init(void)1485084Sjohnlev _init(void)
1495084Sjohnlev {
1505084Sjohnlev return (mod_install(&modlinkage));
1515084Sjohnlev }
1525084Sjohnlev
1535084Sjohnlev int
_info(struct modinfo * modinfop)1545084Sjohnlev _info(struct modinfo *modinfop)
1555084Sjohnlev {
1565084Sjohnlev return (mod_info(&modlinkage, modinfop));
1575084Sjohnlev }
1585084Sjohnlev
1595084Sjohnlev int
_fini(void)1605084Sjohnlev _fini(void)
1615084Sjohnlev {
1625084Sjohnlev return (mod_remove(&modlinkage));
1635084Sjohnlev }
164