/*
* 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 void eib_ibt_reset_partitions(eib_t *);
boolean_t *);
static void eib_ibt_record_srate(eib_t *);
/*
* Definitions private to this file
*/
/*
* SM's init type reply flags
*/
(((itr) & SM_INIT_TYPE_REPLY_NO_LOAD_REPLY) == 0)
(((itr) & SM_INIT_TYPE_PRESERVE_CONTENT_REPLY) == 0)
(((itr) & SM_INIT_TYPE_PRESERVE_PRESENCE_REPLY) == 0)
/*
* eib_ibt_hca_init() initialization progress flags
*/
int
{
if (ss->ei_hca_hdl)
return (EIB_E_SUCCESS);
/*
* Open the HCA
*/
&ss->ei_hca_hdl);
if (ret != IBT_SUCCESS) {
"ibt_open_hca(hca_guid=0x%llx) "
goto ibt_hca_init_fail;
}
/*
* Query and store HCA attributes
*/
if (ret != IBT_SUCCESS) {
"ibt_query_hca(hca_hdl=0x%llx, "
"hca_guid=0x%llx) failed, ret=%d",
goto ibt_hca_init_fail;
}
/*
* At this point, we don't even care about the linkstate, we only want
* to record our invariant base port guid and mtu
*/
if (ret != IBT_SUCCESS) {
"ibt_query_hca_ports(hca_hdl=0x%llx, "
goto ibt_hca_init_fail;
}
if (num_pi != 1) {
"ibt_query_hca_ports(hca_hdl=0x%llx, "
goto ibt_hca_init_fail;
}
/*
* Allocate a protection domain for all our transactions
*/
if (ret != IBT_SUCCESS) {
"ibt_alloc_pd(hca_hdl=0x%llx, "
"hca_guid=0x%llx) failed, ret=%d",
goto ibt_hca_init_fail;
}
/*
* Finally, record the capabilities
*/
return (EIB_E_SUCCESS);
return (EIB_E_FAILURE);
}
void
{
return;
/*
* See if we can get the port attributes or we're as good as down.
*/
return;
}
/*
* If the SM re-initialized the port attributes, but did not preserve
* the old attributes, we need to check more.
*/
/*
* We're just coming back up; if we see that our base lid
* or sgid table has changed, we'll update these and try to
* restart all active vnics. If any of the vnic pkeys have
* changed, we'll reset the affected channels to the new pkey.
*/
sizeof (ib_gid_t)) != 0) {
"eib_ibt_link_mod: port sgid table changed "
"(old %llx.%llx != new %llx.%llx), "
"all vnics are zombies now.",
"eib_ibt_link_mod: port base lid changed "
"(old 0x%x != new 0x%x), "
"all vnics are zombies now.",
} else if (eib_ibt_has_any_pkey_changed(ss)) {
"eib_ibt_link_mod: pkey has changed for vnic(s), "
"resetting all partitions");
}
}
if (pi) {
}
/*
* If the SM hasn't preserved our presence in MCGs, we need to
* rejoin all of them.
*/
if (EIB_PORT_PRES_NOT_PRESERVED(itr)) {
"hca_guid=0x%llx, port=0x%x presence not preserved in SM, "
}
/*
* Before we do the actual work of restarting/rejoining, we need to
* see if the GW is reachable at this point of time. If not, we
* still continue to keep our link "down." Whenever the GW becomes
* just marked.
*/
if (all_zombies) {
}
if (all_need_rejoin) {
}
if (ss->ei_gw_unreachable) {
"gateway (gw_port=0x%x) unreachable for "
"hca_guid=0x%llx, port=0x%x, link state down",
return;
}
/*
* Try to awaken the dead if possible
*/
if (all_zombies) {
"hca_guid=0x%llx, hca_port=0x%x, gw_port=0x%x, "
"attempting to resurrect zombies",
}
/*
* Re-join the mcgs if we need to
*/
if (all_need_rejoin) {
"hca_guid=0x%llx, hca_port=0x%x, gw_port=0x%x, "
"attempting to rejoin mcgs",
}
/*
* If we've restarted the zombies because the gateway went down and
* came back, it is possible our unicast mac address changed from
* what it was earlier. If so, we need to update our unicast address
* with the mac layer before marking the link up.
*/
/*
* Notify the link state up if required
*/
}
int
{
/*
* Make sure the channel pkey and index are set to what we need
*/
}
{
int ret;
/*
* See if we have the address vector
*/
break;
}
/*
* If we don't have it, create a new one and chain it to
* the same bucket
*/
"no memory, could not allocate address vector");
return (NULL);
}
ret = EIB_E_FAILURE;
if (!eib_wa_no_av_discover)
if (ret != EIB_E_SUCCESS) {
}
if (prev)
else
}
/*
* Increment the address vector reference count before returning
*/
return (av);
}
static int
{
"ibt_lid_to_node_info(dlid=0x%x) failed, ret=%d",
return (EIB_E_FAILURE);
}
/*
* Get the reversible path information for this destination
*/
"ibt_get_paths(dgid=%llx.%llx) failed, ret=%d",
return (EIB_E_FAILURE);
}
/*
* Fill in the address vector
*/
sizeof (ibt_adds_vect_t));
return (EIB_E_SUCCESS);
}
void
{
}
void
{
int ndx;
}
}
}
/*ARGSUSED*/
void
{
switch (code) {
case IBT_EVENT_SQD:
"eib_ibt_async_handler: got IBT_EVENT_SQD");
break;
case IBT_EVENT_PORT_UP:
"eib_ibt_async_handler: got IBT_EVENT_PORT_UP");
}
break;
case IBT_ERROR_PORT_DOWN:
"eib_ibt_async_handler: got IBT_ERROR_PORT_DOWN");
}
break;
case IBT_CLNT_REREG_EVENT:
"eib_ibt_async_handler: got IBT_CLNT_REREG_EVENT");
}
break;
case IBT_PORT_CHANGE_EVENT:
"eib_ibt_async_handler: "
"got IBT_PORT_CHANGE_EVENT(PKEY_CHANGE)");
"eib_ibt_async_handler: "
"got IBT_PORT_CHANGE_EVENT(SGID_CHANGE)");
}
break;
case IBT_HCA_ATTACH_EVENT:
/*
* For HCA attach, after a new HCA is plugged in and
* configured using cfgadm, an explicit plumb will need
* to be run, so we don't need to do anything here.
*/
"got IBT_HCA_ATTACH_EVENT");
break;
case IBT_HCA_DETACH_EVENT:
/*
* Before an HCA unplug, cfgadm is expected to trigger
* any rcm scripts to unplumb the EoIB instances on the
* card. If so, we should not be holding any hca resource,
* since we don't do ibt_open_hca() until plumb time. However,
* if an earlier unplumb hadn't cleaned up the hca resources
* properly because the network layer hadn't returned the
* buffers at that time, we could be holding hca resources.
* We'll try to release them here, and protect the code from
*/
"got IBT_HCA_DETACH_EVENT");
"eib_events_handler: nw layer still holding "
"hca resources, could not detach HCA");
} else if (ss->ei_hca_hdl) {
eib_rb_ibt_hca_init(ss, ~0);
}
break;
}
if (ev_code != EIB_EV_NONE) {
"eib_ibt_async_handler: "
"no memory, could not handle event 0x%lx", ev_code);
} else {
}
}
}
/*ARGSUSED*/
void
{
/*
* Checksum
*/
caps->cp_cksum_flags = 0;
if ((!eib_wa_no_cksum_offload) &&
/* HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM; */
}
/*
* Reserved L-Key
*/
}
/*
* LSO
*/
caps->cp_lso_maxlen = 0;
if (!eib_wa_no_lso) {
} else {
}
}
/*
* SGL
*
* Translating virtual address regions into physical regions
* for using the Reserved LKey feature results in a wr sgl that
* is a little longer. Since failing ibt_map_mem_iov() is costly,
* we'll record a high-water mark (65%) when we should stop
* trying to use Reserved LKey
*/
} else {
}
}
/*
* to avoid cq overflow event)
*/
}
void
{
if (progress & EIB_HCAINIT_CAPAB_RECORDED) {
}
}
if (progress & EIB_HCAINIT_PD_ALLOCD) {
if (ret != IBT_SUCCESS) {
"eib_rb_ibt_hca_init: "
"ibt_free_pd(hca_hdl=0x%lx, pd_hdl=0x%lx) "
}
}
}
if (progress & EIB_HCAINIT_HCA_PORTS_QUERIED) {
}
if (progress & EIB_HCAINIT_ATTRS_ALLOCD) {
}
if (progress & EIB_HCAINIT_HCA_OPENED) {
if (ret != IBT_SUCCESS) {
"ibt_close_hca(hca_hdl=0x%lx) failed, "
}
}
}
static void
{
int inst = 0;
/*
* We already have the vhub pkey recorded in our eib_chan_t.
* We only need to make sure our pkey index still matches it.
* If not, modify the channel appropriately and update our
* records.
*/
}
}
}
}
}
static void
{
int inst = 0;
/*
* See if this channel has been waiting for its queue to drain.
*
* Note that since this is especially likely to be called during
* logging in to the gateway, we also need to check the vnic
* currently being created.
*/
goto wakeup_sqd_waiters;
goto wakeup_sqd_waiters;
}
break;
break;
}
}
if (chan) {
}
}
static int
{
new_pkey, &new_pkey_ix);
if (ret != IBT_SUCCESS) {
"ibt_pkey2index(hca_hdl=0x%llx, port_num=0x%x, "
"pkey=0x%x) failed, ret=%d",
return (EIB_E_FAILURE);
}
/*
* If the pkey and the pkey index we have already matches the
* new one, nothing to do.
*/
if (pkey_changed) {
*pkey_changed = B_FALSE;
}
return (EIB_E_SUCCESS);
}
if (pkey_changed) {
*pkey_changed = B_TRUE;
}
/*
* Otherwise, if we're asked only to test if the pkey index
* supplied matches the one recorded in the channel, return
* success, but don't set the pkey.
*/
if (!set) {
return (EIB_E_SUCCESS);
}
/*
* Otherwise, we need to change channel pkey. Pause the
* channel sendq first.
*/
if (ret != IBT_SUCCESS) {
"ibt_pause_sendq(chan_hdl=0x%llx) failed, ret=%d",
return (EIB_E_FAILURE);
}
/*
* Wait for the channel to enter the IBT_STATE_SQD state
*/
/*
* Modify the qp with the supplied pkey index and unpause the channel
* If either of these operations fail, we'll leave the channel in
* the paused state and fail.
*/
/*
* Modify the qp to set the new pkey index, then unpause the
* channel and put it in RTS state and update the new values
* in our records
*/
if (ret != IBT_SUCCESS) {
"ibt_modify_qp(chan_hdl=0x%llx, IBT_CEP_SET_PKEY_IX) "
"failed for new_pkey_ix=0x%x, ret=%d",
return (EIB_E_FAILURE);
}
"ibt_unpause_sendq(chan_hdl=0x%llx) failed, ret=%d",
return (EIB_E_FAILURE);
}
return (EIB_E_SUCCESS);
}
static boolean_t
{
int ret;
/*
* Don't modify the pkey, just ask if the pkey index for the channel's
* pkey has changed for any reason. If we fail, assume that the pkey
* has changed.
*/
if (ret != EIB_E_SUCCESS)
return (changed);
}
static boolean_t
{
int inst = 0;
/*
* Return true if the pkey index of any our pkeys (of the channels
* of all active vnics) has changed.
*/
return (B_TRUE);
return (B_TRUE);
return (B_TRUE);
}
}
return (B_FALSE);
}
/*
* This routine is currently used simply to derive and record the port
* speed from the loopback path information (for debug purposes). For
* EoIB, currently the srate used in address vectors to IB neighbors
* and the gateway is fixed at IBT_SRATE_10. Eventually though, this
* information (and sl) has to come from the gateway for all destinations
* in the vhub table.
*/
static void
{
case IBT_SRATE_2:
case IBT_SRATE_10:
case IBT_SRATE_30:
case IBT_SRATE_5:
case IBT_SRATE_20:
case IBT_SRATE_40:
case IBT_SRATE_60:
case IBT_SRATE_80:
case IBT_SRATE_120:
break;
default:
}
}
"srate = %d", srate);
}