eib_vnic.c revision b494511a9cf72b1fc4eb13a0e593f55c624ab829
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* Declarations private to this file
*/
static int eib_vnic_get_instance(eib_t *, int *);
static void eib_vnic_ret_instance(eib_t *, int);
eib_vhub_map_t *, ibt_mcg_info_t *, int *);
/*
* Definitions private to this file
*/
#define EIB_VNIC_STRUCT_ALLOCD 0x0001
#define EIB_VNIC_GOT_INSTANCE 0x0002
#define EIB_VNIC_CREATE_COMMON_DONE 0x0004
#define EIB_VNIC_CTLQP_CREATED 0x0008
#define EIB_VNIC_DATAQP_CREATED 0x0010
#define EIB_VNIC_LOGIN_DONE 0x0020
#define EIB_VNIC_PARTITION_SET 0x0040
#define EIB_VNIC_RX_POSTED_TO_CTLQP 0x0080
#define EIB_VNIC_RX_POSTED_TO_DATAQP 0x0100
#define EIB_VNIC_ATTACHED_TO_CTL_MCGS 0x0200
#define EIB_VNIC_GOT_VHUB_TABLE 0x0400
#define EIB_VNIC_KEEPALIVES_STARTED 0x0800
#define EIB_VNIC_BROADCAST_JOINED 0x1000
/*
* Destination type
*/
#define EIB_TX_UNICAST 1
#define EIB_TX_MULTICAST 2
#define EIB_TX_BROADCAST 3
int
int *err)
{
/*
* When a previously created vnic is being resurrected due to a
* gateway reboot, there's a race possible where a creation request
* for the existing vnic could get filed with the vnic creator
* thread. So, before we go ahead with the creation of this vnic,
* make sure we already don't have the vnic.
*/
if (macaddr) {
&failed_vnic) == EIB_E_SUCCESS) {
"vnic for mac=%x:%x:%x:%x:%x:%x, vlan=0x%x "
"already there, no duplicate creation", macaddr[0],
return (EIB_E_SUCCESS);
} else if (failed_vnic) {
"vnic for mac=%x:%x:%x:%x:%x:%x, vlan=0x%x "
"failed earlier, shouldn't be here at all",
return (EIB_E_FAILURE);
}
}
/*
* Allocate a vnic structure for this instance
*/
/*
* Get a vnic instance
*/
goto vnic_create_fail;
}
/*
* Initialize vnic's basic parameters. Note that we set the 15-bit
* vnic id to send to gw during a login to be a 2-tuple of
* {devi_instance#, eoib_vnic_instance#}.
*/
if (macaddr) {
}
/*
* Start up this vnic instance
*/
goto vnic_create_fail;
/*
* Return the created vnic
*/
if (vnicp) {
}
return (EIB_E_SUCCESS);
return (EIB_E_FAILURE);
}
void
{
}
/*ARGSUSED*/
int
{
int ret = EIB_E_SUCCESS;
/*
* with a login failure, record the reason.
*/
deadline) == -1) {
}
}
ret = EIB_E_FAILURE;
}
return (ret);
}
void
{
int nack = 1;
/*
* The msb in the vnic id in login ack message is not
* part of our vNIC id.
*/
/*
* Now, we deconstruct the vnic id and determine the vnic
* instance number. If this vnic_instance number isn't
* valid or the vnic_id of the vnic for this instance
* number doesn't match in our records, we quit.
*/
if (vnic_instance >= EIB_MAX_VNICS)
return;
/*
* At this point, we haven't fully created the vnic, so
* this vnic should be present as ei_vnic_pending.
*/
return;
return;
}
/*
* First check if the vnic is still sleeping, waiting
* for login ack. If not, we might as well quit now.
*/
return;
}
/*
* We NACK the waiter under these conditions:
*
* . syndrome was set
* . assigned vlan is different from requested vlan (except
* when we didn't request a specific vlan)
* . when the assigned mac is different from the requested mac
* (except when we didn't request a specific mac)
* . when the VP bit indicates that vlan tag should be used
* but we had not specified a vlan tag in our request
* . when the VP bit indicates that vlan tag should not be
* present and we'd specified a vlan tag in our request
*
* The last case is interesting: if we had not specified any vlan id
* in our request, but the gateway has assigned a vlan and asks us
* tagging on this vnic traffic, since the nw layer on Solaris
* feature is not supported currently.
*/
if (ld->ld_syndrome) {
"vhub mtu (0x%x) bigger than port mtu (0x%x), NACK",
"assigned vlan (0x%x) different from asked (0x%x), "
"assigned mac (%x:%x:%x:%x:%x:%x) different from "
"asked (%x:%x:%x:%x:%x:%x) for vnic id 0x%x, NACK",
"asked for tagless vlan, but VP flag is set "
if (eib_wa_no_good_vp_flag) {
nack = 0;
} else {
"vlan was assigned correctly, but VP flag is not "
}
} else {
nack = 0;
}
/*
*/
if (nack) {
} else {
}
}
int
{
int ret = EIB_E_SUCCESS;
/*
* The EoIB spec does not detail exactly within what time a vhub table
* request is expected to be answered. However, it does mention that
* in the worst case, the vhub update messages from the gateway must
* be seen atleast once in 2.5 * GW_KA_PERIOD (already saved in
* pp_gw_ka_ticks), so we'll settle for that limit.
*/
/*
* Wait for vhub table to be constructed. If we wake up with a
* vhub table construction failure, record the reason.
*/
deadline) == -1) {
}
}
ret = EIB_E_FAILURE;
}
return (ret);
}
void
{
/*
* Construction of vhub table for the vnic is done one way or
* the other. Set the login wait state appropriately and signal
* the waiter. If it's a vhub table failure, we shouldn't parse
* any more vhub table or vhub update packets until the vnic state
* is changed.
*/
}
int
{
/*
* Compose the multicast MGID to join
*/
/*
* Allocate for and prepare the mcg to add to our list
*/
"no memory, failed to join mcg (mac=%x:%x:%x:%x:%x:%x)",
goto vnic_join_data_mcg_fail;
}
"no memory, failed to join mcg (mac=%x:%x:%x:%x:%x:%x)",
goto vnic_join_data_mcg_fail;
}
/*
* Join the multicast group
*
* Should we query for the mcg and join instead of attempting to
* join directly ?
*/
if (ret != IBT_SUCCESS) {
"ibt_join_mcg(mgid=%llx.%llx, pkey=0x%x, qkey=0x%lx, "
goto vnic_join_data_mcg_fail;
}
/*
* Attach to the group to receive multicast messages
*/
if (ret != IBT_SUCCESS) {
if (ret != EIB_E_SUCCESS) {
"eib_vnic_join_data_mcg: "
"ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
}
goto vnic_join_data_mcg_fail;
}
break;
}
}
/*
* If we had't already joined to this mcg, add the newly joined mcg
* to the tail and return success
*/
if (tail)
else
return (EIB_E_SUCCESS);
}
/*
* Duplicate. We need to leave one of the two joins. If "rejoin"
* was requested, leave the old join, otherwise leave the new join.
*
* Note that we must not detach the qp from the mcg, since if this
* was a dup, a second ibt_attach_mcg() above would've simply been
* a nop.
*
* Note also that the leave may not be successful here if our presence
* has been removed by the SM, but we need to do this to prevent leaks
* in ibtf.
*/
if (rejoin) {
/*
* Copy the new mcg over the old one (including the new
* mg_mcginfo), but preserve the link to the next element
* on the list
*/
} else {
}
return (EIB_E_SUCCESS);
if (mcg) {
}
if (mcg_info) {
}
return (EIB_E_FAILURE);
}
int
{
int dtype;
int rv;
/*
* Lookup the destination in the vhub table or in our mcg list
*/
if (rv != EIB_E_SUCCESS) {
"eib_vnic_lookup_dest(dmac=%x:%x:%x:%x:%x:%x, vlan=0x%x) "
return (EIB_E_FAILURE);
}
/*
* If we found a unicast address, get an address vector for the lid
* and sl, modify the ud dest based on the address vector and return.
* If we found a multicast address, use the address vector in the
* mcg info to modify the ud dest and return.
*/
if (dtype == EIB_TX_UNICAST) {
"eib_vnic_setup_dest: "
"eib_ibt_hold_avect(lid=0x%x, sl=0x%x) failed",
return (EIB_E_FAILURE);
}
if (ret != IBT_SUCCESS) {
"eib_vnic_setup_dest: "
"ibt_modify_ud_dest(qpn=0x%lx, qkey=0x%lx) "
return (EIB_E_FAILURE);
}
} else {
if (dtype == EIB_TX_BROADCAST)
else
if (ret != IBT_SUCCESS) {
"eib_vnic_setup_dest: "
"ibt_modify_ud_dest(mc_qpn=0x%lx, qkey=0x%lx) "
return (EIB_E_FAILURE);
}
}
return (EIB_E_SUCCESS);
}
void
{
}
/*ARGSUSED*/
void
{
}
/*ARGSUSED*/
void
{
int i;
/*
* We come here only when we've either completely detached from
* the vhub multicast groups and so cannot receive anymore table
* or update control messages, or we've had a recent vhub table
* construction failure and the vnic state is currently
* EIB_LOGIN_TBL_FAILED and so won't parse any table or update
* control messages. Also, since we haven't completed the vnic
* creation, no one from the tx path will be accessing the
* vn_vhub_table entries either. All said, we're free to play
* around with the vnic's vn_vhub_table and vn_vhub_update here.
*/
if (clobber) {
}
/*
* Destroy the vhub update entries if any
*/
if (upd) {
/*
* Wipe clean the list of vnic entries accumulated via
* vhub updates so far. Release eib_vhub_update_t only
* if explicitly asked to do so
*/
}
upd->up_eport_state = 0;
if (clobber) {
}
}
/*
* Destroy the vhub table entries
*/
return;
/*
* Wipe clean the list of entries in the vhub table collected so
* far. Release eib_vhub_table_t only if explicitly asked to do so.
*/
if (tbl->tb_gateway) {
}
if (tbl->tb_unicast_miss) {
}
if (tbl->tb_vhub_multicast) {
}
if (!eib_wa_no_mcast_entries) {
for (i = 0; i < EIB_TB_NBUCKETS; i++) {
}
}
}
for (i = 0; i < EIB_TB_NBUCKETS; i++) {
}
}
tbl->tb_eport_state = 0;
tbl->tb_entries_seen = 0;
tbl->tb_entries_in_table = 0;
tbl->tb_checksum = 0;
/*
* Don't throw away space created for holding vhub table if we haven't
* been explicitly asked to do so
*/
if (clobber) {
}
}
{
}
return (chan);
}
void
{
/*
* Create a new vnic request for this {mac,vlan} tuple
*/
"no memory, failed to queue new vnic creation request");
return;
}
}
void
{
uint8_t *m;
/*
* Enqueue this new vnic request with the vnic creator and
* signal it.
*/
"BEGIN file request for creation of %x:%x:%x:%x:%x:%x, 0x%x",
/*
* Death request has the highest priority. If we've already been asked
* to die, we don't entertain any more requests.
*/
if (ss->ei_vnic_req) {
return;
}
}
} else {
/*
* If there's already a creation request for this vnic that's
* being processed, return immediately without adding a new
* request.
*/
"eib_vnic_enqueue_req: "
"ei_pending_vnic_req not NULL");
ETHERADDRL) == 0)) {
"eib_vnic_enqueue_req: "
"pending request already present for "
"%x:%x:%x:%x:%x:%x, 0x%x", m[0], m[1], m[2],
"eib_vnic_enqueue_req: "
"END file request");
return;
}
"eib_vnic_enqueue_req: "
"NO pending request for %x:%x:%x:%x:%x:%x, 0x%x",
}
/*
* Or if there's one waiting in the queue for processing, do
* the same thing
*/
/*
* If there's already a create request for this vnic
* waiting in the queue, return immediately
*/
ETHERADDRL) == 0)) {
"eib_vnic_enqueue_req: "
"request already present for "
"%x:%x:%x:%x:%x:%x, 0x%x", m[0],
m[1], m[2], m[3], m[4], m[5],
"eib_vnic_enqueue_req: "
"END file request");
return;
}
}
"eib_vnic_enqueue_req: "
"request not found, filing afresh");
break;
}
}
/*
* Otherwise queue up this new creation request and signal the
* service thread.
*/
if (elem) {
} else {
}
}
"eib_vnic_enqueue_req: END file request");
}
void
{
"eib_vnic_update_failed_macs: "
"no memory, failed to drop old mac");
} else {
}
/*
* We'll search the failed vnics list to see if the new {mac,vlan}
* tuple is in there and remove it if present (since the new address
* is no longer "failed").
*/
if (prev) {
} else {
}
break;
}
}
if (elem) {
}
/*
* We'll also insert the old {mac,vlan} tuple to the "failed vnic req"
* list (it shouldn't be there already), to avoid trying to recreate
* the vnic we just explicitly discarded.
*/
if (vrq) {
}
}
void
{
int inst;
/*
* but with the same vnic id and instance as before.
*/
"eib_vnic_resurrect_zombies: "
"calling eib_vnic_restart(vn_inst=%d)", inst);
"eib_vnic_resurrect_zombies: "
"eib_vnic_restart(vn_inst=%d) done", inst);
}
}
void
{
int ret;
int err;
"eib_vnic_restart: "
"vnic instance (%d) invalid", inst);
return;
}
/*
* Remember what mac was allocated for this vnic last time
*/
/*
* Tear down and restart this vnic instance
*/
if (ret != EIB_E_SUCCESS) {
"eib_vnic_restart: "
"eib_vnic_create_common(vnic_inst=%d) failed, "
}
/*
* If this is vnic instance 0 and if our current assigned mac is
* different from what was assigned last time, we need to pass
* this information back to the caller, so the mac layer can be
* appropriately informed. We will also queue up the old mac
* and vlan in the "failed vnic req" list, so any future packets
* to this address on this interface will be dropped.
*/
if ((inst == 0) &&
}
"eib_vnic_restart: updating failed macs list "
"old=%x:%x:%x:%x:%x:%x, new=%x:%x:%x:%x:%x:%x, "
}
/*
* No longer a zombie or need to rejoin mcgs
*/
}
}
void
{
int inst;
/*
* For each vnic that still requires re-join, go through the
*/
}
}
}
void
{
if (progress & EIB_VNIC_CREATE_COMMON_DONE) {
}
if (progress & EIB_VNIC_GOT_INSTANCE) {
}
if (progress & EIB_VNIC_STRUCT_ALLOCD) {
}
}
/*
* Currently, we only allow 64 vnics per eoib device instance, for
* reasons described in eib.h (see EIB_VNIC_ID() definition), so we
* could use a simple bitmap to assign the vnic instance numbers.
* Once we start allowing more vnics per device instance, this
* allocation scheme will need to be changed.
*/
static int
{
int bitpos;
/*
* What we have is the active vnics list -- the in-use vnics are
* indicated by a 1 in the bit position, and the free ones are
* indicated by 0. We need to find the least significant '0' bit
* to get the first free vnic instance. Or we could bit-reverse
* the active list and locate the least significant '1'.
*/
if (nval == 0)
return (EIB_E_FAILURE);
/*
* The single bit-position values in a 64-bit integer are relatively
* prime with 67, so performing a modulus division with 67 guarantees
* a unique number between 0 and 63 for each value (setbit_mod67[]).
*/
if (bitpos == -1)
return (EIB_E_FAILURE);
return (EIB_E_SUCCESS);
}
static void
{
if (vinst >= EIB_MAX_VNICS) {
"eib_vnic_ret_instance: "
"vnic instance (%d) invalid", vinst);
"eib_vnic_ret_instance: "
"vnic instance (%d) not active!", vinst);
} else {
}
}
static void
{
}
static void
{
}
static int
{
/*
* When we receive login acks within this vnic creation
* routine we need a way to retrieve the vnic structure
* from the vnic instance, so store this somewhere. Note
* that there can be only one outstanding vnic creation
* at any point of time, so we only need one vnic struct.
*/
/*
* Create a control qp for this vnic
*/
"eib_vnic_create_common: "
"eib_ctl_create_qp(vn_id=0x%x) failed, ret=%d",
goto vnic_create_common_fail;
}
/*
* Create a data qp for this vnic
*/
"eib_vnic_create_common: "
"eib_data_create_qp(vn_id=0x%x) failed, ret=%d",
goto vnic_create_common_fail;
}
/*
* Login to the gateway with this vnic's parameters
*/
"eib_vnic_create_common: "
"eib_fip_login(vn_id=0x%x) failed, ret=%d",
goto vnic_create_common_fail;
}
/*
* Associate the control and data qps for the vnic with the
* vHUB partition
*/
"eib_vnic_create_common: "
"eib_vnic_set_partition(vn_id=0x%x) failed, ret=%d",
goto vnic_create_common_fail;
}
/*
* Post initial set of rx buffers on the control qp to the HCA
*/
"eib_vnic_create_common: "
"eib_chan_post_rx(vn_id=0x%x, CTL_QP) failed, ret=%d",
goto vnic_create_common_fail;
}
/*
* Post initial set of rx buffers on the data qp to the HCA
*/
"eib_vnic_create_common: "
"eib_chan_post_rx(vn_id=0x%x, DATA_QP) failed, ret=%d",
goto vnic_create_common_fail;
}
/*
* Attach to the vHUB table and vHUB update multicast groups
*/
"eib_vnic_create_common: "
"eib_vnic_attach_ctl_mcgs(vn_id=0x%x) failed, ret=%d",
goto vnic_create_common_fail;
}
/*
* Send the vHUB table request and construct the vhub table
*/
"eib_vnic_create_common: "
"eib_fip_vhub_table(vn_id=0x%x) failed, ret=%d",
goto vnic_create_common_fail;
}
/*
* Detach from the vHUB table mcg (we no longer need the vHUB
* table messages) and start the keepalives for this vnic.
*/
/*
* All ethernet vnics are automatically members of the broadcast
* group for the vlan they are participating in, so join the
* ethernet broadcast group. Note that when we restart vnics,
* we rejoin the mcgs, so we pass B_TRUE to eib_vnic_join_data_mcg().
*/
err) != EIB_E_SUCCESS) {
"eib_vnic_create_common: "
"eib_vnic_join_data_mcg(vn_id=0x%x, BCAST_GROUP) failed, "
goto vnic_create_common_fail;
}
}
return (EIB_E_SUCCESS);
return (EIB_E_FAILURE);
}
static int
{
int ret;
/*
* Associate the control channel with the vhub partition
*/
if (ret != EIB_E_SUCCESS) {
"eib_vnic_set_partition: "
"eib_ibt_modify_chan_pkey(vn_id=0x%x, CTL_CHAN, "
return (EIB_E_FAILURE);
}
/*
* Now, do the same thing for the data channel. Note that if a
* failure happens, the channel state(s) are left as-is, since
* it is pointless to try to change them back using the same
* interfaces that have just failed.
*/
if (ret != EIB_E_SUCCESS) {
"eib_vnic_set_partition: "
"eib_ibt_modify_chan_pkey(vn_id=0x%x, DATA_CHAN, "
return (EIB_E_FAILURE);
}
return (EIB_E_SUCCESS);
}
static void
{
/*
* Copy mgid prefix and type
*/
/*
* Take n_mac bits from mcast_mac and copy dmac
*/
/*
* Copy rss hash and prepare vhub id from gw port id and vlan
*/
/*
* Ok, now we've assembled the mgid as per EoIB spec. We now have to
* represent it in the way Solaris IBTF wants it and return (sigh).
*/
}
static int
{
/*
* Get tb_vhub_table and tb_vhub_update allocated and ready before
* attaching to the vhub table and vhub update mcgs
*/
"eib_vnic_attach_ctl_mcgs: "
"eib_vnic_attach_vhub_update(vn_id=0x%x) failed",
return (EIB_E_FAILURE);
}
"eib_vnic_attach_ctl_mcgs: "
"eib_vnic_attach_vhub_table(vn_id=0x%x) failed",
return (EIB_E_FAILURE);
}
return (EIB_E_SUCCESS);
}
static int
{
/*
* Compose the MGID for receiving VHUB table
*/
/*
* Locate the multicast group for receiving vhub table
*/
&tbl_mcginfo, &entries);
if (ret != IBT_SUCCESS) {
"eib_vnic_attach_vhub_table: "
"ibt_query_mcg(mgid=%llx.%llx, pkey=0x%x) failed, "
return (EIB_E_FAILURE);
}
/*
* Allocate for and prepare the mcg to add to our list
*/
"eib_vnic_attach_vhub_table: "
"no memory, failed to attach to vhub table "
return (EIB_E_FAILURE);
}
/*
* Join the multicast group
*/
if (ret != IBT_SUCCESS) {
"eib_vnic_attach_vhub_table: "
"ibt_join_mcg(mgid=%llx.%llx, pkey=0x%x, jstate=0x%x) "
return (EIB_E_FAILURE);
}
/*
* Attach to the multicast group to receive tbl multicasts
*/
if (ret != IBT_SUCCESS) {
"eib_vnic_attach_vhub_table: "
"ibt_attach_mcg(mgid=%llx.%llx, pkey=0x%x) "
return (EIB_E_FAILURE);
}
return (EIB_E_SUCCESS);
}
static int
{
/*
* Compose the MGID for receiving VHUB updates
*/
/*
* Locate the multicast group for receiving vhub updates
*/
&upd_mcginfo, &entries);
if (ret != IBT_SUCCESS) {
"eib_vnic_attach_vhub_update: "
"ibt_query_mcg(mgid=%llx.%llx, pkey=0x%x) failed, "
return (EIB_E_FAILURE);
}
/*
* Allocate for and prepare the mcg to add to our list
*/
"eib_vnic_attach_vhub_update: "
"no memory, failed to attach to vhub update "
return (EIB_E_FAILURE);
}
/*
* Join the multicast group
*/
if (ret != IBT_SUCCESS) {
"eib_vnic_attach_vhub_update: "
"ibt_join_mcg(mgid=%llx.%llx, pkey=0x%x, jstate=0x%x) "
return (EIB_E_FAILURE);
}
/*
* Attach to the multicast group to receive upd multicasts
*/
if (ret != IBT_SUCCESS) {
"eib_vnic_attach_vhub_update: "
"ibt_attach_mcg(mgid=%llx.%llx, pkey=0x%x) "
return (EIB_E_FAILURE);
}
return (EIB_E_SUCCESS);
}
static void
{
int err;
/*
* Send the first keepalive and then queue this vnic up with
* the keepalives manager
*/
break;
}
if (elem) {
} else {
}
}
/*ARGSUSED*/
static int
{
/*
* If this was a unicast dmac, locate the vhub entry matching the
* unicast dmac in our vhub table. If it's not found, return the
* gateway entry
*/
if (EIB_UNICAST_MAC(dmac)) {
return (EIB_E_FAILURE);
}
break;
}
return (EIB_E_FAILURE);
}
*dtype = EIB_TX_UNICAST;
if (elem) {
} else {
}
return (EIB_E_SUCCESS);
}
/*
* Is it a broadcast ?
*/
/*
* If this was a multicast dmac, prepare the mgid and look for it
* in the list of mcgs we've joined and use the address vector from
* the mcginfo stored there.
*
* Note that since we don't have a way to associate each vlan with
* the mcg (see eib_m_multicast()), we'll prepare the mgid to use
* the broadcast channel all the time.
*/
break;
}
}
"could not find mgid %llx.%llx",
return (EIB_E_FAILURE);
}
return (EIB_E_SUCCESS);
}
/*ARGSUSED*/
static void
{
/*
* First, take the ch_vhub_data mcg chain out of chan
*/
/*
* Go through the chain of mcgs we've joined, detach the qp from the
* mcg, leave the group and free all associated stuff
*/
if (ret != IBT_SUCCESS) {
"eib_vnic_leave_all_data_mcgs: "
"ibt_detach_mcg(chan_hdl=0x%llx, mcinfo=0x%llx, "
}
if (ret != IBT_SUCCESS) {
"eib_vnic_leave_all_data_mcgs: "
"ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
}
if (mcg->mg_mcginfo)
}
}
static void
{
int err;
/*
* Grab the current list of mcgs
*/
/*
* When rejoin data mcgs is called, we may not even be marked as
* joined in SM's records. But we still have to leave the old
* one first to prevent leaks in ibtf.
*/
&err) != EIB_E_SUCCESS) {
uint8_t *m;
"eib_vnic_rejoin_data_mcgs: "
"eib_vnic_join_data_mcg(mcmac=%x:%x:%x:%x:%x:%x) "
"failed, ret=%d", m[0], m[1], m[2], m[3],
}
if (mcg->mg_mcginfo) {
}
}
}
static void
{
/*
* For reattaching to control mcgs, we will not reinitialize the
* from the table and update mcgs and reattach to them. Hopefully,
* we wouldn't have missed any updates and won't have to restart
* the vnic.
*/
"eib_vnic_reattach_ctl_mcgs: "
"eib_vnic_attach_vhub_update(vn_id=0x%x) failed",
}
"eib_vnic_reattach_ctl_mcgs: "
"eib_vnic_attach_vhub_table(vn_id=0x%x) failed",
}
}
static void
{
int err;
if (progress & EIB_VNIC_BROADCAST_JOINED) {
}
if (progress & EIB_VNIC_KEEPALIVES_STARTED) {
}
if (progress & EIB_VNIC_ATTACHED_TO_CTL_MCGS) {
}
if (progress & EIB_VNIC_LOGIN_DONE) {
}
if (progress & EIB_VNIC_DATAQP_CREATED) {
}
if (progress & EIB_VNIC_CTLQP_CREATED) {
}
}
static void
{
/*
* Detach from the vhub table and vhub update mcgs before blowing
* up vn_vhub_table and vn_vhub_update, since these are assumed to
* be available by the control cq handler.
*/
}
/*ARGSUSED*/
static void
{
return;
if (ret != IBT_SUCCESS) {
"eib_rb_vnic_attach_vhub_table: "
"ibt_detach_mcg(chan_hdl=0x%llx, mcinfo=0x%llx, "
"mgid=%llx.%llx) failed, ret=%d", chan_hdl,
}
if (ret != IBT_SUCCESS) {
"eib_rb_vnic_attach_vhub_table: "
"ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
}
if (mcg->mg_mcginfo) {
}
}
}
/*ARGSUSED*/
static void
{
return;
if (ret != IBT_SUCCESS) {
"eib_rb_vnic_attach_vhub_update: "
"ibt_detach_mcg(chan_hdl=0x%llx, mcinfo=0x%llx, "
"mgid=%llx.%llx) failed, ret=%d", chan_hdl,
}
if (ret != IBT_SUCCESS) {
"eib_rb_vnic_attach_vhub_update: "
"ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
}
if (mcg->mg_mcginfo) {
}
}
}
/*ARGSUSED*/
static void
{
/*
* We only need to locate and remove the vnic entry from the
* keepalives manager list
*/
break;
}
"eib_rb_vnic_start_keepalives: no keepalive element found "
"for vnic 0x%llx (vn_inst=%d) with keepalive manager",
} else {
if (prev) {
} else {
}
}
}
/*ARGSUSED*/
static void
{
/*
* Search our list and remove the item if found
*/
break;
}
return;
}
else
/*
* Detach data channel qp from the mcg, leave the group and free
* all associated stuff
*/
if (ret != IBT_SUCCESS) {
"eib_rb_vnic_join_data_mcg: "
"ibt_detach_mcg(chan_hdl=0x%llx, mcinfo=0x%llx, "
}
mcg->mg_join_state);
if (ret != IBT_SUCCESS) {
"eib_rb_vnic_join_data_mcg: "
"ibt_leave_mcg(mgid=%llx.%llx, jstate=0x%x) "
}
if (mcg->mg_mcginfo)
}