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