1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte 22*fcf3ce44SJohn Forte /* 23*fcf3ce44SJohn Forte * Copyright 2008 Emulex. All rights reserved. 24*fcf3ce44SJohn Forte * Use is subject to License terms. 25*fcf3ce44SJohn Forte */ 26*fcf3ce44SJohn Forte 27*fcf3ce44SJohn Forte 28*fcf3ce44SJohn Forte #include "emlxs.h" 29*fcf3ce44SJohn Forte 30*fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 31*fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_IP_C); 32*fcf3ce44SJohn Forte 33*fcf3ce44SJohn Forte 34*fcf3ce44SJohn Forte extern int32_t 35*fcf3ce44SJohn Forte emlxs_ip_handle_event(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq) 36*fcf3ce44SJohn Forte { 37*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 38*fcf3ce44SJohn Forte IOCB *cmd; 39*fcf3ce44SJohn Forte emlxs_buf_t *sbp; 40*fcf3ce44SJohn Forte NODELIST *ndlp; 41*fcf3ce44SJohn Forte 42*fcf3ce44SJohn Forte cmd = &iocbq->iocb; 43*fcf3ce44SJohn Forte 44*fcf3ce44SJohn Forte HBASTATS.IpEvent++; 45*fcf3ce44SJohn Forte 46*fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 47*fcf3ce44SJohn Forte 48*fcf3ce44SJohn Forte if (!sbp) { 49*fcf3ce44SJohn Forte HBASTATS.IpStray++; 50*fcf3ce44SJohn Forte 51*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg, 52*fcf3ce44SJohn Forte "cmd=0x%x iotag=0x%x status=0x%x perr=0x%x", 53*fcf3ce44SJohn Forte (uint32_t)cmd->ulpCommand, (uint32_t)cmd->ulpIoTag, 54*fcf3ce44SJohn Forte cmd->ulpStatus, cmd->un.ulpWord[4]); 55*fcf3ce44SJohn Forte 56*fcf3ce44SJohn Forte return (EIO); 57*fcf3ce44SJohn Forte } 58*fcf3ce44SJohn Forte if (rp->ringno != FC_IP_RING) { 59*fcf3ce44SJohn Forte HBASTATS.IpStray++; 60*fcf3ce44SJohn Forte 61*fcf3ce44SJohn Forte return (0); 62*fcf3ce44SJohn Forte } 63*fcf3ce44SJohn Forte port = sbp->iocbq.port; 64*fcf3ce44SJohn Forte 65*fcf3ce44SJohn Forte switch (cmd->ulpCommand) { 66*fcf3ce44SJohn Forte /* 67*fcf3ce44SJohn Forte * Error: Abnormal BCAST (Local error) 68*fcf3ce44SJohn Forte */ 69*fcf3ce44SJohn Forte case CMD_XMIT_BCAST_CN: 70*fcf3ce44SJohn Forte case CMD_XMIT_BCAST64_CN: 71*fcf3ce44SJohn Forte 72*fcf3ce44SJohn Forte HBASTATS.IpBcastCompleted++; 73*fcf3ce44SJohn Forte HBASTATS.IpBcastError++; 74*fcf3ce44SJohn Forte 75*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 76*fcf3ce44SJohn Forte "XMIT BCAST completion error cmd=0x%x status=0x%x " 77*fcf3ce44SJohn Forte "[%08x,%08x]", cmd->ulpCommand, cmd->ulpStatus, 78*fcf3ce44SJohn Forte cmd->un.ulpWord[4], cmd->un.ulpWord[5]); 79*fcf3ce44SJohn Forte 80*fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, cmd->ulpStatus, 81*fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 82*fcf3ce44SJohn Forte 83*fcf3ce44SJohn Forte break; 84*fcf3ce44SJohn Forte 85*fcf3ce44SJohn Forte /* 86*fcf3ce44SJohn Forte * Error: Abnormal XMIT SEQUENCE (Local error) 87*fcf3ce44SJohn Forte */ 88*fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE_CR: 89*fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE64_CR: 90*fcf3ce44SJohn Forte 91*fcf3ce44SJohn Forte HBASTATS.IpSeqCompleted++; 92*fcf3ce44SJohn Forte HBASTATS.IpSeqError++; 93*fcf3ce44SJohn Forte 94*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 95*fcf3ce44SJohn Forte "XMIT SEQUENCE CR completion error: " 96*fcf3ce44SJohn Forte "cmd=%x status=0x%x [%08x,%08x]", cmd->ulpCommand, 97*fcf3ce44SJohn Forte cmd->ulpStatus, cmd->un.ulpWord[4], cmd->un.ulpWord[5]); 98*fcf3ce44SJohn Forte 99*fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, cmd->ulpStatus, 100*fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 101*fcf3ce44SJohn Forte 102*fcf3ce44SJohn Forte break; 103*fcf3ce44SJohn Forte 104*fcf3ce44SJohn Forte /* 105*fcf3ce44SJohn Forte * Normal BCAST completion 106*fcf3ce44SJohn Forte */ 107*fcf3ce44SJohn Forte case CMD_XMIT_BCAST_CX: 108*fcf3ce44SJohn Forte case CMD_XMIT_BCAST64_CX: 109*fcf3ce44SJohn Forte 110*fcf3ce44SJohn Forte HBASTATS.IpBcastCompleted++; 111*fcf3ce44SJohn Forte HBASTATS.IpBcastGood++; 112*fcf3ce44SJohn Forte 113*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 114*fcf3ce44SJohn Forte "XMIT BCAST CN completion: cmd=%x status=0x%x [%08x,%08x]", 115*fcf3ce44SJohn Forte cmd->ulpCommand, cmd->ulpStatus, cmd->un.ulpWord[4], 116*fcf3ce44SJohn Forte cmd->un.ulpWord[5]); 117*fcf3ce44SJohn Forte 118*fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, cmd->ulpStatus, 119*fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 120*fcf3ce44SJohn Forte 121*fcf3ce44SJohn Forte break; 122*fcf3ce44SJohn Forte 123*fcf3ce44SJohn Forte /* 124*fcf3ce44SJohn Forte * Normal XMIT SEQUENCE completion 125*fcf3ce44SJohn Forte */ 126*fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE_CX: 127*fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE64_CX: 128*fcf3ce44SJohn Forte 129*fcf3ce44SJohn Forte HBASTATS.IpSeqCompleted++; 130*fcf3ce44SJohn Forte 131*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 132*fcf3ce44SJohn Forte "XMIT SEQUENCE CR completion: cmd=%x status=0x%x " 133*fcf3ce44SJohn Forte "[%08x,%08x]", cmd->ulpCommand, cmd->ulpStatus, 134*fcf3ce44SJohn Forte cmd->un.ulpWord[4], cmd->un.ulpWord[5]); 135*fcf3ce44SJohn Forte 136*fcf3ce44SJohn Forte if (cmd->ulpStatus) { 137*fcf3ce44SJohn Forte HBASTATS.IpSeqError++; 138*fcf3ce44SJohn Forte 139*fcf3ce44SJohn Forte if ((cmd->ulpStatus == IOSTAT_LOCAL_REJECT) && 140*fcf3ce44SJohn Forte ((cmd->un.ulpWord[4] & 0xff) == IOERR_NO_XRI)) { 141*fcf3ce44SJohn Forte ndlp = (NODELIST *) sbp->node; 142*fcf3ce44SJohn Forte if ((cmd->ulpContext == ndlp->nlp_Xri) && 143*fcf3ce44SJohn Forte !(ndlp->nlp_flag[FC_IP_RING] & 144*fcf3ce44SJohn Forte NLP_RPI_XRI)) { 145*fcf3ce44SJohn Forte ndlp->nlp_Xri = 0; 146*fcf3ce44SJohn Forte (void) emlxs_create_xri(port, rp, ndlp); 147*fcf3ce44SJohn Forte } 148*fcf3ce44SJohn Forte } 149*fcf3ce44SJohn Forte } else { 150*fcf3ce44SJohn Forte HBASTATS.IpSeqGood++; 151*fcf3ce44SJohn Forte } 152*fcf3ce44SJohn Forte 153*fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, cmd->ulpStatus, 154*fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 155*fcf3ce44SJohn Forte 156*fcf3ce44SJohn Forte break; 157*fcf3ce44SJohn Forte 158*fcf3ce44SJohn Forte default: 159*fcf3ce44SJohn Forte 160*fcf3ce44SJohn Forte HBASTATS.IpStray++; 161*fcf3ce44SJohn Forte 162*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ip_msg, 163*fcf3ce44SJohn Forte "Invalid iocb: cmd=0x%x", cmd->ulpCommand); 164*fcf3ce44SJohn Forte 165*fcf3ce44SJohn Forte break; 166*fcf3ce44SJohn Forte 167*fcf3ce44SJohn Forte } /* switch(cmd->ulpCommand) */ 168*fcf3ce44SJohn Forte 169*fcf3ce44SJohn Forte 170*fcf3ce44SJohn Forte return (0); 171*fcf3ce44SJohn Forte 172*fcf3ce44SJohn Forte } /* emlxs_ip_handle_event() */ 173*fcf3ce44SJohn Forte 174*fcf3ce44SJohn Forte 175*fcf3ce44SJohn Forte extern int32_t 176*fcf3ce44SJohn Forte emlxs_ip_handle_unsol_req(emlxs_port_t *port, RING *rp, IOCBQ *iocbq, 177*fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 178*fcf3ce44SJohn Forte { 179*fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 180*fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 181*fcf3ce44SJohn Forte IOCB *cmd; 182*fcf3ce44SJohn Forte NETHDR *nd; 183*fcf3ce44SJohn Forte NODELIST *ndlp; 184*fcf3ce44SJohn Forte uint8_t *mac; 185*fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 186*fcf3ce44SJohn Forte uint32_t sid; 187*fcf3ce44SJohn Forte uint32_t i; 188*fcf3ce44SJohn Forte uint32_t IpDropped = 1; 189*fcf3ce44SJohn Forte uint32_t IpBcastReceived = 0; 190*fcf3ce44SJohn Forte uint32_t IpSeqReceived = 0; 191*fcf3ce44SJohn Forte 192*fcf3ce44SJohn Forte cmd = &iocbq->iocb; 193*fcf3ce44SJohn Forte ubp = NULL; 194*fcf3ce44SJohn Forte 195*fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 196*fcf3ce44SJohn Forte port = &VPORT(i); 197*fcf3ce44SJohn Forte 198*fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_BOUND) || 199*fcf3ce44SJohn Forte !(port->flag & EMLXS_PORT_IP_UP)) { 200*fcf3ce44SJohn Forte continue; 201*fcf3ce44SJohn Forte } 202*fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *) 203*fcf3ce44SJohn Forte emlxs_ub_get(port, size, FC_TYPE_IS8802_SNAP, 0); 204*fcf3ce44SJohn Forte 205*fcf3ce44SJohn Forte if (!ubp) { 206*fcf3ce44SJohn Forte 207*fcf3ce44SJohn Forte /* Theoretically we should never get here. */ 208*fcf3ce44SJohn Forte /* 209*fcf3ce44SJohn Forte * There should be one DMA buffer for every ub 210*fcf3ce44SJohn Forte * buffer. If we are out of ub buffers 211*fcf3ce44SJohn Forte */ 212*fcf3ce44SJohn Forte /* then some how this matching has been corrupted */ 213*fcf3ce44SJohn Forte 214*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ip_dropped_msg, 215*fcf3ce44SJohn Forte "Buffer not found. paddr=%lx", 216*fcf3ce44SJohn Forte getPaddr(cmd->un.cont64[0].addrHigh, 217*fcf3ce44SJohn Forte cmd->un.cont64[0].addrLow)); 218*fcf3ce44SJohn Forte 219*fcf3ce44SJohn Forte continue; 220*fcf3ce44SJohn Forte } 221*fcf3ce44SJohn Forte bcopy(mp->virt, ubp->ub_buffer, size); 222*fcf3ce44SJohn Forte 223*fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 224*fcf3ce44SJohn Forte nd = (NETHDR *) ubp->ub_buffer; 225*fcf3ce44SJohn Forte mac = nd->fc_srcname.IEEE; 226*fcf3ce44SJohn Forte ndlp = emlxs_node_find_mac(port, mac); 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte if (ndlp) { 229*fcf3ce44SJohn Forte sid = ndlp->nlp_DID; 230*fcf3ce44SJohn Forte 231*fcf3ce44SJohn Forte if ((ndlp->nlp_Xri == 0) && 232*fcf3ce44SJohn Forte !(ndlp->nlp_flag[FC_IP_RING] & NLP_RPI_XRI)) { 233*fcf3ce44SJohn Forte (void) emlxs_create_xri(port, rp, ndlp); 234*fcf3ce44SJohn Forte } 235*fcf3ce44SJohn Forte } 236*fcf3ce44SJohn Forte /* 237*fcf3ce44SJohn Forte * If no node is found, then check if this is a broadcast 238*fcf3ce44SJohn Forte * frame 239*fcf3ce44SJohn Forte */ 240*fcf3ce44SJohn Forte else if (cmd->un.xrseq.w5.hcsw.Fctl & BC) { 241*fcf3ce44SJohn Forte sid = cmd->un.ulpWord[4] & 0x00ffffff; 242*fcf3ce44SJohn Forte } else { 243*fcf3ce44SJohn Forte /* 244*fcf3ce44SJohn Forte * We have to drop this frame because we do not have 245*fcf3ce44SJohn Forte * the S_ID of the request 246*fcf3ce44SJohn Forte */ 247*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ip_dropped_msg, 248*fcf3ce44SJohn Forte "Node not found. mac=%02x%02x%02x%02x%02x%02x", 249*fcf3ce44SJohn Forte mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 250*fcf3ce44SJohn Forte 251*fcf3ce44SJohn Forte (void) emlxs_ub_release((opaque_t)port, 1, 252*fcf3ce44SJohn Forte &ubp->ub_token); 253*fcf3ce44SJohn Forte 254*fcf3ce44SJohn Forte continue; 255*fcf3ce44SJohn Forte } 256*fcf3ce44SJohn Forte 257*fcf3ce44SJohn Forte if (cmd->un.xrseq.w5.hcsw.Fctl & BC) { 258*fcf3ce44SJohn Forte IpBcastReceived++; 259*fcf3ce44SJohn Forte } else { 260*fcf3ce44SJohn Forte IpSeqReceived++; 261*fcf3ce44SJohn Forte } 262*fcf3ce44SJohn Forte 263*fcf3ce44SJohn Forte /* 264*fcf3ce44SJohn Forte * Setup frame header 265*fcf3ce44SJohn Forte */ 266*fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = cmd->un.xrseq.w5.hcsw.Rctl; 267*fcf3ce44SJohn Forte ubp->ub_frame.type = cmd->un.xrseq.w5.hcsw.Type; 268*fcf3ce44SJohn Forte ubp->ub_frame.s_id = sid; 269*fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 270*fcf3ce44SJohn Forte ubp->ub_frame.rx_id = cmd->ulpContext; 271*fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 272*fcf3ce44SJohn Forte 273*fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 274*fcf3ce44SJohn Forte IpDropped = 0; 275*fcf3ce44SJohn Forte } 276*fcf3ce44SJohn Forte port = &PPORT; 277*fcf3ce44SJohn Forte 278*fcf3ce44SJohn Forte out: 279*fcf3ce44SJohn Forte 280*fcf3ce44SJohn Forte if (IpDropped) { 281*fcf3ce44SJohn Forte HBASTATS.IpDropped++; 282*fcf3ce44SJohn Forte } 283*fcf3ce44SJohn Forte if (IpBcastReceived) { 284*fcf3ce44SJohn Forte HBASTATS.IpBcastReceived++; 285*fcf3ce44SJohn Forte } 286*fcf3ce44SJohn Forte if (IpSeqReceived) { 287*fcf3ce44SJohn Forte HBASTATS.IpSeqReceived++; 288*fcf3ce44SJohn Forte } 289*fcf3ce44SJohn Forte return (0); 290*fcf3ce44SJohn Forte 291*fcf3ce44SJohn Forte } /* emlxs_ip_handle_unsol_req() */ 292*fcf3ce44SJohn Forte 293*fcf3ce44SJohn Forte 294*fcf3ce44SJohn Forte extern int32_t 295*fcf3ce44SJohn Forte emlxs_ip_handle_rcv_seq_list(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq) 296*fcf3ce44SJohn Forte { 297*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 298*fcf3ce44SJohn Forte IOCB *cmd; 299*fcf3ce44SJohn Forte uint64_t bdeAddr; 300*fcf3ce44SJohn Forte MATCHMAP *mp = NULL; 301*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 302*fcf3ce44SJohn Forte HBQE_t *hbqE; 303*fcf3ce44SJohn Forte uint32_t hbq_id; 304*fcf3ce44SJohn Forte uint32_t hbqe_tag; 305*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 306*fcf3ce44SJohn Forte 307*fcf3ce44SJohn Forte /* 308*fcf3ce44SJohn Forte * No action required for now. 309*fcf3ce44SJohn Forte */ 310*fcf3ce44SJohn Forte cmd = &iocbq->iocb; 311*fcf3ce44SJohn Forte 312*fcf3ce44SJohn Forte HBASTATS.IpRcvEvent++; 313*fcf3ce44SJohn Forte 314*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 315*fcf3ce44SJohn Forte "Receive sequence list: cmd=0x%x iotag=0x%x status=0x%x " 316*fcf3ce44SJohn Forte "w4=0x%x ringno=0x%x", cmd->ulpCommand, cmd->ulpIoTag, 317*fcf3ce44SJohn Forte cmd->ulpStatus, cmd->un.ulpWord[4], rp->ringno); 318*fcf3ce44SJohn Forte 319*fcf3ce44SJohn Forte if (cmd->ulpStatus) { 320*fcf3ce44SJohn Forte goto out; 321*fcf3ce44SJohn Forte } 322*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 323*fcf3ce44SJohn Forte hbqE = (HBQE_t *)&iocbq->iocb; 324*fcf3ce44SJohn Forte hbq_id = hbqE->unt.ext.HBQ_tag; 325*fcf3ce44SJohn Forte hbqe_tag = hbqE->unt.ext.HBQE_tag; 326*fcf3ce44SJohn Forte 327*fcf3ce44SJohn Forte if (hba->flag & FC_HBQ_ENABLED) { 328*fcf3ce44SJohn Forte HBQ_INIT_t *hbq; 329*fcf3ce44SJohn Forte 330*fcf3ce44SJohn Forte hbq = &hba->hbq_table[hbq_id]; 331*fcf3ce44SJohn Forte 332*fcf3ce44SJohn Forte HBASTATS.IpUbPosted--; 333*fcf3ce44SJohn Forte 334*fcf3ce44SJohn Forte if (hbqe_tag >= hbq->HBQ_numEntries) { 335*fcf3ce44SJohn Forte mp = NULL; 336*fcf3ce44SJohn Forte } else { 337*fcf3ce44SJohn Forte mp = hba->hbq_table[hbq_id].HBQ_PostBufs[hbqe_tag]; 338*fcf3ce44SJohn Forte } 339*fcf3ce44SJohn Forte } else 340*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 341*fcf3ce44SJohn Forte { 342*fcf3ce44SJohn Forte /* Check for valid buffer */ 343*fcf3ce44SJohn Forte if (!(cmd->un.cont64[0].tus.f.bdeFlags & BUFF_TYPE_INVALID)) { 344*fcf3ce44SJohn Forte bdeAddr = getPaddr(cmd->un.cont64[0].addrHigh, 345*fcf3ce44SJohn Forte cmd->un.cont64[0].addrLow); 346*fcf3ce44SJohn Forte mp = emlxs_mem_get_vaddr(hba, rp, bdeAddr); 347*fcf3ce44SJohn Forte } 348*fcf3ce44SJohn Forte } 349*fcf3ce44SJohn Forte 350*fcf3ce44SJohn Forte out: 351*fcf3ce44SJohn Forte 352*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 353*fcf3ce44SJohn Forte if (hba->flag & FC_HBQ_ENABLED) { 354*fcf3ce44SJohn Forte emlxs_update_HBQ_index(hba, hbq_id); 355*fcf3ce44SJohn Forte } else 356*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 357*fcf3ce44SJohn Forte { 358*fcf3ce44SJohn Forte if (mp) { 359*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_IPBUF, (uint8_t *)mp); 360*fcf3ce44SJohn Forte } 361*fcf3ce44SJohn Forte (void) emlxs_post_buffer(hba, rp, 1); 362*fcf3ce44SJohn Forte } 363*fcf3ce44SJohn Forte 364*fcf3ce44SJohn Forte HBASTATS.IpDropped++; 365*fcf3ce44SJohn Forte 366*fcf3ce44SJohn Forte return (0); 367*fcf3ce44SJohn Forte 368*fcf3ce44SJohn Forte } /* emlxs_ip_handle_rcv_seq_list() */ 369*fcf3ce44SJohn Forte 370*fcf3ce44SJohn Forte 371*fcf3ce44SJohn Forte 372*fcf3ce44SJohn Forte /* 373*fcf3ce44SJohn Forte * Process a create_xri command completion. 374*fcf3ce44SJohn Forte */ 375*fcf3ce44SJohn Forte extern int32_t 376*fcf3ce44SJohn Forte emlxs_handle_create_xri(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq) 377*fcf3ce44SJohn Forte { 378*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 379*fcf3ce44SJohn Forte IOCB *cmd; 380*fcf3ce44SJohn Forte NODELIST *ndlp; 381*fcf3ce44SJohn Forte fc_packet_t *pkt; 382*fcf3ce44SJohn Forte emlxs_buf_t *sbp; 383*fcf3ce44SJohn Forte 384*fcf3ce44SJohn Forte cmd = &iocbq->iocb; 385*fcf3ce44SJohn Forte 386*fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 387*fcf3ce44SJohn Forte 388*fcf3ce44SJohn Forte if (!sbp) { 389*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg, 390*fcf3ce44SJohn Forte "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x", 391*fcf3ce44SJohn Forte cmd->ulpCommand, cmd->ulpIoTag, cmd->ulpStatus, 392*fcf3ce44SJohn Forte cmd->un.ulpWord[4]); 393*fcf3ce44SJohn Forte 394*fcf3ce44SJohn Forte return (EIO); 395*fcf3ce44SJohn Forte } 396*fcf3ce44SJohn Forte /* check for first xmit completion in sequence */ 397*fcf3ce44SJohn Forte ndlp = (NODELIST *)sbp->node; 398*fcf3ce44SJohn Forte 399*fcf3ce44SJohn Forte if (cmd->ulpStatus) { 400*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_bad_ip_completion_msg, 401*fcf3ce44SJohn Forte "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x", 402*fcf3ce44SJohn Forte cmd->ulpCommand, cmd->ulpIoTag, cmd->ulpStatus, 403*fcf3ce44SJohn Forte cmd->un.ulpWord[4]); 404*fcf3ce44SJohn Forte 405*fcf3ce44SJohn Forte mutex_enter(&EMLXS_RINGTX_LOCK); 406*fcf3ce44SJohn Forte ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI; 407*fcf3ce44SJohn Forte mutex_exit(&EMLXS_RINGTX_LOCK); 408*fcf3ce44SJohn Forte 409*fcf3ce44SJohn Forte return (EIO); 410*fcf3ce44SJohn Forte } 411*fcf3ce44SJohn Forte mutex_enter(&EMLXS_RINGTX_LOCK); 412*fcf3ce44SJohn Forte ndlp->nlp_Xri = cmd->ulpContext; 413*fcf3ce44SJohn Forte ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI; 414*fcf3ce44SJohn Forte mutex_exit(&EMLXS_RINGTX_LOCK); 415*fcf3ce44SJohn Forte 416*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 417*fcf3ce44SJohn Forte "create_xri completed: DID=0x%x Xri=0x%x iotag=0x%x", 418*fcf3ce44SJohn Forte ndlp->nlp_DID, ndlp->nlp_Xri, cmd->ulpIoTag); 419*fcf3ce44SJohn Forte 420*fcf3ce44SJohn Forte pkt = sbp->pkt; 421*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 422*fcf3ce44SJohn Forte 423*fcf3ce44SJohn Forte return (0); 424*fcf3ce44SJohn Forte 425*fcf3ce44SJohn Forte } /* emlxs_handle_create_xri() */ 426*fcf3ce44SJohn Forte 427*fcf3ce44SJohn Forte 428*fcf3ce44SJohn Forte /* 429*fcf3ce44SJohn Forte * Issue an iocb command to create an exchange with 430*fcf3ce44SJohn Forte * the remote Nport specified by the NODELIST entry. 431*fcf3ce44SJohn Forte */ 432*fcf3ce44SJohn Forte extern int32_t 433*fcf3ce44SJohn Forte emlxs_create_xri(emlxs_port_t *port, RING *rp, NODELIST *ndlp) 434*fcf3ce44SJohn Forte { 435*fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 436*fcf3ce44SJohn Forte IOCB *icmd; 437*fcf3ce44SJohn Forte IOCBQ *iocbq; 438*fcf3ce44SJohn Forte fc_packet_t *pkt; 439*fcf3ce44SJohn Forte emlxs_buf_t *sbp; 440*fcf3ce44SJohn Forte uint16_t iotag; 441*fcf3ce44SJohn Forte 442*fcf3ce44SJohn Forte /* Check if an XRI has already been requested */ 443*fcf3ce44SJohn Forte mutex_enter(&EMLXS_RINGTX_LOCK); 444*fcf3ce44SJohn Forte if (ndlp->nlp_Xri != 0 || (ndlp->nlp_flag[rp->ringno] & NLP_RPI_XRI)) { 445*fcf3ce44SJohn Forte mutex_exit(&EMLXS_RINGTX_LOCK); 446*fcf3ce44SJohn Forte return (0); 447*fcf3ce44SJohn Forte } 448*fcf3ce44SJohn Forte ndlp->nlp_flag[rp->ringno] |= NLP_RPI_XRI; 449*fcf3ce44SJohn Forte mutex_exit(&EMLXS_RINGTX_LOCK); 450*fcf3ce44SJohn Forte 451*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) { 452*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 453*fcf3ce44SJohn Forte "create_xri failed: Unable to allocate pkt. did=0x%x", 454*fcf3ce44SJohn Forte ndlp->nlp_DID); 455*fcf3ce44SJohn Forte 456*fcf3ce44SJohn Forte goto fail; 457*fcf3ce44SJohn Forte } 458*fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)pkt->pkt_fca_private; 459*fcf3ce44SJohn Forte iocbq = &sbp->iocbq; 460*fcf3ce44SJohn Forte 461*fcf3ce44SJohn Forte /* Get the iotag by registering the packet */ 462*fcf3ce44SJohn Forte iotag = emlxs_register_pkt(rp, sbp); 463*fcf3ce44SJohn Forte 464*fcf3ce44SJohn Forte if (!iotag) { 465*fcf3ce44SJohn Forte /* 466*fcf3ce44SJohn Forte * No more command slots available, retry later 467*fcf3ce44SJohn Forte */ 468*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 469*fcf3ce44SJohn Forte 470*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 471*fcf3ce44SJohn Forte "create_xri failed: Unable to allocate IOTAG. did=0x%x", 472*fcf3ce44SJohn Forte ndlp->nlp_DID); 473*fcf3ce44SJohn Forte 474*fcf3ce44SJohn Forte goto fail; 475*fcf3ce44SJohn Forte } 476*fcf3ce44SJohn Forte icmd = &iocbq->iocb; 477*fcf3ce44SJohn Forte icmd->ulpIoTag = iotag; 478*fcf3ce44SJohn Forte icmd->ulpContext = ndlp->nlp_Rpi; 479*fcf3ce44SJohn Forte icmd->ulpLe = 1; 480*fcf3ce44SJohn Forte icmd->ulpCommand = CMD_CREATE_XRI_CR; 481*fcf3ce44SJohn Forte icmd->ulpOwner = OWN_CHIP; 482*fcf3ce44SJohn Forte 483*fcf3ce44SJohn Forte /* Initalize iocbq */ 484*fcf3ce44SJohn Forte iocbq->port = (void *)port; 485*fcf3ce44SJohn Forte iocbq->node = (void *)ndlp; 486*fcf3ce44SJohn Forte iocbq->ring = (void *)rp; 487*fcf3ce44SJohn Forte 488*fcf3ce44SJohn Forte mutex_enter(&sbp->mtx); 489*fcf3ce44SJohn Forte sbp->node = (void *)ndlp; 490*fcf3ce44SJohn Forte sbp->ring = rp; 491*fcf3ce44SJohn Forte mutex_exit(&sbp->mtx); 492*fcf3ce44SJohn Forte 493*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 494*fcf3ce44SJohn Forte "create_xri sent: DID=0x%x Xri=0x%x iotag=0x%x", 495*fcf3ce44SJohn Forte ndlp->nlp_DID, ndlp->nlp_Xri, iotag); 496*fcf3ce44SJohn Forte 497*fcf3ce44SJohn Forte emlxs_issue_iocb_cmd(hba, rp, iocbq); 498*fcf3ce44SJohn Forte 499*fcf3ce44SJohn Forte return (0); 500*fcf3ce44SJohn Forte 501*fcf3ce44SJohn Forte fail: 502*fcf3ce44SJohn Forte 503*fcf3ce44SJohn Forte /* Clear the XRI flag */ 504*fcf3ce44SJohn Forte mutex_enter(&EMLXS_RINGTX_LOCK); 505*fcf3ce44SJohn Forte ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI; 506*fcf3ce44SJohn Forte mutex_exit(&EMLXS_RINGTX_LOCK); 507*fcf3ce44SJohn Forte 508*fcf3ce44SJohn Forte return (1); 509*fcf3ce44SJohn Forte 510*fcf3ce44SJohn Forte } /* emlxs_create_xri() */ 511