emlxs_ip.c revision 291a2b48b9adcd7b3666c34e80ba6411929afe7f
181e56d8b348d301d615ccf5465ae600fee2867berikabele/*
181e56d8b348d301d615ccf5465ae600fee2867berikabele * CDDL HEADER START
181e56d8b348d301d615ccf5465ae600fee2867berikabele *
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive * The contents of this file are subject to the terms of the
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive * Common Development and Distribution License (the "License").
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive * You may not use this file except in compliance with the License.
5a58787efeb02a1c3f06569d019ad81fd2efa06end *
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim * or http://www.opensolaris.org/os/licensing.
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim * See the License for the specific language governing permissions
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * and limitations under the License.
2e545ce2450a9953665f701bb05350f0d3f26275nd *
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * When distributing Covered Code, include this CDDL HEADER in each
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim * If applicable, add the following below this CDDL HEADER, with the
5a58787efeb02a1c3f06569d019ad81fd2efa06end * fields enclosed by brackets "[]" replaced with your own identifying
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * information: Portions Copyright [yyyy] [name of copyright owner]
3f08db06526d6901aa08c110b5bc7dde6bc39905nd *
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim * CDDL HEADER END
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim */
5a58787efeb02a1c3f06569d019ad81fd2efa06end
3f08db06526d6901aa08c110b5bc7dde6bc39905nd/*
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd * Copyright 2009 Emulex. All rights reserved.
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim * Use is subject to License terms.
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim */
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim
1c8f2418892d98febb00a06b9a4f45f8bcfd80a3nd#include <emlxs.h>
7f5b59ccc63c0c0e3e678a168f09ee6a2f51f9d0nd
fac8c35bfb158112226ab43ddf84d59daca5dc30nd/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
d474d8ef01ec5c2a09341cd148851ed383c3287crbowenEMLXS_MSG_DEF(EMLXS_IP_C);
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd
3b3b7fc78d1f5bfc2769903375050048ff41ff26ndextern int32_t
cfcf06e7ae42af93c34c0d62d0944f547092e9ffsliveemlxs_ip_handle_event(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
52178ae4ccdd6ef40b8740e1efaa9e6fc5af7a2aerikabele{
5a58787efeb02a1c3f06569d019ad81fd2efa06end emlxs_port_t *port = &PPORT;
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim IOCB *cmd;
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim emlxs_buf_t *sbp;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick NODELIST *ndlp;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh cmd = &iocbq->iocb;
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim
5a58787efeb02a1c3f06569d019ad81fd2efa06end HBASTATS.IpEvent++;
5a58787efeb02a1c3f06569d019ad81fd2efa06end
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen sbp = (emlxs_buf_t *)iocbq->sbp;
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen if (!sbp) {
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen HBASTATS.IpStray++;
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg,
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen "cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen (uint32_t)cmd->ulpCommand, (uint32_t)cmd->ulpIoTag,
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen cmd->ulpStatus, cmd->un.ulpWord[4]);
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen return (EIO);
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen }
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen if (rp->ringno != FC_IP_RING) {
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen HBASTATS.IpStray++;
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen return (0);
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen }
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen port = sbp->iocbq.port;
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen switch (cmd->ulpCommand) {
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen /*
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen * Error: Abnormal BCAST command completion (Local error)
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen */
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim case CMD_XMIT_BCAST_CN:
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen case CMD_XMIT_BCAST64_CN:
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen HBASTATS.IpBcastCompleted++;
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen HBASTATS.IpBcastError++;
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf "XMIT BCAST completion error cmd=0x%x status=0x%x "
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim "[%08x,%08x]", cmd->ulpCommand, cmd->ulpStatus,
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen emlxs_pkt_complete(sbp, cmd->ulpStatus,
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen cmd->un.grsp.perr.statLocalError, 1);
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen break;
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen /*
57d0156f7bbd9ea3a72342cf9912aba61d118702rbowen * Error: Abnormal XMIT SEQUENCE command completion
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim * (Local error)
5a58787efeb02a1c3f06569d019ad81fd2efa06end */
5a58787efeb02a1c3f06569d019ad81fd2efa06end case CMD_XMIT_SEQUENCE_CR:
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive case CMD_XMIT_SEQUENCE64_CR:
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive HBASTATS.IpSeqCompleted++;
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive HBASTATS.IpSeqError++;
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive
df855969ca92fac8fecc1e19085904611e3ee06dtrawick EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
df855969ca92fac8fecc1e19085904611e3ee06dtrawick "XMIT SEQUENCE CR completion error: cmd=%x status=0x%x "
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf "[%08x,%08x]", cmd->ulpCommand, cmd->ulpStatus,
df855969ca92fac8fecc1e19085904611e3ee06dtrawick cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
cfcf06e7ae42af93c34c0d62d0944f547092e9ffslive emlxs_pkt_complete(sbp, cmd->ulpStatus,
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen cmd->un.grsp.perr.statLocalError, 1);
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen break;
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen /*
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen * Normal BCAST completion
54609d2f9bb9bd1628c8ffb25907336a9738449arbowen */
54609d2f9bb9bd1628c8ffb25907336a9738449arbowen case CMD_XMIT_BCAST_CX:
54609d2f9bb9bd1628c8ffb25907336a9738449arbowen case CMD_XMIT_BCAST64_CX:
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen HBASTATS.IpBcastCompleted++;
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen HBASTATS.IpBcastGood++;
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen "XMIT BCAST CN completion: cmd=%x status=0x%x [%08x,%08x]",
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen cmd->ulpCommand, cmd->ulpStatus, cmd->un.ulpWord[4],
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen cmd->un.ulpWord[5]);
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen emlxs_pkt_complete(sbp, cmd->ulpStatus,
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen cmd->un.grsp.perr.statLocalError, 1);
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen break;
22cb0c2351a6156efcb7288803778690ce22f2dfrbowen
df855969ca92fac8fecc1e19085904611e3ee06dtrawick /*
df855969ca92fac8fecc1e19085904611e3ee06dtrawick * Normal XMIT SEQUENCE completion
df855969ca92fac8fecc1e19085904611e3ee06dtrawick */
df855969ca92fac8fecc1e19085904611e3ee06dtrawick case CMD_XMIT_SEQUENCE_CX:
df855969ca92fac8fecc1e19085904611e3ee06dtrawick case CMD_XMIT_SEQUENCE64_CX:
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick HBASTATS.IpSeqCompleted++;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
df855969ca92fac8fecc1e19085904611e3ee06dtrawick "XMIT SEQUENCE CR completion: cmd=%x status=0x%x"
df855969ca92fac8fecc1e19085904611e3ee06dtrawick "[%08x,%08x]", cmd->ulpCommand, cmd->ulpStatus,
df855969ca92fac8fecc1e19085904611e3ee06dtrawick cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick if (cmd->ulpStatus) {
df855969ca92fac8fecc1e19085904611e3ee06dtrawick HBASTATS.IpSeqError++;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick if ((cmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
df855969ca92fac8fecc1e19085904611e3ee06dtrawick ((cmd->un.ulpWord[4] & 0xff) == IOERR_NO_XRI)) {
df855969ca92fac8fecc1e19085904611e3ee06dtrawick ndlp = (NODELIST *)sbp->node;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick if ((cmd->ulpContext == ndlp->nlp_Xri) &&
df855969ca92fac8fecc1e19085904611e3ee06dtrawick !(ndlp->nlp_flag[FC_IP_RING] &
df855969ca92fac8fecc1e19085904611e3ee06dtrawick NLP_RPI_XRI)) {
df855969ca92fac8fecc1e19085904611e3ee06dtrawick ndlp->nlp_Xri = 0;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick (void) emlxs_create_xri(port, rp, ndlp);
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf }
df855969ca92fac8fecc1e19085904611e3ee06dtrawick }
df855969ca92fac8fecc1e19085904611e3ee06dtrawick } else {
df855969ca92fac8fecc1e19085904611e3ee06dtrawick HBASTATS.IpSeqGood++;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick }
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick emlxs_pkt_complete(sbp, cmd->ulpStatus,
df855969ca92fac8fecc1e19085904611e3ee06dtrawick cmd->un.grsp.perr.statLocalError, 1);
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick break;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick default:
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick HBASTATS.IpStray++;
df855969ca92fac8fecc1e19085904611e3ee06dtrawick
df855969ca92fac8fecc1e19085904611e3ee06dtrawick EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ip_msg,
5a58787efeb02a1c3f06569d019ad81fd2efa06end "Invalid iocb: cmd=0x%x", cmd->ulpCommand);
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim break;
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim } /* switch(cmd->ulpCommand) */
1c8f2418892d98febb00a06b9a4f45f8bcfd80a3nd
7f5b59ccc63c0c0e3e678a168f09ee6a2f51f9d0nd
fac8c35bfb158112226ab43ddf84d59daca5dc30nd return (0);
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen} /* emlxs_ip_handle_event() */
727872d18412fc021f03969b8641810d8896820bhumbedooh
0d0ba3a410038e179b695446bb149cce6264e0abnd
727872d18412fc021f03969b8641810d8896820bhumbedoohextern int32_t
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedoohemlxs_ip_handle_unsol_req(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
0d0ba3a410038e179b695446bb149cce6264e0abnd MATCHMAP *mp, uint32_t size)
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh{
727872d18412fc021f03969b8641810d8896820bhumbedooh emlxs_hba_t *hba = HBA;
0d0ba3a410038e179b695446bb149cce6264e0abnd fc_unsol_buf_t *ubp;
0d0ba3a410038e179b695446bb149cce6264e0abnd IOCB *cmd;
0d0ba3a410038e179b695446bb149cce6264e0abnd NETHDR *nd;
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedooh NODELIST *ndlp;
0d0ba3a410038e179b695446bb149cce6264e0abnd uint8_t *mac;
0d0ba3a410038e179b695446bb149cce6264e0abnd emlxs_ub_priv_t *ub_priv;
0d0ba3a410038e179b695446bb149cce6264e0abnd uint32_t sid;
727872d18412fc021f03969b8641810d8896820bhumbedooh uint32_t i;
0d0ba3a410038e179b695446bb149cce6264e0abnd uint32_t IpDropped = 1;
0d0ba3a410038e179b695446bb149cce6264e0abnd uint32_t IpBcastReceived = 0;
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh uint32_t IpSeqReceived = 0;
07dc96d063d49299da433f84b5c5681da9bbdf68rbowen
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen cmd = &iocbq->iocb;
0d0ba3a410038e179b695446bb149cce6264e0abnd ubp = NULL;
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd for (i = 0; i < MAX_VPORTS; i++) {
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd port = &VPORT(i);
5a58787efeb02a1c3f06569d019ad81fd2efa06end
if (!(port->flag & EMLXS_PORT_BOUND) ||
!(port->flag & EMLXS_PORT_IP_UP)) {
continue;
}
ubp =
(fc_unsol_buf_t *)emlxs_ub_get(port, size,
FC_TYPE_IS8802_SNAP, 0);
if (!ubp) {
/* Theoretically we should never get here. */
/* There should be one DMA buffer for every ub */
/* buffer. If we are out of ub buffers */
/* then some how this matching has been corrupted */
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ip_dropped_msg,
"Buffer not found. paddr=%lx",
getPaddr(cmd->un.cont64[0].addrHigh,
cmd->un.cont64[0].addrLow));
continue;
}
bcopy(mp->virt, ubp->ub_buffer, size);
ub_priv = ubp->ub_fca_private;
nd = (NETHDR *)ubp->ub_buffer;
mac = nd->fc_srcname.IEEE;
ndlp = emlxs_node_find_mac(port, mac);
if (ndlp) {
sid = ndlp->nlp_DID;
if ((ndlp->nlp_Xri == 0) &&
!(ndlp->nlp_flag[FC_IP_RING] & NLP_RPI_XRI)) {
(void) emlxs_create_xri(port, rp, ndlp);
}
}
/*
* If no node is found, then check if this is a
* broadcast frame
*/
else if (cmd->un.xrseq.w5.hcsw.Fctl & BC) {
sid = cmd->un.ulpWord[4] & 0x00ffffff;
}
else {
/* We have to drop this frame because we do not have */
/* the S_ID of the request */
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ip_dropped_msg,
"Node not found. mac=%02x%02x%02x%02x%02x%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
(void) emlxs_ub_release((opaque_t)port, 1,
&ubp->ub_token);
continue;
}
if (cmd->un.xrseq.w5.hcsw.Fctl & BC) {
IpBcastReceived++;
} else {
IpSeqReceived++;
}
/*
* Setup frame header
*/
ubp->ub_frame.r_ctl = cmd->un.xrseq.w5.hcsw.Rctl;
ubp->ub_frame.type = cmd->un.xrseq.w5.hcsw.Type;
ubp->ub_frame.s_id = sid;
ubp->ub_frame.ox_id = ub_priv->token;
ubp->ub_frame.rx_id = cmd->ulpContext;
ubp->ub_class = FC_TRAN_CLASS3;
emlxs_ub_callback(port, ubp);
IpDropped = 0;
}
port = &PPORT;
out:
if (IpDropped) {
HBASTATS.IpDropped++;
}
if (IpBcastReceived) {
HBASTATS.IpBcastReceived++;
}
if (IpSeqReceived) {
HBASTATS.IpSeqReceived++;
}
return (0);
} /* emlxs_ip_handle_unsol_req() */
extern int32_t
emlxs_ip_handle_rcv_seq_list(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
{
emlxs_port_t *port = &PPORT;
IOCB *cmd;
uint64_t bdeAddr;
MATCHMAP *mp = NULL;
#ifdef SLI3_SUPPORT
HBQE_t *hbqE;
uint32_t hbq_id;
uint32_t hbqe_tag;
#endif /* SLI3_SUPPORT */
/*
* No action required for now.
*/
cmd = &iocbq->iocb;
HBASTATS.IpRcvEvent++;
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
"Receive sequence list: cmd=0x%x iotag=0x%x status=0x%x "
"w4=0x%x ringno=0x%x", cmd->ulpCommand, cmd->ulpIoTag,
cmd->ulpStatus, cmd->un.ulpWord[4], rp->ringno);
if (cmd->ulpStatus) {
goto out;
}
#ifdef SLI3_SUPPORT
hbqE = (HBQE_t *)&iocbq->iocb;
hbq_id = hbqE->unt.ext.HBQ_tag;
hbqe_tag = hbqE->unt.ext.HBQE_tag;
if (hba->flag & FC_HBQ_ENABLED) {
HBQ_INIT_t *hbq;
hbq = &hba->hbq_table[hbq_id];
HBASTATS.IpUbPosted--;
if (hbqe_tag >= hbq->HBQ_numEntries) {
mp = NULL;
} else {
mp = hba->hbq_table[hbq_id].HBQ_PostBufs[hbqe_tag];
}
} else
#endif /* SLI3_SUPPORT */
{
/* Check for valid buffer */
if (!(cmd->un.cont64[0].tus.f.bdeFlags & BUFF_TYPE_INVALID)) {
bdeAddr =
getPaddr(cmd->un.cont64[0].addrHigh,
cmd->un.cont64[0].addrLow);
mp = emlxs_mem_get_vaddr(hba, rp, bdeAddr);
}
}
out:
#ifdef SLI3_SUPPORT
if (hba->flag & FC_HBQ_ENABLED) {
emlxs_update_HBQ_index(hba, hbq_id);
} else
#endif /* SLI3_SUPPORT */
{
if (mp) {
(void) emlxs_mem_put(hba, MEM_IPBUF, (uint8_t *)mp);
}
(void) emlxs_post_buffer(hba, rp, 1);
}
HBASTATS.IpDropped++;
return (0);
} /* emlxs_ip_handle_rcv_seq_list() */
/*
* Process a create_xri command completion.
*/
extern int32_t
emlxs_handle_create_xri(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
{
emlxs_port_t *port = &PPORT;
IOCB *cmd;
NODELIST *ndlp;
fc_packet_t *pkt;
emlxs_buf_t *sbp;
cmd = &iocbq->iocb;
sbp = (emlxs_buf_t *)iocbq->sbp;
if (!sbp) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg,
"create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x",
cmd->ulpCommand, cmd->ulpIoTag, cmd->ulpStatus,
cmd->un.ulpWord[4]);
return (EIO);
}
/* check for first xmit completion in sequence */
ndlp = (NODELIST *)sbp->node;
if (cmd->ulpStatus) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_bad_ip_completion_msg,
"create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x",
cmd->ulpCommand, cmd->ulpIoTag, cmd->ulpStatus,
cmd->un.ulpWord[4]);
mutex_enter(&EMLXS_RINGTX_LOCK);
ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI;
mutex_exit(&EMLXS_RINGTX_LOCK);
return (EIO);
}
mutex_enter(&EMLXS_RINGTX_LOCK);
ndlp->nlp_Xri = cmd->ulpContext;
ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI;
mutex_exit(&EMLXS_RINGTX_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
"create_xri completed: DID=0x%x Xri=0x%x iotag=0x%x",
ndlp->nlp_DID, ndlp->nlp_Xri, cmd->ulpIoTag);
pkt = sbp->pkt;
emlxs_pkt_free(pkt);
return (0);
} /* emlxs_handle_create_xri() */
/*
* Issue an iocb command to create an exchange with the remote Nport
* specified by the NODELIST entry.
*/
extern int32_t
emlxs_create_xri(emlxs_port_t *port, RING *rp, NODELIST *ndlp)
{
emlxs_hba_t *hba = HBA;
IOCB *icmd;
IOCBQ *iocbq;
fc_packet_t *pkt;
emlxs_buf_t *sbp;
uint16_t iotag;
/* Check if an XRI has already been requested */
mutex_enter(&EMLXS_RINGTX_LOCK);
if (ndlp->nlp_Xri != 0 || (ndlp->nlp_flag[rp->ringno] & NLP_RPI_XRI)) {
mutex_exit(&EMLXS_RINGTX_LOCK);
return (0);
}
ndlp->nlp_flag[rp->ringno] |= NLP_RPI_XRI;
mutex_exit(&EMLXS_RINGTX_LOCK);
if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
"create_xri failed: Unable to allocate pkt. did=0x%x",
ndlp->nlp_DID);
goto fail;
}
sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
iocbq = &sbp->iocbq;
/* Get the iotag by registering the packet */
iotag = emlxs_register_pkt(rp, sbp);
if (!iotag) {
/*
* No more command slots available, retry later
*/
emlxs_pkt_free(pkt);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
"create_xri failed: Unable to allocate IOTAG. did=0x%x",
ndlp->nlp_DID);
goto fail;
}
icmd = &iocbq->iocb;
icmd->ulpIoTag = iotag;
icmd->ulpContext = ndlp->nlp_Rpi;
icmd->ulpLe = 1;
icmd->ulpCommand = CMD_CREATE_XRI_CR;
icmd->ulpOwner = OWN_CHIP;
/* Initalize iocbq */
iocbq->port = (void *)port;
iocbq->node = (void *)ndlp;
iocbq->ring = (void *)rp;
mutex_enter(&sbp->mtx);
sbp->node = (void *)ndlp;
sbp->ring = rp;
mutex_exit(&sbp->mtx);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
"create_xri sent: DID=0x%x Xri=0x%x iotag=0x%x", ndlp->nlp_DID,
ndlp->nlp_Xri, iotag);
emlxs_sli_issue_iocb_cmd(hba, rp, iocbq);
return (0);
fail:
/* Clear the XRI flag */
mutex_enter(&EMLXS_RINGTX_LOCK);
ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI;
mutex_exit(&EMLXS_RINGTX_LOCK);
return (1);
} /* emlxs_create_xri() */