VBoxNetAdp-solaris.c revision faff6adca592b2de8725db32b9476cbcb120ba57
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * VBoxNetAdapter - Network Adapter Driver (Host), Solaris Specific Code.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * available from http://www.virtualbox.org. This file is free software;
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * you can redistribute it and/or modify it under the terms of the GNU
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * General Public License (GPL) as published by the Free Software
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * additional information or have any questions.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync/*******************************************************************************
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync* Header Files *
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync*******************************************************************************/
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync#if defined(DEBUG_ramshankar) && !defined(LOG_ENABLED)
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync/*******************************************************************************
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync* Defined Constants And Macros *
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync*******************************************************************************/
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync/** The module descriptions as seen in 'modinfo'. */
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisModOpen(queue_t *pQueue, dev_t *pDev, int fFile, int fStream, cred_t *pCred);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisModClose(queue_t *pQueue, int fFile, cred_t *pCred);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisModReadPut(queue_t *pQueue, mblk_t *pMsg);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisModWritePut(queue_t *pQueue, mblk_t *pMsg);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisModWriteService(queue_t *pQueue);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Streams: module info.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic struct module_info g_VBoxNetAdpSolarisModInfo =
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync 0, /* min. packet size */
43bb4d90097ef9a9d7fc597315d0869427609694vboxsync 0, /* hi-water mark */
43bb4d90097ef9a9d7fc597315d0869427609694vboxsync 0 /* lo-water mark */
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Streams: read queue hooks.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Streams: write queue hooks.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Streams: IO stream tab.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic struct streamtab g_VBoxNetAdpSolarisStreamTab =
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * cb_ops: driver char/block entry points
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * dev_ops: driver entry/exit and other ops.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync 0, /* ref count */
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync (struct bus_ops *)0,
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * modldrv: export driver specifics to kernel
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync DEVICE_DESC_DRV " " VBOX_VERSION_STRING "r" VBOXSOLQUOTE(VBOX_SVN_REV),
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * modlinkage: export install/remove/info to the kernel
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic struct modlinkage g_VBoxNetAdpSolarisModLinkage =
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync &g_VBoxNetAdpSolarisDriver, /* adapter streams driver framework */
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync/*******************************************************************************
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync* Global Variables *
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync*******************************************************************************/
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync/** The default ethernet broadcast address */
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic uchar_t achBroadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * vboxnetadp_state_t: per-instance data
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync RTMAC FactoryMac; /* default 'factory' MAC address */
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync/*******************************************************************************
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync* Internal Functions *
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync*******************************************************************************/
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisGenerateMac(PRTMAC pMac);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisSetMacAddress(gld_mac_info_t *pMacInfo, unsigned char *pszMacAddr);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisSend(gld_mac_info_t *pMacInfo, mblk_t *pMsg);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisStub(gld_mac_info_t *pMacInfo);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisSetPromisc(gld_mac_info_t *pMacInfo, int fPromisc);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisSetMulticast(gld_mac_info_t *pMacInfo, unsigned char *pMulticastAddr, int fMulticast);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Kernel entry points
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Prevent module autounloading.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync modctl_t *pModCtl = mod_getctl(&g_VBoxNetAdpSolarisModLinkage);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Initialize IPRT.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":failed to initialize IPRT (rc=%d)\n", rc));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Undo the work done during start (in reverse order).
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync int rc = mod_info(&g_VBoxNetAdpSolarisModLinkage, pModInfo);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Attach entry point, to attach a device to the system or resume it.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * @param pDip The module structure instance.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * @param enmCmd Operation type (attach/resume).
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * @returns corresponding solaris error code.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogFlow((DEVICE_NAME ":VBoxNetAdpSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync vboxnetadp_state_t *pState = RTMemAllocZ(sizeof(vboxnetadp_state_t));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Setup GLD MAC layer registeration info.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync pMacInfo->gldm_set_mac_addr = vboxNetAdpSolarisSetMacAddress;
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync pMacInfo->gldm_set_multicast = vboxNetAdpSolarisSetMulticast;
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync pMacInfo->gldm_set_promiscuous = vboxNetAdpSolarisSetPromisc;
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync pMacInfo->gldm_ppa = ddi_get_instance(pState->pDip);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * We use a semi-random MAC addresses similar to a guest NIC's MAC address
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * as the default factory address of the interface.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync rc = vboxNetAdpSolarisGenerateMac(&pState->FactoryMac);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync bcopy(&pState->FactoryMac, &pState->CurrentMac, sizeof(RTMAC));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync pMacInfo->gldm_vendor_addr = (unsigned char *)&pState->FactoryMac;
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Now try registering our GLD with the MAC layer.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Registeration can fail on some S10 versions when the MTU size is more than 1500.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * When we implement jumbo frames we should probably retry with MTU 1500 for S10.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync rc = gld_register(pDip, (char *)ddi_driver_name(pDip), pMacInfo);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to register GLD. rc=%d\n", rc));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to generate mac address.rc=%d\n"));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to alloc state.\n"));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to alloc mac structure.\n"));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync /* Nothing to do here... */
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Detach entry point, to detach a device to the system or suspend it.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * @param pDip The module structure instance.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * @param enmCmd Operation type (detach/suspend).
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * @returns corresponding solaris error code.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int VBoxNetAdpSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogFlow((DEVICE_NAME ":VBoxNetAdpSolarisDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync * Unregister and clean up.
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync gld_mac_info_t *pMacInfo = ddi_get_driver_private(pDip);
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync vboxnetadp_state_t *pState = (vboxnetadp_state_t *)pMacInfo->gldm_private;
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to unregister GLD from MAC layer.rc=%d\n", rc));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to get internal state.\n"));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to get driver private GLD data.\n"));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsync /* Nothing to do here... */
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisGenerateMac(PRTMAC pMac)
29890600941d8c492d0c52cc0daefda9bad1b538vboxsync LogFlow((DEVICE_NAME ":VBoxNetAdpSolarisGenerateMac Generated %.*Rhxs\n", sizeof(RTMAC), &pMac));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisSetMacAddress(gld_mac_info_t *pMacInfo, unsigned char *pszMacAddr)
29890600941d8c492d0c52cc0daefda9bad1b538vboxsync vboxnetadp_state_t *pState = (vboxnetadp_state_t *)pMacInfo->gldm_private;
29890600941d8c492d0c52cc0daefda9bad1b538vboxsync bcopy(pszMacAddr, &pState->CurrentMac, sizeof(RTMAC));
29890600941d8c492d0c52cc0daefda9bad1b538vboxsync LogFlow((DEVICE_NAME ":vboxNetAdpSolarisSetMacAddress updated MAC %.*Rhxs\n", sizeof(RTMAC), &pState->CurrentMac));
29890600941d8c492d0c52cc0daefda9bad1b538vboxsync LogRel((DEVICE_NAME ":vboxNetAdpSolarisSetMacAddress failed to get internal state.\n"));
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisSend(gld_mac_info_t *pMacInfo, mblk_t *pMsg)
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisStub(gld_mac_info_t *pMacInfo)
65acc9a737d682ad726d06327bf6f6ecc6eb7e83vboxsyncstatic int vboxNetAdpSolarisSetMulticast(gld_mac_info_t *pMacInfo, unsigned char *pMulticastAddr, int fMulticast)