678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * CDDL HEADER START
678453a8ed49104d8adad58f3ba591bdc39883e8speer *
678453a8ed49104d8adad58f3ba591bdc39883e8speer * The contents of this file are subject to the terms of the
678453a8ed49104d8adad58f3ba591bdc39883e8speer * Common Development and Distribution License (the "License").
678453a8ed49104d8adad58f3ba591bdc39883e8speer * You may not use this file except in compliance with the License.
678453a8ed49104d8adad58f3ba591bdc39883e8speer *
678453a8ed49104d8adad58f3ba591bdc39883e8speer * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
678453a8ed49104d8adad58f3ba591bdc39883e8speer * or http://www.opensolaris.org/os/licensing.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * See the License for the specific language governing permissions
678453a8ed49104d8adad58f3ba591bdc39883e8speer * and limitations under the License.
678453a8ed49104d8adad58f3ba591bdc39883e8speer *
678453a8ed49104d8adad58f3ba591bdc39883e8speer * When distributing Covered Code, include this CDDL HEADER in each
678453a8ed49104d8adad58f3ba591bdc39883e8speer * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * If applicable, add the following below this CDDL HEADER, with the
678453a8ed49104d8adad58f3ba591bdc39883e8speer * fields enclosed by brackets "[]" replaced with your own identifying
678453a8ed49104d8adad58f3ba591bdc39883e8speer * information: Portions Copyright [yyyy] [name of copyright owner]
678453a8ed49104d8adad58f3ba591bdc39883e8speer *
678453a8ed49104d8adad58f3ba591bdc39883e8speer * CDDL HEADER END
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * Use is subject to license terms.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/types.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/errno.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/debug.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/time.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/sysmacros.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/systm.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/user.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/stropts.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/stream.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/strlog.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/strsubr.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/cmn_err.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/cpu.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/kmem.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/conf.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/ddi.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/sunddi.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/ksynch.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/stat.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/kstat.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/vtrace.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/strsun.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/dlpi.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/ethernet.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <net/if.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/varargs.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/machsystm.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/modctl.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/modhash.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/mac_provider.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/mac_ether.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/taskq.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/note.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/mach_descrip.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/mac.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/mdeg.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/ldc.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/vsw_fdb.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/vsw.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/vio_mailbox.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/vnet_mailbox.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/vnet_common.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/vio_util.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/sdt.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/atomic.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer#include <sys/callb.h>
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer#define VSW_DDS_NEXT_REQID(vsharep) (++vsharep->vs_req_id)
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speerextern boolean_t vsw_hio_enabled; /* HybridIO enabled? */
678453a8ed49104d8adad58f3ba591bdc39883e8speerextern int vsw_hio_max_cleanup_retries;
678453a8ed49104d8adad58f3ba591bdc39883e8speerextern int vsw_hio_cleanup_delay;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/* Functions imported from other files */
678453a8ed49104d8adad58f3ba591bdc39883e8speerextern int vsw_send_msg(vsw_ldc_t *, void *, int, boolean_t);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramextern void vsw_hio_port_reset(vsw_port_t *portp, boolean_t immediate);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengextern void vsw_port_mac_reconfig(vsw_port_t *portp, boolean_t update_vlans,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t new_pvid, vsw_vlanid_t *new_vids, int new_nvids);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/* Functions exported to other files */
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid vsw_hio_init(vsw_t *vswp);
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid vsw_hio_cleanup(vsw_t *vswp);
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid vsw_hio_start(vsw_t *vswp, vsw_ldc_t *ldcp);
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid vsw_hio_stop(vsw_t *vswp, vsw_ldc_t *ldcp);
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid vsw_process_dds_msg(vsw_t *vswp, vsw_ldc_t *ldcp, void *msg);
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid vsw_hio_start_ports(vsw_t *vswp);
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid vsw_hio_stop_port(vsw_port_t *portp);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/* Support functions */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramstatic void vsw_hio_free_all_shares(vsw_t *vswp, boolean_t reboot);
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic vsw_share_t *vsw_hio_alloc_share(vsw_t *vswp, vsw_ldc_t *ldcp);
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic void vsw_hio_free_share(vsw_share_t *vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic vsw_share_t *vsw_hio_find_free_share(vsw_t *vswp);
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic vsw_share_t *vsw_hio_find_vshare_ldcid(vsw_t *vswp, uint64_t ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic vsw_share_t *vsw_hio_find_vshare_port(vsw_t *vswp, vsw_port_t *portp);
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic int vsw_send_dds_msg(vsw_ldc_t *ldcp, uint8_t dds_subclass,
678453a8ed49104d8adad58f3ba591bdc39883e8speer uint64_t cookie, uint64_t macaddr, uint32_t req_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic int vsw_send_dds_resp_msg(vsw_ldc_t *ldcp, vio_dds_msg_t *dmsg, int ack);
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic int vsw_hio_send_delshare_msg(vsw_share_t *vsharep);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramstatic boolean_t vsw_hio_reboot_callb(void *arg, int code);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramstatic boolean_t vsw_hio_panic_callb(void *arg, int code);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Locking strategy for HybridIO is followed as below:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * - As the Shares are associated with a network device, the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * the global lock('vswp>mac_lock') is used for all Shares
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * related operations.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * - The 'port->maccl_rwlock' is used to synchronize only the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * the operations that operate on that port's mac client. That
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * is, the share_bind and unbind operations only.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * - The locking hierarchy follows that the global mac_lock is
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * acquired first and then the ports mac client lock(maccl_rwlock)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGstatic kstat_t *vsw_hio_setup_kstats(char *ks_mod, char *ks_name, vsw_t *vswp);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGstatic void vsw_hio_destroy_kstats(vsw_t *vswp);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGstatic int vsw_hio_kstats_update(kstat_t *ksp, int rw);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_init -- Initialize the HybridIO related info.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * - Query SHARES and RINGS capability. Both capabilities
678453a8ed49104d8adad58f3ba591bdc39883e8speer * need to be supported by the physical-device.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_init(vsw_t *vswp)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_t *hiop = &vswp->vhio;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int num_shares;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int i;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(MUTEX_HELD(&vswp->mac_lock));
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsw_hio_enabled == B_FALSE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer vswp->hio_capable = B_FALSE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng num_shares = mac_share_capable(vswp->mh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (num_shares == 0) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer D2(vswp, "%s: %s is not HybridIO capable\n", __func__,
678453a8ed49104d8adad58f3ba591bdc39883e8speer vswp->physname);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hiop->vh_num_shares = num_shares;
678453a8ed49104d8adad58f3ba591bdc39883e8speer hiop->vh_shares = kmem_zalloc((sizeof (vsw_share_t) *
678453a8ed49104d8adad58f3ba591bdc39883e8speer hiop->vh_num_shares), KM_SLEEP);
678453a8ed49104d8adad58f3ba591bdc39883e8speer for (i = 0; i < hiop->vh_num_shares; i++) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer hiop->vh_shares[i].vs_state = VSW_SHARE_FREE;
678453a8ed49104d8adad58f3ba591bdc39883e8speer hiop->vh_shares[i].vs_index = i;
678453a8ed49104d8adad58f3ba591bdc39883e8speer hiop->vh_shares[i].vs_vswp = vswp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer vswp->hio_capable = B_TRUE;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram /*
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * Register to get reboot and panic events so that
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * we can cleanup HybridIO resources gracefully.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vswp->hio_reboot_cb_id = callb_add(vsw_hio_reboot_callb,
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram (void *)vswp, CB_CL_MDBOOT, "vsw_hio");
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vswp->hio_panic_cb_id = callb_add(vsw_hio_panic_callb,
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram (void *)vswp, CB_CL_PANIC, "vsw_hio");
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG /* setup kstats for hybrid resources */
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_ksp = vsw_hio_setup_kstats(DRV_NAME, "hio", vswp);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG if (hiop->vh_ksp == NULL) {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG DERR(vswp, "%s: kstats setup failed", __func__);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG }
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
678453a8ed49104d8adad58f3ba591bdc39883e8speer D2(vswp, "%s: %s is HybridIO capable num_shares=%d\n", __func__,
678453a8ed49104d8adad58f3ba591bdc39883e8speer vswp->physname, hiop->vh_num_shares);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_alloc_share -- Allocate and setup the share for a guest domain.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * - Allocate a free share.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * - Bind the Guest's MAC address.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic vsw_share_t *
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_alloc_share(vsw_t *vswp, vsw_ldc_t *ldcp)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_port_t *portp = ldcp->ldc_port;
678453a8ed49104d8adad58f3ba591bdc39883e8speer uint64_t ldc_id = ldcp->ldc_id;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int rv;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = vsw_hio_find_free_share(vswp);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep == NULL) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* No free shares available */
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (NULL);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng WRITE_ENTER(&portp->maccl_rwlock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = mac_share_bind(portp->p_mch, ldc_id, &vsharep->vs_cookie);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_EXIT(&portp->maccl_rwlock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (rv != 0) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (NULL);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Cache some useful info */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_ldcid = ldcp->ldc_id;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_macaddr = vnet_macaddr_strtoul(
678453a8ed49104d8adad58f3ba591bdc39883e8speer portp->p_macaddr.ether_addr_octet);
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_portp = ldcp->ldc_port;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_state |= VSW_SHARE_ASSIGNED;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_find_free_share -- Find a free Share.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic vsw_share_t *
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_find_free_share(vsw_t *vswp)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_t *hiop = &vswp->vhio;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int i;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer for (i = 0; i < hiop->vh_num_shares; i++) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = &hiop->vh_shares[i];
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep->vs_state == VSW_SHARE_FREE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:Returning free share(%d)\n",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, vsharep->vs_index);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:no free share\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (NULL);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_find_vshare_ldcid -- Given ldc_id, find the corresponding
678453a8ed49104d8adad58f3ba591bdc39883e8speer * share structure.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic vsw_share_t *
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_find_vshare_ldcid(vsw_t *vswp, uint64_t ldc_id)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_t *hiop = &vswp->vhio;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int i;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter, ldc=0x%lx", __func__, ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer for (i = 0; i < hiop->vh_num_shares; i++) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = &hiop->vh_shares[i];
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep->vs_state == VSW_SHARE_FREE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer continue;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep->vs_ldcid == ldc_id) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:returning share(%d)",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, vsharep->vs_index);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:returning NULL", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (NULL);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_find_vshare_port -- Given portp, find the corresponding
678453a8ed49104d8adad58f3ba591bdc39883e8speer * share structure.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic vsw_share_t *
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_find_vshare_port(vsw_t *vswp, vsw_port_t *portp)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_t *hiop = &vswp->vhio;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int i;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter, portp=0x%p", __func__, portp);
678453a8ed49104d8adad58f3ba591bdc39883e8speer for (i = 0; i < hiop->vh_num_shares; i++) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = &hiop->vh_shares[i];
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep->vs_state == VSW_SHARE_FREE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer continue;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep->vs_portp == portp) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:returning share(%d)",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, vsharep->vs_index);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:returning NULL", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (NULL);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_free_share -- Unbind the MAC address and free share.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic void
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_free_share(vsw_share_t *vsharep)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_t *vswp = vsharep->vs_vswp;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_port_t *portp = vsharep->vs_portp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng WRITE_ENTER(&portp->maccl_rwlock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_share_unbind(portp->p_mch);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_EXIT(&portp->maccl_rwlock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_state = VSW_SHARE_FREE;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vsharep->vs_macaddr = 0;
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG vsharep->vs_portp = NULL;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* DERR only for printing by default */
678453a8ed49104d8adad58f3ba591bdc39883e8speer DERR(vswp, "Share freed for ldc_id=0x%lx Cookie=0x%lX",
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_ldcid, vsharep->vs_cookie);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * vsw_hio_cleanup -- Cleanup the HybridIO. It unregisters the callbs
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * and frees all shares.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramvoid
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramvsw_hio_cleanup(vsw_t *vswp)
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram{
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram D1(vswp, "%s:enter\n", __func__);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram /* Unregister reboot and panic callbs. */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram if (vswp->hio_reboot_cb_id) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram (void) callb_delete(vswp->hio_reboot_cb_id);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vswp->hio_reboot_cb_id = 0;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram }
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram if (vswp->hio_panic_cb_id) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram (void) callb_delete(vswp->hio_panic_cb_id);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vswp->hio_panic_cb_id = 0;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram }
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_free_all_shares(vswp, B_FALSE);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vsw_hio_destroy_kstats(vswp);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram D1(vswp, "%s:exit\n", __func__);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram}
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram/*
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * vsw_hio_free_all_shares -- A routine to free all shares gracefully.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * The following are the steps followed to accomplish this:
678453a8ed49104d8adad58f3ba591bdc39883e8speer *
678453a8ed49104d8adad58f3ba591bdc39883e8speer * - First clear 'hio_capable' to avoid further share allocations.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * - If a share is in accepted(ACKD) state, that means the guest
678453a8ed49104d8adad58f3ba591bdc39883e8speer * has HybridIO setup etc. If so, send a DEL_SHARE message and
678453a8ed49104d8adad58f3ba591bdc39883e8speer * give some time(delay) for the guest to ACK.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * - If the Share is another state, give some time to transition to
678453a8ed49104d8adad58f3ba591bdc39883e8speer * ACKD state, then try the above.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * - After max retries, reset the ports to brute force the shares
678453a8ed49104d8adad58f3ba591bdc39883e8speer * to be freed. Give a little delay for the LDC reset code to
678453a8ed49104d8adad58f3ba591bdc39883e8speer * free the Share.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramstatic void
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramvsw_hio_free_all_shares(vsw_t *vswp, boolean_t reboot)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_t *hiop = &vswp->vhio;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_port_list_t *plist = &vswp->plist;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int free_shares = 0;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int max_retries = vsw_hio_max_cleanup_retries;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int i;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * Acquire plist->lockrw to make the locking a bit easier
678453a8ed49104d8adad58f3ba591bdc39883e8speer * and keep the ports in a stable state while we are cleaningup
678453a8ed49104d8adad58f3ba591bdc39883e8speer * HybridIO.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speer READ_ENTER(&plist->lockrw);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * first clear the hio_capable flag so that no more
678453a8ed49104d8adad58f3ba591bdc39883e8speer * HybridIO operations are initiated.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vswp->hio_capable = B_FALSE;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer do {
678453a8ed49104d8adad58f3ba591bdc39883e8speer free_shares = 0;
678453a8ed49104d8adad58f3ba591bdc39883e8speer for (i = 0; i < hiop->vh_num_shares; i++) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = &hiop->vh_shares[i];
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep->vs_state == VSW_SHARE_FREE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer free_shares++;
678453a8ed49104d8adad58f3ba591bdc39883e8speer continue;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * If the share is in DDS_ACKD state, then
678453a8ed49104d8adad58f3ba591bdc39883e8speer * send DEL_SHARE message so that guest can
678453a8ed49104d8adad58f3ba591bdc39883e8speer * release its Hybrid resource.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep->vs_state & VSW_SHARE_DDS_ACKD) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer int rv;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* send DDS_DEL_SHARE */
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:sending DEL_SHARE msg for "
678453a8ed49104d8adad58f3ba591bdc39883e8speer "share(%d)", __func__, vsharep->vs_index);
678453a8ed49104d8adad58f3ba591bdc39883e8speer rv = vsw_hio_send_delshare_msg(vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (rv != 0) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * No alternative, reset the port
678453a8ed49104d8adad58f3ba591bdc39883e8speer * to force the release of Hybrid
678453a8ed49104d8adad58f3ba591bdc39883e8speer * resources.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_port_reset(vsharep->vs_portp,
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram B_FALSE);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (max_retries == 1) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram /*
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * Last retry, reset the port.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * If it is reboot case, issue an immediate
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * reset.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram */
678453a8ed49104d8adad58f3ba591bdc39883e8speer DWARN(vswp, "%s:All retries failed, "
678453a8ed49104d8adad58f3ba591bdc39883e8speer " cause a reset to trigger cleanup for "
678453a8ed49104d8adad58f3ba591bdc39883e8speer "share(%d)", __func__, vsharep->vs_index);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_port_reset(vsharep->vs_portp, reboot);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (free_shares == hiop->vh_num_shares) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Clean up is done */
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * Release the lock so that reply for DEL_SHARE
678453a8ed49104d8adad58f3ba591bdc39883e8speer * messages come and get processed, that is, shares
678453a8ed49104d8adad58f3ba591bdc39883e8speer * get freed.
678453a8ed49104d8adad58f3ba591bdc39883e8speer * This delay is also needed for the port reset to
678453a8ed49104d8adad58f3ba591bdc39883e8speer * release the Hybrid resource.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
d0288fccb96090b22ce5bbc3da0a20ef62a15be2Raghuram Kothakota drv_usecwait(vsw_hio_cleanup_delay);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer max_retries--;
678453a8ed49104d8adad58f3ba591bdc39883e8speer } while ((free_shares < hiop->vh_num_shares) && (max_retries > 0));
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* By now, all shares should be freed */
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (free_shares != hiop->vh_num_shares) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram if (reboot == B_FALSE) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram cmn_err(CE_NOTE, "vsw%d: All physical resources "
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram "could not be freed", vswp->instance);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram }
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer kmem_free(hiop->vh_shares, sizeof (vsw_share_t) * hiop->vh_num_shares);
678453a8ed49104d8adad58f3ba591bdc39883e8speer hiop->vh_shares = NULL;
678453a8ed49104d8adad58f3ba591bdc39883e8speer hiop->vh_num_shares = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer RW_EXIT(&plist->lockrw);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_start_ports -- Start HybridIO for ports that have
678453a8ed49104d8adad58f3ba591bdc39883e8speer * already established connection before HybridIO is intialized.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_start_ports(vsw_t *vswp)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_port_list_t *plist = &vswp->plist;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_port_t *portp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer boolean_t reset;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vswp->hio_capable == B_FALSE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer READ_ENTER(&plist->lockrw);
678453a8ed49104d8adad58f3ba591bdc39883e8speer for (portp = plist->head; portp != NULL; portp = portp->p_next) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer if ((portp->p_hio_enabled == B_FALSE) ||
678453a8ed49104d8adad58f3ba591bdc39883e8speer (portp->p_hio_capable == B_FALSE)) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer continue;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer reset = B_FALSE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = vsw_hio_find_vshare_port(vswp, portp);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep == NULL) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer reset = B_TRUE;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (reset == B_TRUE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Cause a rest to trigger HybridIO setup */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_port_reset(portp, B_FALSE);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer RW_EXIT(&plist->lockrw);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_start -- Start HybridIO for a guest(given LDC)
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_start(vsw_t *vswp, vsw_ldc_t *ldcp)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer uint32_t req_id;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int rv;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter ldc=0x%lx", __func__, ldcp->ldc_id);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vswp->hio_capable == B_FALSE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D2(vswp, "%s:not HIO capable", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Verify if a share was already allocated */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = vsw_hio_find_vshare_ldcid(vswp, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D2(vswp, "%s:Share already allocated to ldc=0x%lx",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = vsw_hio_alloc_share(vswp, ldcp);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D2(vswp, "%s: no Share available for ldc=0x%lx",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer req_id = VSW_DDS_NEXT_REQID(vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer rv = vsw_send_dds_msg(ldcp, DDS_VNET_ADD_SHARE, vsharep->vs_cookie,
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_macaddr, req_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (rv != 0) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * Failed to send a DDS message, so cleanup now.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_free_share(vsharep);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsharep->vs_state &= ~VSW_SHARE_DDS_ACKD;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_state |= VSW_SHARE_DDS_SENT;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* DERR only to print by default */
678453a8ed49104d8adad58f3ba591bdc39883e8speer DERR(vswp, "Share allocated for ldc_id=0x%lx Cookie=0x%lX",
678453a8ed49104d8adad58f3ba591bdc39883e8speer ldcp->ldc_id, vsharep->vs_cookie);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit ldc=0x%lx", __func__, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_stop -- Stop/clean the HybridIO config for a guest(given ldc).
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_stop(vsw_t *vswp, vsw_ldc_t *ldcp)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter ldc=0x%lx", __func__, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = vsw_hio_find_vshare_ldcid(vswp, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep == NULL) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:no share found for ldc=0x%lx",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, ldcp->ldc_id);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_free_share(vsharep);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit ldc=0x%lx", __func__, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_send_delshare_msg -- Send a DEL_SHARE message to the guest.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic int
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_send_delshare_msg(vsw_share_t *vsharep)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_t *vswp = vsharep->vs_vswp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_port_t *portp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_ldc_t *ldcp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer uint32_t req_id;
678453a8ed49104d8adad58f3ba591bdc39883e8speer uint64_t cookie = vsharep->vs_cookie;
678453a8ed49104d8adad58f3ba591bdc39883e8speer uint64_t macaddr = vsharep->vs_macaddr;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int rv;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(MUTEX_HELD(&vswp->mac_lock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer portp = vsharep->vs_portp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (portp == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (0);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp = portp->ldcp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer if ((ldcp == NULL) || (ldcp->ldc_id != vsharep->vs_ldcid)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (0);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer req_id = VSW_DDS_NEXT_REQID(vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer rv = vsw_send_dds_msg(ldcp, DDS_VNET_DEL_SHARE,
678453a8ed49104d8adad58f3ba591bdc39883e8speer cookie, macaddr, req_id);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram if (rv == 0) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsharep->vs_state &= ~VSW_SHARE_DDS_ACKD;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsharep->vs_state |= VSW_SHARE_DDS_SENT;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram }
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (rv);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_send_dds_msg -- Send a DDS message.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic int
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_send_dds_msg(vsw_ldc_t *ldcp, uint8_t dds_subclass, uint64_t
678453a8ed49104d8adad58f3ba591bdc39883e8speer cookie, uint64_t macaddr, uint32_t req_id)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_t *vswp = ldcp->ldc_port->p_vswp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vio_dds_msg_t vmsg;
678453a8ed49104d8adad58f3ba591bdc39883e8speer dds_share_msg_t *smsg = &vmsg.msg.share_msg;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int rv;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer vmsg.tag.vio_msgtype = VIO_TYPE_CTRL;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vmsg.tag.vio_subtype = VIO_SUBTYPE_INFO;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vmsg.tag.vio_subtype_env = VIO_DDS_INFO;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vmsg.tag.vio_sid = ldcp->local_session;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vmsg.dds_class = DDS_VNET_NIU;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vmsg.dds_subclass = dds_subclass;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vmsg.dds_req_id = req_id;
678453a8ed49104d8adad58f3ba591bdc39883e8speer smsg->macaddr = macaddr;
678453a8ed49104d8adad58f3ba591bdc39883e8speer smsg->cookie = cookie;
678453a8ed49104d8adad58f3ba591bdc39883e8speer rv = vsw_send_msg(ldcp, &vmsg, sizeof (vmsg), B_FALSE);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit rv=%d\n", __func__, rv);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (rv);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_process_dds_msg -- Process a DDS message received from a guest.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_process_dds_msg(vsw_t *vswp, vsw_ldc_t *ldcp, void *msg)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vio_dds_msg_t *dmsg = msg;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter ldc=0x%lx\n", __func__, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (dmsg->dds_class != DDS_VNET_NIU) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* discard */
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * We expect to receive DDS messages only from guests that
678453a8ed49104d8adad58f3ba591bdc39883e8speer * have HybridIO started.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = vsw_hio_find_vshare_ldcid(vswp, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer switch (dmsg->dds_subclass) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer case DDS_VNET_ADD_SHARE:
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* A response for ADD_SHARE message. */
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:DDS_VNET_ADD_SHARE\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (!(vsharep->vs_state & VSW_SHARE_DDS_SENT)) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer DWARN(vswp, "%s: invalid ADD_SHARE response message "
678453a8ed49104d8adad58f3ba591bdc39883e8speer " share state=0x%X", __func__, vsharep->vs_state);
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (dmsg->dds_req_id != vsharep->vs_req_id) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer DWARN(vswp, "%s: invalid req_id in ADD_SHARE response"
678453a8ed49104d8adad58f3ba591bdc39883e8speer " message req_id=0x%X share's req_id=0x%X",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, dmsg->dds_req_id, vsharep->vs_req_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (dmsg->tag.vio_subtype == VIO_SUBTYPE_NACK) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer DWARN(vswp, "%s: NACK received for ADD_SHARE"
678453a8ed49104d8adad58f3ba591bdc39883e8speer " message ldcid=0x%lx", __func__, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* cleanup for NACK */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_free_share(vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer } else {
678453a8ed49104d8adad58f3ba591bdc39883e8speer D2(vswp, "%s: ACK received for ADD_SHARE", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_state &= ~VSW_SHARE_DDS_SENT;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep->vs_state |= VSW_SHARE_DDS_ACKD;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer case DDS_VNET_DEL_SHARE:
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* A response for DEL_SHARE message */
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:DDS_VNET_DEL_SHARE\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (!(vsharep->vs_state & VSW_SHARE_DDS_SENT)) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram DWARN(vswp, "%s: invalid DEL_SHARE response message "
678453a8ed49104d8adad58f3ba591bdc39883e8speer " share state=0x%X", __func__, vsharep->vs_state);
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (dmsg->dds_req_id != vsharep->vs_req_id) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram DWARN(vswp, "%s: invalid req_id in DEL_SHARE response"
678453a8ed49104d8adad58f3ba591bdc39883e8speer " message share req_id=0x%X share's req_id=0x%X",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, dmsg->dds_req_id, vsharep->vs_req_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (dmsg->tag.vio_subtype == VIO_SUBTYPE_NACK) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram DWARN(vswp, "%s: NACK received for DEL_SHARE",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* There is nothing we can do, free share now */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_free_share(vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer case DDS_VNET_REL_SHARE:
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Guest has released Share voluntarily, so free it now */
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:DDS_VNET_REL_SHARE\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* send ACK */
678453a8ed49104d8adad58f3ba591bdc39883e8speer (void) vsw_send_dds_resp_msg(ldcp, dmsg, B_FALSE);
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_free_share(vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer default:
678453a8ed49104d8adad58f3ba591bdc39883e8speer DERR(vswp, "%s: Invalid DDS message type=0x%X",
678453a8ed49104d8adad58f3ba591bdc39883e8speer __func__, dmsg->dds_subclass);
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit ldc=0x%lx\n", __func__, ldcp->ldc_id);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_send_dds_resp_msg -- Send a DDS response message.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speerstatic int
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_send_dds_resp_msg(vsw_ldc_t *ldcp, vio_dds_msg_t *dmsg, int ack)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_t *vswp = ldcp->ldc_port->p_vswp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int rv;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (ack == B_TRUE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer dmsg->tag.vio_subtype = VIO_SUBTYPE_ACK;
678453a8ed49104d8adad58f3ba591bdc39883e8speer dmsg->msg.share_resp_msg.status = DDS_VNET_SUCCESS;
678453a8ed49104d8adad58f3ba591bdc39883e8speer } else {
678453a8ed49104d8adad58f3ba591bdc39883e8speer dmsg->tag.vio_subtype = VIO_SUBTYPE_NACK;
678453a8ed49104d8adad58f3ba591bdc39883e8speer dmsg->msg.share_resp_msg.status = DDS_VNET_FAIL;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer rv = vsw_send_msg(ldcp, dmsg, sizeof (vio_dds_msg_t), B_FALSE);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit rv=%d\n", __func__, rv);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return (rv);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_port_update -- update Hybrid mode change for a port.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_port_update(vsw_port_t *portp, boolean_t hio_enabled)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Verify if the mode really changed */
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (portp->p_hio_enabled == hio_enabled) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (hio_enabled == B_FALSE) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Hybrid Mode is disabled, so stop HybridIO */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_hio_stop_port(portp);
678453a8ed49104d8adad58f3ba591bdc39883e8speer portp->p_hio_enabled = B_FALSE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_port_mac_reconfig(portp, B_FALSE, 0, NULL, 0);
678453a8ed49104d8adad58f3ba591bdc39883e8speer } else {
678453a8ed49104d8adad58f3ba591bdc39883e8speer portp->p_hio_enabled = B_TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_port_mac_reconfig(portp, B_FALSE, 0, NULL, 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* reset the port to initiate HybridIO setup */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_port_reset(portp, B_FALSE);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer/*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * vsw_hio_stop_port -- Stop HybridIO for a given port. Sequence
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * followed is similar to vsw_hio_free_all_shares().
678453a8ed49104d8adad58f3ba591bdc39883e8speer *
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
678453a8ed49104d8adad58f3ba591bdc39883e8speervoid
678453a8ed49104d8adad58f3ba591bdc39883e8speervsw_hio_stop_port(vsw_port_t *portp)
678453a8ed49104d8adad58f3ba591bdc39883e8speer{
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_t *vswp = portp->p_vswp;
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsw_share_t *vsharep;
678453a8ed49104d8adad58f3ba591bdc39883e8speer int max_retries = vsw_hio_max_cleanup_retries;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:enter\n", __func__);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vswp->hio_capable == B_FALSE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer vsharep = vsw_hio_find_vshare_port(vswp, portp);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer return;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer do {
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (vsharep->vs_state & VSW_SHARE_DDS_ACKD) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer int rv;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* send DDS_DEL_SHARE */
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:sending DEL_SHARE msg for "
678453a8ed49104d8adad58f3ba591bdc39883e8speer "share(%d)", __func__, vsharep->vs_index);
678453a8ed49104d8adad58f3ba591bdc39883e8speer rv = vsw_hio_send_delshare_msg(vsharep);
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (rv != 0) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * Cause a port reset to trigger
678453a8ed49104d8adad58f3ba591bdc39883e8speer * cleanup.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_port_reset(vsharep->vs_portp, B_FALSE);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer if (max_retries == 1) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* last retry */
678453a8ed49104d8adad58f3ba591bdc39883e8speer DWARN(vswp, "%s:All retries failed, "
678453a8ed49104d8adad58f3ba591bdc39883e8speer " cause a reset to trigger cleanup for "
678453a8ed49104d8adad58f3ba591bdc39883e8speer "share(%d)", __func__, vsharep->vs_index);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_port_reset(vsharep->vs_portp, B_FALSE);
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Check if the share still assigned to this port */
678453a8ed49104d8adad58f3ba591bdc39883e8speer if ((vsharep->vs_portp != portp) ||
678453a8ed49104d8adad58f3ba591bdc39883e8speer (vsharep->vs_state == VSW_SHARE_FREE)) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /*
678453a8ed49104d8adad58f3ba591bdc39883e8speer * Release the lock so that reply for DEL_SHARE
678453a8ed49104d8adad58f3ba591bdc39883e8speer * messages come and get processed, that is, shares
678453a8ed49104d8adad58f3ba591bdc39883e8speer * get freed.
678453a8ed49104d8adad58f3ba591bdc39883e8speer */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
d0288fccb96090b22ce5bbc3da0a20ef62a15be2Raghuram Kothakota drv_usecwait(vsw_hio_cleanup_delay);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* Check if the share still assigned to this port */
678453a8ed49104d8adad58f3ba591bdc39883e8speer if ((vsharep->vs_portp != portp) ||
678453a8ed49104d8adad58f3ba591bdc39883e8speer (vsharep->vs_state == VSW_SHARE_FREE)) {
678453a8ed49104d8adad58f3ba591bdc39883e8speer break;
678453a8ed49104d8adad58f3ba591bdc39883e8speer }
678453a8ed49104d8adad58f3ba591bdc39883e8speer max_retries--;
678453a8ed49104d8adad58f3ba591bdc39883e8speer } while ((vsharep->vs_state != VSW_SHARE_FREE) && (max_retries > 0));
678453a8ed49104d8adad58f3ba591bdc39883e8speer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
678453a8ed49104d8adad58f3ba591bdc39883e8speer D1(vswp, "%s:exit\n", __func__);
678453a8ed49104d8adad58f3ba591bdc39883e8speer}
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram/*
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * vsw_hio_rest_all -- Resets all ports that have shares allocated.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * It is called only in the panic code path, so the LDC channels
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * are reset immediately.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramstatic void
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramvsw_hio_reset_all(vsw_t *vswp)
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram{
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_t *hiop = &vswp->vhio;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_share_t *vsharep;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram int i;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram D1(vswp, "%s:enter\n", __func__);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram if (vswp->hio_capable != B_TRUE)
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram return;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram for (i = 0; i < hiop->vh_num_shares; i++) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsharep = &hiop->vh_shares[i];
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram if (vsharep->vs_state == VSW_SHARE_FREE) {
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram continue;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram }
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram /*
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * Reset the port with immediate flag enabled,
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * to cause LDC reset immediately.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_port_reset(vsharep->vs_portp, B_TRUE);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram }
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram D1(vswp, "%s:exit\n", __func__);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram}
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram/*
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * vsw_hio_reboot_callb -- Called for reboot event. It tries to
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * free all currently allocated shares.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram/* ARGSUSED */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramstatic boolean_t
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramvsw_hio_reboot_callb(void *arg, int code)
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram{
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_t *vswp = arg;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram D1(vswp, "%s:enter\n", __func__);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_free_all_shares(vswp, B_TRUE);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram D1(vswp, "%s:exit\n", __func__);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram return (B_TRUE);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram}
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram/*
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * vsw_hio_panic_callb -- Called from panic event. It resets all
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * the ports that have shares allocated. This is done to
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram * trigger the cleanup in the guest ahead of HV reset.
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram/* ARGSUSED */
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramstatic boolean_t
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuramvsw_hio_panic_callb(void *arg, int code)
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram{
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_t *vswp = arg;
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram D1(vswp, "%s:enter\n", __func__);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram vsw_hio_reset_all(vswp);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram D1(vswp, "%s:exit\n", __func__);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram return (B_TRUE);
cdfc78ad277d82b1080e7c86213063d1b73e7789raghuram}
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG/*
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG * Setup kstats for hio statistics.
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG */
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGstatic kstat_t *
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGvsw_hio_setup_kstats(char *ks_mod, char *ks_name, vsw_t *vswp)
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG{
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kstat_t *ksp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vsw_hio_kstats_t *hiokp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vsw_hio_t *hiop;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG char share_assigned_info[MAXNAMELEN];
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG size_t size;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG int i;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop = &vswp->vhio;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG /*
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG * vsw_hio_stats_t structure is variable size structure
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG * having fields defined only for one share. So, we need
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG * allocate additional space for the rest of the shares.
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG */
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG size = sizeof (vsw_hio_kstats_t) / sizeof (kstat_named_t);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG ASSERT(hiop->vh_num_shares >= 1);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG size += ((hiop->vh_num_shares - 1) * 2);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG ksp = kstat_create(ks_mod, vswp->instance, ks_name, "misc",
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG KSTAT_TYPE_NAMED, size, KSTAT_FLAG_VIRTUAL);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG if (ksp == NULL) {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG return (NULL);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG }
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiokp = (vsw_hio_kstats_t *)kmem_zalloc(sizeof (kstat_named_t) *
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG size, KM_SLEEP);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG ksp->ks_data = hiokp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_ksp = ksp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_kstatsp = hiokp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_kstat_size = size;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kstat_named_init(&hiokp->hio_capable, "hio_capable", KSTAT_DATA_CHAR);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kstat_named_init(&hiokp->hio_num_shares, "hio_num_shares",
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG KSTAT_DATA_ULONG);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG for (i = 0; i < hiop->vh_num_shares; i++) {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG (void) sprintf(share_assigned_info, "%s%d", "hio_share_", i);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kstat_named_init(&(hiokp->share[i].assigned),
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG share_assigned_info, KSTAT_DATA_ULONG);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG (void) sprintf(share_assigned_info, "%s%d%s",
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG "hio_share_", i, "_state");
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kstat_named_init(&(hiokp->share[i].state),
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG share_assigned_info, KSTAT_DATA_ULONG);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG }
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG ksp->ks_update = vsw_hio_kstats_update;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG ksp->ks_private = (void *)vswp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kstat_install(ksp);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG return (ksp);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG}
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG/*
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG * Destroy hio kstats.
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG */
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGstatic void
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGvsw_hio_destroy_kstats(vsw_t *vswp)
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG{
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kstat_t *ksp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vsw_hio_t *hiop;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG ASSERT(vswp != NULL);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG ksp = vswp->vhio.vh_ksp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop = &vswp->vhio;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG if (ksp != NULL) {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kmem_free(hiop->vh_kstatsp, sizeof (kstat_named_t) *
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_kstat_size);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG kstat_delete(ksp);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_kstatsp = NULL;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_ksp = NULL;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG }
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG}
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG/*
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG * Update hio kstats.
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG */
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGstatic int
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANGvsw_hio_kstats_update(kstat_t *ksp, int rw)
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG{
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vsw_t *vswp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vsw_hio_t *hiop;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vsw_hio_kstats_t *hiokp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG int i;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG vswp = (vsw_t *)ksp->ks_private;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG ASSERT(vswp != NULL);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop = &vswp->vhio;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiokp = hiop->vh_kstatsp;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG if (rw == KSTAT_READ) {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG if (vswp->hio_capable) {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG (void) strcpy(hiokp->hio_capable.value.c, "Yes");
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG } else {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG /* not hio capable, just return */
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG (void) strcpy(hiokp->hio_capable.value.c, "No");
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG return (0);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG }
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiokp->hio_num_shares.value.ul = (uint32_t)hiop->vh_num_shares;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG for (i = 0; i < hiop->vh_num_shares; i++) {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiokp->share[i].assigned.value.ul =
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_shares[i].vs_macaddr;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiokp->share[i].state.value.ul =
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG hiop->vh_shares[i].vs_state;
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG } else {
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG return (EACCES);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG }
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG return (0);
6ab6cb20c72ce71fe6022b1c164f36dfe716e425WENTAO YANG}