b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * CDDL HEADER START
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The contents of this file are subject to the terms of the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Common Development and Distribution License (the "License").
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * You may not use this file except in compliance with the License.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * or http://www.opensolaris.org/os/licensing.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * See the License for the specific language governing permissions
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and limitations under the License.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * When distributing Covered Code, include this CDDL HEADER in each
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If applicable, add the following below this CDDL HEADER, with the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * fields enclosed by brackets "[]" replaced with your own identifying
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * information: Portions Copyright [yyyy] [name of copyright owner]
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * CDDL HEADER END
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/types.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/kmem.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/conf.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ddi.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/sunddi.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ksynch.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ib/clients/eoib/eib_impl.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Declarations private to this file
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int eib_vnic_get_instance(eib_t *, int *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_vnic_ret_instance(eib_t *, int);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_vnic_modify_enter(eib_t *, uint_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_vnic_modify_exit(eib_t *, uint_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int eib_vnic_create_common(eib_t *, eib_vnic_t *, int *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int eib_vnic_set_partition(eib_t *, eib_vnic_t *, int *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_vnic_make_vhub_mgid(uint8_t *, uint8_t, uint8_t *, uint8_t,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t, uint32_t, ib_gid_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int eib_vnic_attach_ctl_mcgs(eib_t *, eib_vnic_t *, int *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int eib_vnic_attach_vhub_table(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int eib_vnic_attach_vhub_update(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_vnic_start_keepalives(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int eib_vnic_lookup_dest(eib_vnic_t *, uint8_t *, uint16_t,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_map_t *, ibt_mcg_info_t *, int *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_vnic_leave_all_data_mcgs(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_vnic_rejoin_data_mcgs(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_vnic_reattach_ctl_mcgs(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_rb_vnic_create_common(eib_t *, eib_vnic_t *, uint_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_rb_vnic_attach_ctl_mcgs(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_rb_vnic_attach_vhub_table(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_rb_vnic_attach_vhub_update(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_rb_vnic_start_keepalives(eib_t *, eib_vnic_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eib_rb_vnic_join_data_mcg(eib_t *, eib_vnic_t *, uint8_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Definitions private to this file
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_STRUCT_ALLOCD 0x0001
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_GOT_INSTANCE 0x0002
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_CREATE_COMMON_DONE 0x0004
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_CTLQP_CREATED 0x0008
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_DATAQP_CREATED 0x0010
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_LOGIN_DONE 0x0020
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_PARTITION_SET 0x0040
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_RX_POSTED_TO_CTLQP 0x0080
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_RX_POSTED_TO_DATAQP 0x0100
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_ATTACHED_TO_CTL_MCGS 0x0200
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_GOT_VHUB_TABLE 0x0400
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_KEEPALIVES_STARTED 0x0800
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_VNIC_BROADCAST_JOINED 0x1000
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Destination type
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_TX_UNICAST 1
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_TX_MULTICAST 2
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define EIB_TX_BROADCAST 3
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanint
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_create(eib_t *ss, uint8_t *macaddr, uint16_t vlan, eib_vnic_t **vnicp,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int *err)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_t *vnic = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan boolean_t failed_vnic = B_FALSE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t progress = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_enter(ss, EIB_VN_BEING_CREATED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * When a previously created vnic is being resurrected due to a
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * gateway reboot, there's a race possible where a creation request
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * for the existing vnic could get filed with the vnic creator
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * thread. So, before we go ahead with the creation of this vnic,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * make sure we already don't have the vnic.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (macaddr) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_data_lookup_vnic(ss, macaddr, vlan, vnicp,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan &failed_vnic) == EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_create: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vnic for mac=%x:%x:%x:%x:%x:%x, vlan=0x%x "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "already there, no duplicate creation", macaddr[0],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan macaddr[1], macaddr[2], macaddr[3], macaddr[4],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan macaddr[5], vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_exit(ss, EIB_VN_BEING_CREATED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (failed_vnic) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_create: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vnic for mac=%x:%x:%x:%x:%x:%x, vlan=0x%x "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed earlier, shouldn't be here at all",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan macaddr[0], macaddr[1], macaddr[2], macaddr[3],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan macaddr[4], macaddr[5], vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = EEXIST;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_exit(ss, EIB_VN_BEING_CREATED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Allocate a vnic structure for this instance
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic = kmem_zalloc(sizeof (eib_vnic_t), KM_SLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_ss = ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_instance = -1;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&vnic->vn_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_init(&vnic->vn_cv, NULL, CV_DEFAULT, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_STRUCT_ALLOCD;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Get a vnic instance
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_get_instance(ss, &vnic->vn_instance) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = EMFILE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_GOT_INSTANCE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Initialize vnic's basic parameters. Note that we set the 15-bit
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * vnic id to send to gw during a login to be a 2-tuple of
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * {devi_instance#, eoib_vnic_instance#}.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_vlan = vlan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (macaddr) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(macaddr, vnic->vn_macaddr, sizeof (vnic->vn_macaddr));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id = (uint16_t)EIB_VNIC_ID(ss->ei_instance, vnic->vn_instance);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Start up this vnic instance
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_create_common(ss, vnic, err) != EIB_E_SUCCESS)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_CREATE_COMMON_DONE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Return the created vnic
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vnicp) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *vnicp = vnic;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_exit(ss, EIB_VN_BEING_CREATED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvnic_create_fail:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_create(ss, vnic, progress);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_exit(ss, EIB_VN_BEING_CREATED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_delete(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_enter(ss, EIB_VN_BEING_DELETED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_create(ss, vnic, ~0);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_exit(ss, EIB_VN_BEING_DELETED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanint
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_wait_for_login_ack(eib_t *ss, eib_vnic_t *vnic, int *err)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan clock_t deadline;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int ret = EIB_E_SUCCESS;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan deadline = ddi_get_lbolt() + drv_usectohz(EIB_LOGIN_TIMEOUT_USEC);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Wait for login ack/nack or wait time to get over. If we wake up
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * with a login failure, record the reason.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while (vnic->vn_state == EIB_LOGIN_ACK_WAIT) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (cv_timedwait(&vnic->vn_cv, &vnic->vn_lock,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan deadline) == -1) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vnic->vn_state == EIB_LOGIN_ACK_WAIT)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_state = EIB_LOGIN_TIMED_OUT;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vnic->vn_state != EIB_LOGIN_ACK_RCVD) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = EIB_E_FAILURE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = (vnic->vn_state == EIB_LOGIN_TIMED_OUT) ?
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ETIME : ECANCELED;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_login_ack(eib_t *ss, eib_login_data_t *ld)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_t *vnic;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t vnic_instance;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t hdrs_sz;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint16_t vnic_id;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int nack = 1;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The msb in the vnic id in login ack message is not
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * part of our vNIC id.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic_id = ld->ld_vnic_id & (~FIP_VL_VNIC_ID_MSBIT);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Now, we deconstruct the vnic id and determine the vnic
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * instance number. If this vnic_instance number isn't
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * valid or the vnic_id of the vnic for this instance
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * number doesn't match in our records, we quit.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic_instance = EIB_VNIC_INSTANCE(vnic_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vnic_instance >= EIB_MAX_VNICS)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * At this point, we haven't fully created the vnic, so
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * this vnic should be present as ei_vnic_pending.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((vnic = ss->ei_vnic_pending) == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (vnic->vn_id != vnic_id) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * First check if the vnic is still sleeping, waiting
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * for login ack. If not, we might as well quit now.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vnic->vn_state != EIB_LOGIN_ACK_WAIT) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We NACK the waiter under these conditions:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * . syndrome was set
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * . vhub mtu is bigger than our max mtu (minus eoib/eth hdrs sz)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * . assigned vlan is different from requested vlan (except
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * when we didn't request a specific vlan)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * . when the assigned mac is different from the requested mac
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * (except when we didn't request a specific mac)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * . when the VP bit indicates that vlan tag should be used
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * but we had not specified a vlan tag in our request
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * . when the VP bit indicates that vlan tag should not be
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * present and we'd specified a vlan tag in our request
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The last case is interesting: if we had not specified any vlan id
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * in our request, but the gateway has assigned a vlan and asks us
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to use/expect that tag on every packet dealt by this vnic, it
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * means effectively the EoIB driver has to insert/remove vlan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * tagging on this vnic traffic, since the nw layer on Solaris
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * won't be using/expecting any tag on traffic for this vnic. This
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * feature is not supported currently.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan hdrs_sz = EIB_ENCAP_HDR_SZ + sizeof (struct ether_header) + VLAN_TAGSZ;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ld->ld_syndrome) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_login_ack: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "non-zero syndrome 0x%lx, NACK", ld->ld_syndrome);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (ld->ld_vhub_mtu > (ss->ei_props->ep_mtu - hdrs_sz)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_login_ack: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vhub mtu (0x%x) bigger than port mtu (0x%x), NACK",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_vhub_mtu, ss->ei_props->ep_mtu);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if ((vnic->vn_vlan) && (vnic->vn_vlan != ld->ld_assigned_vlan)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_login_ack: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "assigned vlan (0x%x) different from asked (0x%x), "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "for vnic id 0x%x, NACK", ld->ld_assigned_vlan,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_vlan, vnic->vn_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (bcmp(vnic->vn_macaddr, eib_zero_mac, ETHERADDRL) &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcmp(vnic->vn_macaddr, ld->ld_assigned_mac, ETHERADDRL)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *asked, *got;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan asked = vnic->vn_macaddr;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan got = ld->ld_assigned_mac;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_login_ack: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "assigned mac (%x:%x:%x:%x:%x:%x) different from "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "asked (%x:%x:%x:%x:%x:%x) for vnic id 0x%x, NACK",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan got[0], got[1], got[2], got[3], got[4], got[5], asked[0],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan asked[1], asked[2], asked[3], asked[4], asked[5]);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if ((vnic->vn_vlan == 0) && (ld->ld_vlan_in_packets)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_login_ack: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "asked for tagless vlan, but VP flag is set "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "for vnic id 0x%x, NACK", vnic->vn_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if ((vnic->vn_vlan) && (!ld->ld_vlan_in_packets)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_wa_no_good_vp_flag) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_vlan_in_packets = 1;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_vhub_id = EIB_VHUB_ID(ld->ld_gw_port_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_assigned_vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan nack = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_login_ack: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vlan was assigned correctly, but VP flag is not "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "set for vnic id 0x%x, NACK", vnic->vn_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_vhub_id = EIB_VHUB_ID(ld->ld_gw_port_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_assigned_vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan nack = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * ACK/NACK the waiter
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (nack) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_state = EIB_LOGIN_NACK_RCVD;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(ld, &vnic->vn_login_data, sizeof (eib_login_data_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_state = EIB_LOGIN_ACK_RCVD;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_signal(&vnic->vn_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanint
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_wait_for_table(eib_t *ss, eib_vnic_t *vnic, int *err)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan clock_t deadline;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int ret = EIB_E_SUCCESS;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The EoIB spec does not detail exactly within what time a vhub table
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * request is expected to be answered. However, it does mention that
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * in the worst case, the vhub update messages from the gateway must
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * be seen atleast once in 2.5 * GW_KA_PERIOD (already saved in
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * pp_gw_ka_ticks), so we'll settle for that limit.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan deadline = ddi_get_lbolt() + ss->ei_gw_props->pp_gw_ka_ticks;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Wait for vhub table to be constructed. If we wake up with a
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * vhub table construction failure, record the reason.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while (vnic->vn_state == EIB_LOGIN_TBL_WAIT) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (cv_timedwait(&vnic->vn_cv, &vnic->vn_lock,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan deadline) == -1) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vnic->vn_state == EIB_LOGIN_TBL_WAIT)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_state = EIB_LOGIN_TIMED_OUT;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vnic->vn_state != EIB_LOGIN_TBL_DONE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = EIB_E_FAILURE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = (vnic->vn_state == EIB_LOGIN_TIMED_OUT) ?
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ETIME : ECANCELED;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_vhub_table_done(eib_vnic_t *vnic, uint_t result_state)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(result_state == EIB_LOGIN_TBL_DONE ||
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan result_state == EIB_LOGIN_TBL_FAILED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Construction of vhub table for the vnic is done one way or
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the other. Set the login wait state appropriately and signal
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the waiter. If it's a vhub table failure, we shouldn't parse
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * any more vhub table or vhub update packets until the vnic state
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * is changed.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_state = result_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_signal(&vnic->vn_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanint
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_join_data_mcg(eib_t *ss, eib_vnic_t *vnic, uint8_t *mcast_mac,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan boolean_t rejoin, int *err)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_data_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_login_data_t *ld = &vnic->vn_login_data;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *elem;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *tail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_mcg_info_t *mcg_info;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_mcg_attr_t mcg_attr;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Compose the multicast MGID to join
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bzero(&mcg_attr, sizeof (ibt_mcg_attr_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_make_vhub_mgid(ld->ld_gw_mgid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (uint8_t)EIB_MGID_VHUB_DATA, mcast_mac, ld->ld_n_mac_mcgid, 0,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_vhub_id, &(mcg_attr.mc_mgid));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_pkey = (ib_pkey_t)ld->ld_vhub_pkey;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_qkey = (ib_qkey_t)EIB_DATA_QKEY;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Allocate for and prepare the mcg to add to our list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_info = kmem_zalloc(sizeof (ibt_mcg_info_t), KM_NOSLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg_info == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_join_data_mcg: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "no memory, failed to join mcg (mac=%x:%x:%x:%x:%x:%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcast_mac[0], mcast_mac[1], mcast_mac[2],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcast_mac[3], mcast_mac[4], mcast_mac[5]);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = ENOMEM;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_join_data_mcg_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg = kmem_zalloc(sizeof (eib_mcg_t), KM_NOSLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_join_data_mcg: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "no memory, failed to join mcg (mac=%x:%x:%x:%x:%x:%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcast_mac[0], mcast_mac[1], mcast_mac[2],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcast_mac[3], mcast_mac[4], mcast_mac[5]);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = ENOMEM;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_join_data_mcg_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_rgid = ss->ei_props->ep_sgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid = mcg_attr.mc_mgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_join_state = IB_MC_JSTATE_FULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mcginfo = mcg_info;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(mcast_mac, mcg->mg_mac, ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Join the multicast group
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Should we query for the mcg and join instead of attempting to
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * join directly ?
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_join_state = mcg->mg_join_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_flow = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_tclass = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_sl = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_scope = 0; /* IB_MC_SCOPE_SUBNET_LOCAL perhaps ? */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_join_mcg(mcg->mg_rgid, &mcg_attr, mcg_info, NULL, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_join_data_mcg: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_join_mcg(mgid=%llx.%llx, pkey=0x%x, qkey=0x%lx, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "jstate=0x%x) failed, ret=%d", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_qkey, mcg_attr.mc_join_state, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = EINVAL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_join_data_mcg_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Attach to the group to receive multicast messages
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_attach_mcg(chan->ch_chan, mcg_info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = EINVAL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_join_data_mcg: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, mcg->mg_join_state, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_join_data_mcg_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tail = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = chan->ch_vhub_data; elem != NULL; elem = elem->mg_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((elem->mg_mgid.gid_prefix == mcg_attr.mc_mgid.gid_prefix) &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (elem->mg_mgid.gid_guid == mcg_attr.mc_mgid.gid_guid)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tail = elem;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we had't already joined to this mcg, add the newly joined mcg
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to the tail and return success
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (tail)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tail->mg_next = mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan else
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan->ch_vhub_data = mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Duplicate. We need to leave one of the two joins. If "rejoin"
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * was requested, leave the old join, otherwise leave the new join.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Note that we must not detach the qp from the mcg, since if this
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * was a dup, a second ibt_attach_mcg() above would've simply been
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * a nop.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Note also that the leave may not be successful here if our presence
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * has been removed by the SM, but we need to do this to prevent leaks
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * in ibtf.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (rejoin) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(elem->mg_mcginfo != NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(elem->mg_mcginfo, sizeof (ibt_mcg_info_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ibt_leave_mcg(elem->mg_rgid, elem->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, elem->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Copy the new mcg over the old one (including the new
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * mg_mcginfo), but preserve the link to the next element
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * on the list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_next = elem->mg_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(mcg, elem, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(mcg->mg_mcginfo != NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg->mg_mcginfo, sizeof (ibt_mcg_info_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvnic_join_data_mcg_fail:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg_info) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg_info, sizeof (ibt_mcg_info_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanint
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_setup_dest(eib_vnic_t *vnic, eib_wqe_t *swqe, uint8_t *dmac,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint16_t vlan)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_t *ss = vnic->vn_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_stats_t *stats = ss->ei_stats;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_avect_t *av;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_map_t ucast;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_mcg_info_t mcast;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int dtype;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int rv;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Lookup the destination in the vhub table or in our mcg list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan rv = eib_vnic_lookup_dest(vnic, dmac, vlan, &ucast, &mcast, &dtype);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (rv != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_setup_dest: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_lookup_dest(dmac=%x:%x:%x:%x:%x:%x, vlan=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed", dmac[0], dmac[1], dmac[2], dmac[3], dmac[4],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dmac[5], vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we found a unicast address, get an address vector for the lid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and sl, modify the ud dest based on the address vector and return.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we found a multicast address, use the address vector in the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * mcg info to modify the ud dest and return.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (dtype == EIB_TX_UNICAST) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((av = eib_ibt_hold_avect(ss, ucast.mp_lid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ucast.mp_sl)) == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_setup_dest: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_ibt_hold_avect(lid=0x%x, sl=0x%x) failed",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ucast.mp_lid, ucast.mp_sl);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_modify_ud_dest(swqe->qe_dest, EIB_DATA_QKEY,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ucast.mp_qpn, &av->av_vect);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_ibt_release_avect(ss, av);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_setup_dest: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_modify_ud_dest(qpn=0x%lx, qkey=0x%lx) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", ucast.mp_qpn, EIB_DATA_QKEY, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_modify_ud_dest(swqe->qe_dest, EIB_DATA_QKEY,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan IB_MC_QPN, &(mcast.mc_adds_vect));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (dtype == EIB_TX_BROADCAST)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_INCR_COUNTER(&stats->st_brdcstxmit);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan else
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_INCR_COUNTER(&stats->st_multixmit);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_setup_dest: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_modify_ud_dest(mc_qpn=0x%lx, qkey=0x%lx) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", IB_MC_QPN, EIB_DATA_QKEY, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_leave_data_mcg(eib_t *ss, eib_vnic_t *vnic, uint8_t *mcast_mac)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_join_data_mcg(ss, vnic, mcast_mac);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_init_tables(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_table_t *tbl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_update_t *upd;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl = kmem_zalloc(sizeof (eib_vhub_table_t), KM_SLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&tbl->tb_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_eport_state = FIP_EPORT_UP;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan upd = kmem_zalloc(sizeof (eib_vhub_update_t), KM_SLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&upd->up_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_vhub_table = tbl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_vhub_update = upd;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_fini_tables(eib_t *ss, eib_vnic_t *vnic, boolean_t clobber)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_update_t *upd;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_table_t *tbl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_map_t *elem;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_map_t *nxt;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int i;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We come here only when we've either completely detached from
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the vhub multicast groups and so cannot receive anymore table
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * or update control messages, or we've had a recent vhub table
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * construction failure and the vnic state is currently
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * EIB_LOGIN_TBL_FAILED and so won't parse any table or update
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * control messages. Also, since we haven't completed the vnic
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * creation, no one from the tx path will be accessing the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * vn_vhub_table entries either. All said, we're free to play
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * around with the vnic's vn_vhub_table and vn_vhub_update here.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan upd = vnic->vn_vhub_update;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl = vnic->vn_vhub_table;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (clobber) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_vhub_update = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_vhub_table = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Destroy the vhub update entries if any
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (upd) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Wipe clean the list of vnic entries accumulated via
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * vhub updates so far. Release eib_vhub_update_t only
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * if explicitly asked to do so
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&upd->up_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = upd->up_vnic_entry; elem != NULL; elem = nxt) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan nxt = elem->mp_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(elem, sizeof (eib_vhub_map_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan upd->up_vnic_entry = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan upd->up_tusn = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan upd->up_eport_state = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&upd->up_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (clobber) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_destroy(&upd->up_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(upd, sizeof (eib_vhub_update_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Destroy the vhub table entries
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (tbl == NULL)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Wipe clean the list of entries in the vhub table collected so
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * far. Release eib_vhub_table_t only if explicitly asked to do so.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&tbl->tb_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (tbl->tb_gateway) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(tbl->tb_gateway, sizeof (eib_vhub_map_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_gateway = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (tbl->tb_unicast_miss) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(tbl->tb_unicast_miss, sizeof (eib_vhub_map_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_unicast_miss = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (tbl->tb_vhub_multicast) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(tbl->tb_vhub_multicast, sizeof (eib_vhub_map_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_vhub_multicast = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (!eib_wa_no_mcast_entries) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (i = 0; i < EIB_TB_NBUCKETS; i++) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = tbl->tb_mcast_entry[i]; elem != NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan elem = nxt) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan nxt = elem->mp_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(elem, sizeof (eib_vhub_map_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_mcast_entry[i] = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (i = 0; i < EIB_TB_NBUCKETS; i++) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = tbl->tb_vnic_entry[i]; elem != NULL; elem = nxt) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan nxt = elem->mp_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(elem, sizeof (eib_vhub_map_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_vnic_entry[i] = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_tusn = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_eport_state = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_entries_seen = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_entries_in_table = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan tbl->tb_checksum = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&tbl->tb_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Don't throw away space created for holding vhub table if we haven't
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * been explicitly asked to do so
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (clobber) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_destroy(&tbl->tb_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(tbl, sizeof (eib_vhub_table_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_chan_t *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_get_data_chan(eib_t *ss, int vinst)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_t *vnic;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vinst >= 0 && vinst < EIB_MAX_VNICS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((vnic = ss->ei_vnic[vinst]) != NULL)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan = vnic->vn_data_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (chan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_need_new(eib_t *ss, uint8_t *mac, uint16_t vlan)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_req_t *vrq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_INCR_COUNTER(&ss->ei_stats->st_noxmitbuf);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Create a new vnic request for this {mac,vlan} tuple
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq = kmem_zalloc(sizeof (eib_vnic_req_t), KM_NOSLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vrq == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_need_new: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "no memory, failed to queue new vnic creation request");
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_req = EIB_CR_REQ_NEW_VNIC;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(mac, vrq->vr_mac, ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_vlan = vlan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_enqueue_req(ss, vrq);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_enqueue_req(eib_t *ss, eib_vnic_req_t *vrq)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_req_t *elem = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *m;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Enqueue this new vnic request with the vnic creator and
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * signal it.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan m = vrq->vr_mac;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance, "eib_vnic_enqueue_req: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "BEGIN file request for creation of %x:%x:%x:%x:%x:%x, 0x%x",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan m[0], m[1], m[2], m[3], m[4], m[5], vrq->vr_vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_req_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Death request has the highest priority. If we've already been asked
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to die, we don't entertain any more requests.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ss->ei_vnic_req) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ss->ei_vnic_req->vr_req == EIB_CR_REQ_DIE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_req_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(vrq, sizeof (eib_vnic_req_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vrq->vr_req == EIB_CR_REQ_DIE || vrq->vr_req == EIB_CR_REQ_FLUSH) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_next = ss->ei_vnic_req;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic_req = vrq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If there's already a creation request for this vnic that's
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * being processed, return immediately without adding a new
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * request.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((elem = ss->ei_pending_vnic_req) != NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_enqueue_req: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ei_pending_vnic_req not NULL");
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((elem->vr_vlan == vrq->vr_vlan) &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (bcmp(elem->vr_mac, vrq->vr_mac,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ETHERADDRL) == 0)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_enqueue_req: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "pending request already present for "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "%x:%x:%x:%x:%x:%x, 0x%x", m[0], m[1], m[2],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan m[3], m[4], m[5], vrq->vr_vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_req_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(vrq, sizeof (eib_vnic_req_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_enqueue_req: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "END file request");
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_enqueue_req: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "NO pending request for %x:%x:%x:%x:%x:%x, 0x%x",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan m[0], m[1], m[2], m[3], m[4], m[5], vrq->vr_vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Or if there's one waiting in the queue for processing, do
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the same thing
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = ss->ei_vnic_req; elem; elem = elem->vr_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If there's already a create request for this vnic
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * waiting in the queue, return immediately
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem->vr_req == EIB_CR_REQ_NEW_VNIC) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((elem->vr_vlan == vrq->vr_vlan) &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (bcmp(elem->vr_mac, vrq->vr_mac,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ETHERADDRL) == 0)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_enqueue_req: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "request already present for "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "%x:%x:%x:%x:%x:%x, 0x%x", m[0],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan m[1], m[2], m[3], m[4], m[5],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_req_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(vrq, sizeof (eib_vnic_req_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_enqueue_req: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "END file request");
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem->vr_next == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_enqueue_req: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "request not found, filing afresh");
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Otherwise queue up this new creation request and signal the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * service thread.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan elem->vr_next = vrq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic_req = vrq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_signal(&ss->ei_vnic_req_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_req_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_enqueue_req: END file request");
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_update_failed_macs(eib_t *ss, uint8_t *old_mac, uint16_t old_vlan,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *new_mac, uint16_t new_vlan)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_req_t *vrq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_req_t *elem;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_req_t *prev;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq = kmem_zalloc(sizeof (eib_vnic_req_t), KM_NOSLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vrq == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_update_failed_macs: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "no memory, failed to drop old mac");
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_req = 0; /* unused */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(old_mac, vrq->vr_mac, ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_vlan = old_vlan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_req_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We'll search the failed vnics list to see if the new {mac,vlan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * tuple is in there and remove it if present (since the new address
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * is no longer "failed").
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan prev = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = ss->ei_failed_vnic_req; elem; elem = elem->vr_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((bcmp(elem->vr_mac, new_mac, ETHERADDRL) == 0) &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (elem->vr_vlan == new_vlan)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (prev) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan prev->vr_next = elem->vr_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_failed_vnic_req = elem->vr_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan elem->vr_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(elem, sizeof (eib_vnic_req_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We'll also insert the old {mac,vlan} tuple to the "failed vnic req"
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * list (it shouldn't be there already), to avoid trying to recreate
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the vnic we just explicitly discarded.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vrq) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vrq->vr_next = ss->ei_failed_vnic_req;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_failed_vnic_req = vrq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_req_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_resurrect_zombies(eib_t *ss, uint8_t *vn0_mac)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int inst;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We want to restart/relogin each vnic instance with the gateway,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * but with the same vnic id and instance as before.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while ((inst = EIB_FIND_LSB_SET(ss->ei_zombie_vnics)) != -1) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_resurrect_zombies: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "calling eib_vnic_restart(vn_inst=%d)", inst);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_restart(ss, inst, vn0_mac);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_resurrect_zombies: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_restart(vn_inst=%d) done", inst);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_restart(eib_t *ss, int inst, uint8_t *vn0_mac)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_t *vnic;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_login_data_t *ld;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t old_mac[ETHERADDRL];
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int err;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (inst < 0 || inst >= EIB_MAX_VNICS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_restart: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vnic instance (%d) invalid", inst);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_enter(ss, EIB_VN_BEING_MODIFIED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((vnic = ss->ei_vnic[inst]) != NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Remember what mac was allocated for this vnic last time
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(vnic->vn_login_data.ld_assigned_mac, old_mac, ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Tear down and restart this vnic instance
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_create_common(ss, vnic, ~0);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = eib_vnic_create_common(ss, vnic, &err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_restart: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common(vnic_inst=%d) failed, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ret=%d", inst, err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If this is vnic instance 0 and if our current assigned mac is
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * different from what was assigned last time, we need to pass
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * this information back to the caller, so the mac layer can be
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * appropriately informed. We will also queue up the old mac
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and vlan in the "failed vnic req" list, so any future packets
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to this address on this interface will be dropped.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld = &vnic->vn_login_data;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((inst == 0) &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (bcmp(ld->ld_assigned_mac, old_mac, ETHERADDRL) != 0)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *m = ld->ld_assigned_mac;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vn0_mac != NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(ld->ld_assigned_mac, vn0_mac,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_VERBOSE(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_restart: updating failed macs list "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "old=%x:%x:%x:%x:%x:%x, new=%x:%x:%x:%x:%x:%x, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vlan=0x%x", old_mac[0], old_mac[1], old_mac[2],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan old_mac[3], old_mac[4], old_mac[5], m[0], m[1],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan m[2], m[3], m[4], m[5], vnic->vn_vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_update_failed_macs(ss, old_mac, vnic->vn_vlan,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_assigned_mac, vnic->vn_vlan);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * No longer a zombie or need to rejoin mcgs
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_zombie_vnics &= (~((uint64_t)1 << inst));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_rejoin_vnics &= (~((uint64_t)1 << inst));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_modify_exit(ss, EIB_VN_BEING_MODIFIED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_rejoin_mcgs(eib_t *ss)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_t *vnic;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int inst;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * For each vnic that still requires re-join, go through the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * control channels and data channel and reattach/rejoin mcgs.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while ((inst = EIB_FIND_LSB_SET(ss->ei_rejoin_vnics)) != -1) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((vnic = ss->ei_vnic[inst]) != NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_reattach_ctl_mcgs(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_rejoin_data_mcgs(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_rejoin_vnics &= (~((uint64_t)1 << inst));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_rb_vnic_create(eib_t *ss, eib_vnic_t *vnic, uint_t progress)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_CREATE_COMMON_DONE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_create_common(ss, vnic, ~0);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_GOT_INSTANCE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_ret_instance(ss, vnic->vn_instance);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_instance = -1;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_STRUCT_ALLOCD) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_destroy(&vnic->vn_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_destroy(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(vnic, sizeof (eib_vnic_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Currently, we only allow 64 vnics per eoib device instance, for
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * reasons described in eib.h (see EIB_VNIC_ID() definition), so we
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * could use a simple bitmap to assign the vnic instance numbers.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Once we start allowing more vnics per device instance, this
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * allocation scheme will need to be changed.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_get_instance(eib_t *ss, int *vinst)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int bitpos;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint64_t nval;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * What we have is the active vnics list -- the in-use vnics are
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * indicated by a 1 in the bit position, and the free ones are
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * indicated by 0. We need to find the least significant '0' bit
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to get the first free vnic instance. Or we could bit-reverse
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the active list and locate the least significant '1'.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan nval = ~(ss->ei_active_vnics);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (nval == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The single bit-position values in a 64-bit integer are relatively
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * prime with 67, so performing a modulus division with 67 guarantees
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * a unique number between 0 and 63 for each value (setbit_mod67[]).
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bitpos = EIB_FIND_LSB_SET(nval);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (bitpos == -1)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_active_vnics |= ((uint64_t)1 << bitpos);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *vinst = bitpos;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_ret_instance(eib_t *ss, int vinst)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (vinst >= EIB_MAX_VNICS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_ret_instance: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vnic instance (%d) invalid", vinst);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if ((ss->ei_active_vnics & ((uint64_t)1 << vinst)) == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_ret_instance: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vnic instance (%d) not active!", vinst);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_active_vnics &= (~((uint64_t)1 << vinst));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_modify_enter(eib_t *ss, uint_t op)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while (ss->ei_vnic_state & EIB_VN_BEING_MODIFIED)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_wait(&ss->ei_vnic_cv, &ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic_state |= op;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_modify_exit(eib_t *ss, uint_t op)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic_state &= (~op);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_broadcast(&ss->ei_vnic_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_create_common(eib_t *ss, eib_vnic_t *vnic, int *err)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t progress = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * When we receive login acks within this vnic creation
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * routine we need a way to retrieve the vnic structure
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * from the vnic instance, so store this somewhere. Note
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * that there can be only one outstanding vnic creation
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * at any point of time, so we only need one vnic struct.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(ss->ei_vnic_pending == NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic_pending = vnic;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Create a control qp for this vnic
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_ctl_create_qp(ss, vnic, err) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_ctl_create_qp(vn_id=0x%x) failed, ret=%d",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_CTLQP_CREATED;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Create a data qp for this vnic
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_data_create_qp(ss, vnic, err) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_data_create_qp(vn_id=0x%x) failed, ret=%d",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_DATAQP_CREATED;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Login to the gateway with this vnic's parameters
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_fip_login(ss, vnic, err) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_fip_login(vn_id=0x%x) failed, ret=%d",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_LOGIN_DONE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Associate the control and data qps for the vnic with the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * vHUB partition
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_set_partition(ss, vnic, err) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_set_partition(vn_id=0x%x) failed, ret=%d",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_PARTITION_SET;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Post initial set of rx buffers on the control qp to the HCA
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_chan_post_rx(ss, vnic->vn_ctl_chan, NULL) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_chan_post_rx(vn_id=0x%x, CTL_QP) failed, ret=%d",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = ENOMEM;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_RX_POSTED_TO_CTLQP;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Post initial set of rx buffers on the data qp to the HCA
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_chan_post_rx(ss, vnic->vn_data_chan, NULL) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_chan_post_rx(vn_id=0x%x, DATA_QP) failed, ret=%d",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = ENOMEM;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_RX_POSTED_TO_DATAQP;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Attach to the vHUB table and vHUB update multicast groups
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_attach_ctl_mcgs(ss, vnic, err) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_ctl_mcgs(vn_id=0x%x) failed, ret=%d",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_ATTACHED_TO_CTL_MCGS;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Send the vHUB table request and construct the vhub table
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_fip_vhub_table(ss, vnic, err) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_fip_vhub_table(vn_id=0x%x) failed, ret=%d",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_GOT_VHUB_TABLE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Detach from the vHUB table mcg (we no longer need the vHUB
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * table messages) and start the keepalives for this vnic.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_start_keepalives(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_attach_vhub_table(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_KEEPALIVES_STARTED;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * All ethernet vnics are automatically members of the broadcast
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * group for the vlan they are participating in, so join the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * ethernet broadcast group. Note that when we restart vnics,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * we rejoin the mcgs, so we pass B_TRUE to eib_vnic_join_data_mcg().
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_join_data_mcg(ss, vnic, eib_broadcast_mac, B_TRUE,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan err) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_create_common: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_join_data_mcg(vn_id=0x%x, BCAST_GROUP) failed, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ret=%d", vnic->vn_id, *err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto vnic_create_common_fail;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan progress |= EIB_VNIC_BROADCAST_JOINED;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ss->ei_vnic[vnic->vn_instance] == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic[vnic->vn_instance] = vnic;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic_pending = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvnic_create_common_fail:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_create_common(ss, vnic, progress);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_set_partition(eib_t *ss, eib_vnic_t *vnic, int *err)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Associate the control channel with the vhub partition
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = eib_ibt_modify_chan_pkey(ss, vnic->vn_ctl_chan,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_login_data.ld_vhub_pkey);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_set_partition: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_ibt_modify_chan_pkey(vn_id=0x%x, CTL_CHAN, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vhub_pkey=0x%x) failed", vnic->vn_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_login_data.ld_vhub_pkey);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = EINVAL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Now, do the same thing for the data channel. Note that if a
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * failure happens, the channel state(s) are left as-is, since
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * it is pointless to try to change them back using the same
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * interfaces that have just failed.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = eib_ibt_modify_chan_pkey(ss, vnic->vn_data_chan,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_login_data.ld_vhub_pkey);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_set_partition: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_ibt_modify_chan_pkey(vn_id=0x%x, DATA_CHAN, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "vhub_pkey=0x%x) failed", vnic->vn_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_login_data.ld_vhub_pkey);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = EINVAL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_make_vhub_mgid(uint8_t *mg_prefix, uint8_t mg_type,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *mcast_mac, uint8_t n_mac, uint8_t rss_hash, uint32_t vhub_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ib_gid_t *mgid)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mgid_t em;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint64_t dmac_mask;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint64_t dmac = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *dmac_str = (uint8_t *)&dmac;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t vhub_id_nw;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *vhub_id_str = (uint8_t *)&vhub_id_nw;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Copy mgid prefix and type
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(mg_prefix, em.gd_spec.sp_mgid_prefix, FIP_MGID_PREFIX_LEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan em.gd_spec.sp_type = mg_type;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Take n_mac bits from mcast_mac and copy dmac
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(mcast_mac, dmac_str + 2, ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dmac_mask = ((uint64_t)1 << n_mac) - 1;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dmac_mask = htonll(dmac_mask);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dmac &= dmac_mask;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(dmac_str + 2, em.gd_spec.sp_dmac, ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Copy rss hash and prepare vhub id from gw port id and vlan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan em.gd_spec.sp_rss_hash = rss_hash;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vhub_id_nw = htonl(vhub_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(vhub_id_str + 1, em.gd_spec.sp_vhub_id, FIP_VHUBID_LEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Ok, now we've assembled the mgid as per EoIB spec. We now have to
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * represent it in the way Solaris IBTF wants it and return (sigh).
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mgid->gid_prefix = ntohll(em.gd_sol.gid_prefix);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mgid->gid_guid = ntohll(em.gd_sol.gid_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_attach_ctl_mcgs(eib_t *ss, eib_vnic_t *vnic, int *err)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Get tb_vhub_table and tb_vhub_update allocated and ready before
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * attaching to the vhub table and vhub update mcgs
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_init_tables(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_attach_vhub_update(ss, vnic) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_ctl_mcgs: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_update(vn_id=0x%x) failed",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = EINVAL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_fini_tables(ss, vnic, B_TRUE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_attach_vhub_table(ss, vnic) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_ctl_mcgs: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_table(vn_id=0x%x) failed",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *err = EINVAL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_attach_vhub_update(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_fini_tables(ss, vnic, B_TRUE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_attach_vhub_table(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_ctl_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_login_data_t *ld = &vnic->vn_login_data;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_mcg_info_t *tbl_mcginfo;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_mcg_attr_t mcg_attr;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t entries;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Compose the MGID for receiving VHUB table
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bzero(&mcg_attr, sizeof (ibt_mcg_attr_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_make_vhub_mgid(ld->ld_gw_mgid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (uint8_t)EIB_MGID_VHUB_TABLE, eib_broadcast_mac, ld->ld_n_mac_mcgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan 0, ld->ld_vhub_id, &(mcg_attr.mc_mgid));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_pkey = (ib_pkey_t)ld->ld_vhub_pkey;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_qkey = (ib_qkey_t)EIB_FIP_QKEY;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Locate the multicast group for receiving vhub table
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_query_mcg(ss->ei_props->ep_sgid, &mcg_attr, 1,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan &tbl_mcginfo, &entries);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_table: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_query_mcg(mgid=%llx.%llx, pkey=0x%x) failed, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ret=%d", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Allocate for and prepare the mcg to add to our list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg = kmem_zalloc(sizeof (eib_mcg_t), KM_NOSLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_table: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "no memory, failed to attach to vhub table "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(mgid=%llx.%llx, pkey=0x%x)", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_mcg_info(tbl_mcginfo, 1);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_rgid = ss->ei_props->ep_sgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid = mcg_attr.mc_mgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_join_state = IB_MC_JSTATE_FULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mcginfo = tbl_mcginfo;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(eib_broadcast_mac, mcg->mg_mac, ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Join the multicast group
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_join_state = mcg->mg_join_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_flow = tbl_mcginfo->mc_adds_vect.av_flow;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_tclass = tbl_mcginfo->mc_adds_vect.av_tclass;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_sl = tbl_mcginfo->mc_adds_vect.av_srvl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_scope = 0; /* IB_MC_SCOPE_SUBNET_LOCAL perhaps ? */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_join_mcg(mcg->mg_rgid, &mcg_attr, tbl_mcginfo, NULL, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_table: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_join_mcg(mgid=%llx.%llx, pkey=0x%x, jstate=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_join_state, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_mcg_info(tbl_mcginfo, 1);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Attach to the multicast group to receive tbl multicasts
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_attach_mcg(chan->ch_chan, tbl_mcginfo);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_table: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_attach_mcg(mgid=%llx.%llx, pkey=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_mcg_info(tbl_mcginfo, 1);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan->ch_vhub_table = mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_attach_vhub_update(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_ctl_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_login_data_t *ld = &vnic->vn_login_data;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_mcg_info_t *upd_mcginfo;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_mcg_attr_t mcg_attr;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t entries;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Compose the MGID for receiving VHUB updates
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bzero(&mcg_attr, sizeof (ibt_mcg_attr_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_make_vhub_mgid(ld->ld_gw_mgid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (uint8_t)EIB_MGID_VHUB_UPDATE, eib_broadcast_mac,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ld->ld_n_mac_mcgid, 0, ld->ld_vhub_id, &(mcg_attr.mc_mgid));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_pkey = (ib_pkey_t)ld->ld_vhub_pkey;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_qkey = (ib_qkey_t)EIB_FIP_QKEY;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Locate the multicast group for receiving vhub updates
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_query_mcg(ss->ei_props->ep_sgid, &mcg_attr, 1,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan &upd_mcginfo, &entries);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_update: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_query_mcg(mgid=%llx.%llx, pkey=0x%x) failed, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ret=%d", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Allocate for and prepare the mcg to add to our list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg = kmem_zalloc(sizeof (eib_mcg_t), KM_NOSLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_update: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "no memory, failed to attach to vhub update "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(mgid=%llx.%llx, pkey=0x%x)", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_mcg_info(upd_mcginfo, 1);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_rgid = ss->ei_props->ep_sgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid = mcg_attr.mc_mgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_join_state = IB_MC_JSTATE_FULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mcginfo = upd_mcginfo;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(eib_broadcast_mac, mcg->mg_mac, ETHERADDRL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Join the multicast group
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_join_state = mcg->mg_join_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_flow = upd_mcginfo->mc_adds_vect.av_flow;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_tclass = upd_mcginfo->mc_adds_vect.av_tclass;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_sl = upd_mcginfo->mc_adds_vect.av_srvl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_scope = 0; /* IB_MC_SCOPE_SUBNET_LOCAL perhaps ? */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_join_mcg(mcg->mg_rgid, &mcg_attr, upd_mcginfo, NULL, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_update: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_join_mcg(mgid=%llx.%llx, pkey=0x%x, jstate=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_join_state, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_mcg_info(upd_mcginfo, 1);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Attach to the multicast group to receive upd multicasts
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_attach_mcg(chan->ch_chan, upd_mcginfo);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_update: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_attach_mcg(mgid=%llx.%llx, pkey=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg_attr.mc_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg_attr.mc_mgid.gid_guid, mcg_attr.mc_pkey);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_mcg_info(upd_mcginfo, 1);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan->ch_vhub_update = mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_start_keepalives(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_ka_vnics_t *kav;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_ka_vnics_t *elem;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int err;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kav = kmem_zalloc(sizeof (eib_ka_vnics_t), KM_SLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kav->ka_vnic = vnic;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kav->ka_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Send the first keepalive and then queue this vnic up with
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the keepalives manager
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eib_fip_heartbeat(ss, vnic, &err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_ka_vnics_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = ss->ei_ka_vnics; elem; elem = elem->ka_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem->ka_next == NULL)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan elem->ka_next = kav;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_ka_vnics = kav;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_ka_vnics_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_lookup_dest(eib_vnic_t *vnic, uint8_t *dmac, uint16_t vlan,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_map_t *ucast, ibt_mcg_info_t *mcast, int *dtype)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_t *ss = vnic->vn_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_map_t *elem;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_data_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_login_data_t *ld = &vnic->vn_login_data;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_map_t *gw;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vhub_table_t *tbl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t bkt = (dmac[ETHERADDRL-1]) % EIB_TB_NBUCKETS;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ib_gid_t mgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If this was a unicast dmac, locate the vhub entry matching the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * unicast dmac in our vhub table. If it's not found, return the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * gateway entry
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (EIB_UNICAST_MAC(dmac)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((tbl = vnic->vn_vhub_table) == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&tbl->tb_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gw = tbl->tb_gateway;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = tbl->tb_vnic_entry[bkt]; elem != NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan elem = elem->mp_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (bcmp(elem->mp_mac, dmac, ETHERADDRL) == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&tbl->tb_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((elem == NULL) && (gw == NULL)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *dtype = EIB_TX_UNICAST;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(elem, ucast, sizeof (eib_vhub_map_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gw, ucast, sizeof (eib_vhub_map_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&vnic->vn_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Is it a broadcast ?
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *dtype = (bcmp(dmac, eib_broadcast_mac, ETHERADDRL) == 0) ?
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_TX_BROADCAST : EIB_TX_MULTICAST;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If this was a multicast dmac, prepare the mgid and look for it
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * in the list of mcgs we've joined and use the address vector from
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the mcginfo stored there.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Note that since we don't have a way to associate each vlan with
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the mcg (see eib_m_multicast()), we'll prepare the mgid to use
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the broadcast channel all the time.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_make_vhub_mgid(ld->ld_gw_mgid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (uint8_t)EIB_MGID_VHUB_DATA, eib_broadcast_mac, ld->ld_n_mac_mcgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan 0, ld->ld_vhub_id, &mgid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (mcg = chan->ch_vhub_data; mcg; mcg = mcg->mg_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((mcg->mg_mgid.gid_prefix == mgid.gid_prefix) &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (mcg->mg_mgid.gid_guid == mgid.gid_guid)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_lookup_dest: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "could not find mgid %llx.%llx",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mgid.gid_prefix, mgid.gid_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(mcg->mg_mcginfo, mcast, sizeof (ibt_mcg_info_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (EIB_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_leave_all_data_mcgs(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_data_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcglist;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *nxt = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * First, take the ch_vhub_data mcg chain out of chan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcglist = chan->ch_vhub_data;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan->ch_vhub_data = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Go through the chain of mcgs we've joined, detach the qp from the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * mcg, leave the group and free all associated stuff
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (mcg = mcglist; mcg != NULL; mcg = nxt) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan nxt = mcg->mg_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_detach_mcg(chan->ch_chan, mcg->mg_mcginfo);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_leave_all_data_mcgs: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_detach_mcg(chan_hdl=0x%llx, mcinfo=0x%llx, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "mgid=%llx.%llx) failed, ret=%d", chan->ch_chan,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mcginfo, mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_leave_all_data_mcgs: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, mcg->mg_join_state, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg->mg_mcginfo)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg->mg_mcginfo, sizeof (ibt_mcg_info_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_rejoin_data_mcgs(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_data_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcglist;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int err;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Grab the current list of mcgs
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcglist = chan->ch_vhub_data;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan->ch_vhub_data = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * When rejoin data mcgs is called, we may not even be marked as
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * joined in SM's records. But we still have to leave the old
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * one first to prevent leaks in ibtf.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (mcg = mcglist; mcg != NULL; mcg = next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan next = mcg->mg_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ibt_detach_mcg(chan->ch_chan, mcg->mg_mcginfo);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_join_data_mcg(ss, vnic, mcg->mg_mac, B_TRUE,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan &err) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *m;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan m = mcg->mg_mac;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_rejoin_data_mcgs: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_join_data_mcg(mcmac=%x:%x:%x:%x:%x:%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", m[0], m[1], m[2], m[3],
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan m[4], m[5], err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg->mg_mcginfo) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg->mg_mcginfo, sizeof (ibt_mcg_info_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_vnic_reattach_ctl_mcgs(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * For reattaching to control mcgs, we will not reinitialize the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * vhub table/vhub update we've constructed. We'll simply detach
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * from the table and update mcgs and reattach to them. Hopefully,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * we wouldn't have missed any updates and won't have to restart
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the vnic.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_attach_vhub_table(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_attach_vhub_update(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_attach_vhub_update(ss, vnic) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_reattach_ctl_mcgs: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_update(vn_id=0x%x) failed",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eib_vnic_attach_vhub_table(ss, vnic) != EIB_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_reattach_ctl_mcgs: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_vnic_attach_vhub_table(vn_id=0x%x) failed",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic->vn_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_attach_vhub_update(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_rb_vnic_create_common(eib_t *ss, eib_vnic_t *vnic, uint_t progress)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int err;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic[vnic->vn_instance] = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_vnic_pending = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_vnic_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_BROADCAST_JOINED) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_leave_all_data_mcgs(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_KEEPALIVES_STARTED) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_start_keepalives(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_ATTACHED_TO_CTL_MCGS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_attach_ctl_mcgs(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_LOGIN_DONE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eib_fip_logout(ss, vnic, &err);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_DATAQP_CREATED) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_data_create_qp(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (progress & EIB_VNIC_CTLQP_CREATED) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_ctl_create_qp(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_rb_vnic_attach_ctl_mcgs(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Detach from the vhub table and vhub update mcgs before blowing
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * up vn_vhub_table and vn_vhub_update, since these are assumed to
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * be available by the control cq handler.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_attach_vhub_table(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_rb_vnic_attach_vhub_update(ss, vnic);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_vnic_fini_tables(ss, vnic, B_TRUE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_rb_vnic_attach_vhub_table(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_ctl_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_channel_hdl_t chan_hdl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (chan == NULL)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan_hdl = chan->ch_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg = chan->ch_vhub_table;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan->ch_vhub_table = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (chan_hdl && mcg) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_detach_mcg(chan_hdl, mcg->mg_mcginfo);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_rb_vnic_attach_vhub_table: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_detach_mcg(chan_hdl=0x%llx, mcinfo=0x%llx, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "mgid=%llx.%llx) failed, ret=%d", chan_hdl,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mcginfo, mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_rb_vnic_attach_vhub_table: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, mcg->mg_join_state, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg->mg_mcginfo) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_mcg_info(mcg->mg_mcginfo, 1);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_rb_vnic_attach_vhub_update(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_ctl_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_channel_hdl_t chan_hdl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (chan == NULL)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan_hdl = chan->ch_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg = chan->ch_vhub_update;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan->ch_vhub_update = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (chan_hdl && mcg) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_detach_mcg(chan_hdl, mcg->mg_mcginfo);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_rb_vnic_attach_vhub_update: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_detach_mcg(chan_hdl=0x%llx, mcinfo=0x%llx, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "mgid=%llx.%llx) failed, ret=%d", chan_hdl,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mcginfo, mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_reserved_gid, mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_rb_vnic_attach_vhub_update: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, mcg->mg_join_state, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg->mg_mcginfo) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_mcg_info(mcg->mg_mcginfo, 1);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_rb_vnic_start_keepalives(eib_t *ss, eib_vnic_t *vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_ka_vnics_t *prev;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_ka_vnics_t *elem;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We only need to locate and remove the vnic entry from the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * keepalives manager list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->ei_ka_vnics_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan prev = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (elem = ss->ei_ka_vnics; elem; elem = elem->ka_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem->ka_vnic == vnic)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan prev = elem;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (elem == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_DEBUG(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_rb_vnic_start_keepalives: no keepalive element found "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "for vnic 0x%llx (vn_inst=%d) with keepalive manager",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic, vnic->vn_instance);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (prev) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan prev->ka_next = elem->ka_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->ei_ka_vnics = elem->ka_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(elem, sizeof (eib_ka_vnics_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->ei_ka_vnics_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_rb_vnic_join_data_mcg(eib_t *ss, eib_vnic_t *vnic, uint8_t *mcast_mac)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_chan_t *chan = vnic->vn_data_chan;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *prev;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_mcg_t *mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Search our list and remove the item if found
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan prev = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (mcg = chan->ch_vhub_data; mcg != NULL; mcg = mcg->mg_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (bcmp(mcg->mg_mac, mcast_mac, ETHERADDRL) == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan prev = mcg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (prev != NULL)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan prev->mg_next = mcg->mg_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan else
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan->ch_vhub_data = mcg->mg_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&chan->ch_vhub_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Detach data channel qp from the mcg, leave the group and free
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * all associated stuff
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_detach_mcg(chan->ch_chan, mcg->mg_mcginfo);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_rb_vnic_join_data_mcg: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_detach_mcg(chan_hdl=0x%llx, mcinfo=0x%llx, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "mgid=%llx.%llx) failed, ret=%d", chan->ch_chan,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mcginfo, mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_leave_mcg(mcg->mg_rgid, mcg->mg_mgid, eib_reserved_gid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_join_state);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_WARN(ss->ei_instance,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "eib_rb_vnic_join_data_mcg: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", mcg->mg_mgid.gid_prefix,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mcg->mg_mgid.gid_guid, mcg->mg_join_state, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (mcg->mg_mcginfo)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg->mg_mcginfo, sizeof (ibt_mcg_info_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(mcg, sizeof (eib_mcg_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}