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 /* 23291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24*82527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27*82527734SSukumar Swaminathan 28291a2b48SSukumar Swaminathan #include <emlxs.h> 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 31fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_IP_C); 32fcf3ce44SJohn Forte 33fcf3ce44SJohn Forte 34fcf3ce44SJohn Forte extern int32_t 35*82527734SSukumar Swaminathan emlxs_ip_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 36fcf3ce44SJohn Forte { 37fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 38fcf3ce44SJohn Forte IOCB *cmd; 39fcf3ce44SJohn Forte emlxs_buf_t *sbp; 40fcf3ce44SJohn Forte NODELIST *ndlp; 41fcf3ce44SJohn Forte 42fcf3ce44SJohn Forte cmd = &iocbq->iocb; 43fcf3ce44SJohn Forte 44fcf3ce44SJohn Forte HBASTATS.IpEvent++; 45fcf3ce44SJohn Forte 46fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 47fcf3ce44SJohn Forte 48fcf3ce44SJohn Forte if (!sbp) { 49fcf3ce44SJohn Forte HBASTATS.IpStray++; 50fcf3ce44SJohn Forte 51fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg, 52fcf3ce44SJohn Forte "cmd=0x%x iotag=0x%x status=0x%x perr=0x%x", 53*82527734SSukumar Swaminathan (uint32_t)cmd->ULPCOMMAND, (uint32_t)cmd->ULPIOTAG, 54*82527734SSukumar Swaminathan cmd->ULPSTATUS, cmd->un.ulpWord[4]); 55fcf3ce44SJohn Forte 56fcf3ce44SJohn Forte return (EIO); 57fcf3ce44SJohn Forte } 58291a2b48SSukumar Swaminathan 59*82527734SSukumar Swaminathan if (cp->channelno != hba->channel_ip) { 60fcf3ce44SJohn Forte HBASTATS.IpStray++; 61fcf3ce44SJohn Forte 62fcf3ce44SJohn Forte return (0); 63fcf3ce44SJohn Forte } 64291a2b48SSukumar Swaminathan 65fcf3ce44SJohn Forte port = sbp->iocbq.port; 66fcf3ce44SJohn Forte 67*82527734SSukumar Swaminathan switch (cmd->ULPCOMMAND) { 68fcf3ce44SJohn Forte /* 69291a2b48SSukumar Swaminathan * Error: Abnormal BCAST command completion (Local error) 70fcf3ce44SJohn Forte */ 71fcf3ce44SJohn Forte case CMD_XMIT_BCAST_CN: 72fcf3ce44SJohn Forte case CMD_XMIT_BCAST64_CN: 73fcf3ce44SJohn Forte 74fcf3ce44SJohn Forte HBASTATS.IpBcastCompleted++; 75fcf3ce44SJohn Forte HBASTATS.IpBcastError++; 76fcf3ce44SJohn Forte 77fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 78fcf3ce44SJohn Forte "XMIT BCAST completion error cmd=0x%x status=0x%x " 79*82527734SSukumar Swaminathan "[%08x,%08x]", cmd->ULPCOMMAND, cmd->ULPSTATUS, 80fcf3ce44SJohn Forte cmd->un.ulpWord[4], cmd->un.ulpWord[5]); 81fcf3ce44SJohn Forte 82*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, cmd->ULPSTATUS, 83fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 84fcf3ce44SJohn Forte 85fcf3ce44SJohn Forte break; 86fcf3ce44SJohn Forte 87fcf3ce44SJohn Forte /* 88291a2b48SSukumar Swaminathan * Error: Abnormal XMIT SEQUENCE command completion 89291a2b48SSukumar Swaminathan * (Local error) 90fcf3ce44SJohn Forte */ 91fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE_CR: 92fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE64_CR: 93fcf3ce44SJohn Forte 94fcf3ce44SJohn Forte HBASTATS.IpSeqCompleted++; 95fcf3ce44SJohn Forte HBASTATS.IpSeqError++; 96fcf3ce44SJohn Forte 97fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 98291a2b48SSukumar Swaminathan "XMIT SEQUENCE CR completion error: cmd=%x status=0x%x " 99*82527734SSukumar Swaminathan "[%08x,%08x]", cmd->ULPCOMMAND, cmd->ULPSTATUS, 100291a2b48SSukumar Swaminathan cmd->un.ulpWord[4], cmd->un.ulpWord[5]); 101fcf3ce44SJohn Forte 102*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, cmd->ULPSTATUS, 103fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 104fcf3ce44SJohn Forte 105fcf3ce44SJohn Forte break; 106fcf3ce44SJohn Forte 107fcf3ce44SJohn Forte /* 108fcf3ce44SJohn Forte * Normal BCAST completion 109fcf3ce44SJohn Forte */ 110fcf3ce44SJohn Forte case CMD_XMIT_BCAST_CX: 111fcf3ce44SJohn Forte case CMD_XMIT_BCAST64_CX: 112fcf3ce44SJohn Forte 113fcf3ce44SJohn Forte HBASTATS.IpBcastCompleted++; 114fcf3ce44SJohn Forte HBASTATS.IpBcastGood++; 115fcf3ce44SJohn Forte 116fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 117fcf3ce44SJohn Forte "XMIT BCAST CN completion: cmd=%x status=0x%x [%08x,%08x]", 118*82527734SSukumar Swaminathan cmd->ULPCOMMAND, cmd->ULPSTATUS, cmd->un.ulpWord[4], 119fcf3ce44SJohn Forte cmd->un.ulpWord[5]); 120fcf3ce44SJohn Forte 121*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, cmd->ULPSTATUS, 122fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 123fcf3ce44SJohn Forte 124fcf3ce44SJohn Forte break; 125fcf3ce44SJohn Forte 126fcf3ce44SJohn Forte /* 127fcf3ce44SJohn Forte * Normal XMIT SEQUENCE completion 128fcf3ce44SJohn Forte */ 129fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE_CX: 130fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE64_CX: 131fcf3ce44SJohn Forte 132fcf3ce44SJohn Forte HBASTATS.IpSeqCompleted++; 133fcf3ce44SJohn Forte 134fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 135291a2b48SSukumar Swaminathan "XMIT SEQUENCE CR completion: cmd=%x status=0x%x" 136*82527734SSukumar Swaminathan "[%08x,%08x]", cmd->ULPCOMMAND, cmd->ULPSTATUS, 137fcf3ce44SJohn Forte cmd->un.ulpWord[4], cmd->un.ulpWord[5]); 138fcf3ce44SJohn Forte 139*82527734SSukumar Swaminathan if (cmd->ULPSTATUS) { 140fcf3ce44SJohn Forte HBASTATS.IpSeqError++; 141fcf3ce44SJohn Forte 142*82527734SSukumar Swaminathan if ((cmd->ULPSTATUS == IOSTAT_LOCAL_REJECT) && 143fcf3ce44SJohn Forte ((cmd->un.ulpWord[4] & 0xff) == IOERR_NO_XRI)) { 144291a2b48SSukumar Swaminathan ndlp = (NODELIST *)sbp->node; 145*82527734SSukumar Swaminathan if ((cmd->ULPCONTEXT == ndlp->nlp_Xri) && 146*82527734SSukumar Swaminathan !(ndlp->nlp_flag[hba->channel_ip] & 147fcf3ce44SJohn Forte NLP_RPI_XRI)) { 148fcf3ce44SJohn Forte ndlp->nlp_Xri = 0; 149*82527734SSukumar Swaminathan (void) emlxs_create_xri(port, cp, ndlp); 150fcf3ce44SJohn Forte } 151fcf3ce44SJohn Forte } 152fcf3ce44SJohn Forte } else { 153fcf3ce44SJohn Forte HBASTATS.IpSeqGood++; 154fcf3ce44SJohn Forte } 155fcf3ce44SJohn Forte 156*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, cmd->ULPSTATUS, 157fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 158fcf3ce44SJohn Forte 159fcf3ce44SJohn Forte break; 160fcf3ce44SJohn Forte 161fcf3ce44SJohn Forte default: 162fcf3ce44SJohn Forte 163fcf3ce44SJohn Forte HBASTATS.IpStray++; 164fcf3ce44SJohn Forte 165fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ip_msg, 166*82527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", cmd->ULPCOMMAND); 167fcf3ce44SJohn Forte 168fcf3ce44SJohn Forte break; 169fcf3ce44SJohn Forte 170*82527734SSukumar Swaminathan } /* switch(cmd->ULPCOMMAND) */ 171fcf3ce44SJohn Forte 172fcf3ce44SJohn Forte 173fcf3ce44SJohn Forte return (0); 174fcf3ce44SJohn Forte 175*82527734SSukumar Swaminathan } /* emlxs_ip_handle_event() */ 176fcf3ce44SJohn Forte 177fcf3ce44SJohn Forte 178fcf3ce44SJohn Forte extern int32_t 179*82527734SSukumar Swaminathan emlxs_ip_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 180fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 181fcf3ce44SJohn Forte { 182fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 183fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 184fcf3ce44SJohn Forte IOCB *cmd; 185fcf3ce44SJohn Forte NETHDR *nd; 186fcf3ce44SJohn Forte NODELIST *ndlp; 187fcf3ce44SJohn Forte uint8_t *mac; 188fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 189fcf3ce44SJohn Forte uint32_t sid; 190fcf3ce44SJohn Forte uint32_t i; 191fcf3ce44SJohn Forte uint32_t IpDropped = 1; 192fcf3ce44SJohn Forte uint32_t IpBcastReceived = 0; 193fcf3ce44SJohn Forte uint32_t IpSeqReceived = 0; 194fcf3ce44SJohn Forte 195fcf3ce44SJohn Forte cmd = &iocbq->iocb; 196fcf3ce44SJohn Forte ubp = NULL; 197fcf3ce44SJohn Forte 198fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 199fcf3ce44SJohn Forte port = &VPORT(i); 200fcf3ce44SJohn Forte 201fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_BOUND) || 202fcf3ce44SJohn Forte !(port->flag & EMLXS_PORT_IP_UP)) { 203fcf3ce44SJohn Forte continue; 204fcf3ce44SJohn Forte } 205fcf3ce44SJohn Forte 206291a2b48SSukumar Swaminathan ubp = 207291a2b48SSukumar Swaminathan (fc_unsol_buf_t *)emlxs_ub_get(port, size, 208291a2b48SSukumar Swaminathan FC_TYPE_IS8802_SNAP, 0); 209fcf3ce44SJohn Forte 210291a2b48SSukumar Swaminathan if (!ubp) { 211fcf3ce44SJohn Forte /* Theoretically we should never get here. */ 212291a2b48SSukumar Swaminathan /* There should be one DMA buffer for every ub */ 213291a2b48SSukumar Swaminathan /* buffer. If we are out of ub buffers */ 214fcf3ce44SJohn Forte /* then some how this matching has been corrupted */ 215fcf3ce44SJohn Forte 216fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ip_dropped_msg, 217fcf3ce44SJohn Forte "Buffer not found. paddr=%lx", 218*82527734SSukumar Swaminathan PADDR(cmd->un.cont64[0].addrHigh, 219fcf3ce44SJohn Forte cmd->un.cont64[0].addrLow)); 220fcf3ce44SJohn Forte 221fcf3ce44SJohn Forte continue; 222fcf3ce44SJohn Forte } 223291a2b48SSukumar Swaminathan 224fcf3ce44SJohn Forte bcopy(mp->virt, ubp->ub_buffer, size); 225fcf3ce44SJohn Forte 226fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 227291a2b48SSukumar Swaminathan nd = (NETHDR *)ubp->ub_buffer; 228fcf3ce44SJohn Forte mac = nd->fc_srcname.IEEE; 229fcf3ce44SJohn Forte ndlp = emlxs_node_find_mac(port, mac); 230fcf3ce44SJohn Forte 231fcf3ce44SJohn Forte if (ndlp) { 232fcf3ce44SJohn Forte sid = ndlp->nlp_DID; 233fcf3ce44SJohn Forte 234fcf3ce44SJohn Forte if ((ndlp->nlp_Xri == 0) && 235*82527734SSukumar Swaminathan !(ndlp->nlp_flag[hba->channel_ip] & NLP_RPI_XRI)) { 236*82527734SSukumar Swaminathan (void) emlxs_create_xri(port, cp, ndlp); 237fcf3ce44SJohn Forte } 238fcf3ce44SJohn Forte } 239291a2b48SSukumar Swaminathan 240fcf3ce44SJohn Forte /* 241291a2b48SSukumar Swaminathan * If no node is found, then check if this is a 242291a2b48SSukumar Swaminathan * broadcast frame 243fcf3ce44SJohn Forte */ 244fcf3ce44SJohn Forte else if (cmd->un.xrseq.w5.hcsw.Fctl & BC) { 245fcf3ce44SJohn Forte sid = cmd->un.ulpWord[4] & 0x00ffffff; 246291a2b48SSukumar Swaminathan } 247291a2b48SSukumar Swaminathan 248291a2b48SSukumar Swaminathan else { 249291a2b48SSukumar Swaminathan /* We have to drop this frame because we do not have */ 250291a2b48SSukumar Swaminathan /* the S_ID of the request */ 251fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ip_dropped_msg, 252fcf3ce44SJohn Forte "Node not found. mac=%02x%02x%02x%02x%02x%02x", 253fcf3ce44SJohn Forte mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 254fcf3ce44SJohn Forte 255fcf3ce44SJohn Forte (void) emlxs_ub_release((opaque_t)port, 1, 256fcf3ce44SJohn Forte &ubp->ub_token); 257fcf3ce44SJohn Forte 258fcf3ce44SJohn Forte continue; 259fcf3ce44SJohn Forte } 260fcf3ce44SJohn Forte 261fcf3ce44SJohn Forte if (cmd->un.xrseq.w5.hcsw.Fctl & BC) { 262fcf3ce44SJohn Forte IpBcastReceived++; 263fcf3ce44SJohn Forte } else { 264fcf3ce44SJohn Forte IpSeqReceived++; 265fcf3ce44SJohn Forte } 266fcf3ce44SJohn Forte 267fcf3ce44SJohn Forte /* 268fcf3ce44SJohn Forte * Setup frame header 269fcf3ce44SJohn Forte */ 270fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = cmd->un.xrseq.w5.hcsw.Rctl; 271fcf3ce44SJohn Forte ubp->ub_frame.type = cmd->un.xrseq.w5.hcsw.Type; 272fcf3ce44SJohn Forte ubp->ub_frame.s_id = sid; 273fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 274*82527734SSukumar Swaminathan ubp->ub_frame.rx_id = cmd->ULPCONTEXT; 275fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 276fcf3ce44SJohn Forte 277fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 278fcf3ce44SJohn Forte IpDropped = 0; 279fcf3ce44SJohn Forte } 280fcf3ce44SJohn Forte port = &PPORT; 281fcf3ce44SJohn Forte 282fcf3ce44SJohn Forte out: 283fcf3ce44SJohn Forte 284fcf3ce44SJohn Forte if (IpDropped) { 285fcf3ce44SJohn Forte HBASTATS.IpDropped++; 286fcf3ce44SJohn Forte } 287291a2b48SSukumar Swaminathan 288fcf3ce44SJohn Forte if (IpBcastReceived) { 289fcf3ce44SJohn Forte HBASTATS.IpBcastReceived++; 290fcf3ce44SJohn Forte } 291291a2b48SSukumar Swaminathan 292fcf3ce44SJohn Forte if (IpSeqReceived) { 293fcf3ce44SJohn Forte HBASTATS.IpSeqReceived++; 294fcf3ce44SJohn Forte } 295291a2b48SSukumar Swaminathan 296fcf3ce44SJohn Forte return (0); 297fcf3ce44SJohn Forte 298*82527734SSukumar Swaminathan } /* emlxs_ip_handle_unsol_req() */ 299fcf3ce44SJohn Forte 300fcf3ce44SJohn Forte 301fcf3ce44SJohn Forte extern int32_t 302*82527734SSukumar Swaminathan emlxs_ip_handle_rcv_seq_list(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 303fcf3ce44SJohn Forte { 304fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 305fcf3ce44SJohn Forte IOCB *cmd; 306fcf3ce44SJohn Forte uint64_t bdeAddr; 307fcf3ce44SJohn Forte MATCHMAP *mp = NULL; 308fcf3ce44SJohn Forte HBQE_t *hbqE; 309fcf3ce44SJohn Forte uint32_t hbq_id; 310fcf3ce44SJohn Forte uint32_t hbqe_tag; 311*82527734SSukumar Swaminathan RING *rp; 312fcf3ce44SJohn Forte 313fcf3ce44SJohn Forte /* 314fcf3ce44SJohn Forte * No action required for now. 315fcf3ce44SJohn Forte */ 316fcf3ce44SJohn Forte cmd = &iocbq->iocb; 317*82527734SSukumar Swaminathan rp = &hba->sli.sli3.ring[cp->channelno]; 318fcf3ce44SJohn Forte 319fcf3ce44SJohn Forte HBASTATS.IpRcvEvent++; 320fcf3ce44SJohn Forte 321fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 322fcf3ce44SJohn Forte "Receive sequence list: cmd=0x%x iotag=0x%x status=0x%x " 323*82527734SSukumar Swaminathan "w4=0x%x channelno=0x%x", cmd->ULPCOMMAND, cmd->ULPIOTAG, 324*82527734SSukumar Swaminathan cmd->ULPSTATUS, cmd->un.ulpWord[4], cp->channelno); 325fcf3ce44SJohn Forte 326*82527734SSukumar Swaminathan if (cmd->ULPSTATUS) { 327fcf3ce44SJohn Forte goto out; 328fcf3ce44SJohn Forte } 329*82527734SSukumar Swaminathan 330fcf3ce44SJohn Forte hbqE = (HBQE_t *)&iocbq->iocb; 331fcf3ce44SJohn Forte hbq_id = hbqE->unt.ext.HBQ_tag; 332fcf3ce44SJohn Forte hbqe_tag = hbqE->unt.ext.HBQE_tag; 333fcf3ce44SJohn Forte 334fcf3ce44SJohn Forte if (hba->flag & FC_HBQ_ENABLED) { 335fcf3ce44SJohn Forte HBQ_INIT_t *hbq; 336fcf3ce44SJohn Forte 337*82527734SSukumar Swaminathan hbq = &hba->sli.sli3.hbq_table[hbq_id]; 338fcf3ce44SJohn Forte 339fcf3ce44SJohn Forte HBASTATS.IpUbPosted--; 340fcf3ce44SJohn Forte 341fcf3ce44SJohn Forte if (hbqe_tag >= hbq->HBQ_numEntries) { 342fcf3ce44SJohn Forte mp = NULL; 343fcf3ce44SJohn Forte } else { 344*82527734SSukumar Swaminathan mp = hba->sli.sli3.hbq_table 345*82527734SSukumar Swaminathan [hbq_id].HBQ_PostBufs[hbqe_tag]; 346fcf3ce44SJohn Forte } 347*82527734SSukumar Swaminathan } else { 348fcf3ce44SJohn Forte /* Check for valid buffer */ 349fcf3ce44SJohn Forte if (!(cmd->un.cont64[0].tus.f.bdeFlags & BUFF_TYPE_INVALID)) { 350291a2b48SSukumar Swaminathan bdeAddr = 351*82527734SSukumar Swaminathan PADDR(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 if (hba->flag & FC_HBQ_ENABLED) { 360fcf3ce44SJohn Forte emlxs_update_HBQ_index(hba, hbq_id); 361*82527734SSukumar Swaminathan } else { 362fcf3ce44SJohn Forte if (mp) { 363fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_IPBUF, (uint8_t *)mp); 364fcf3ce44SJohn Forte } 365fcf3ce44SJohn Forte (void) emlxs_post_buffer(hba, rp, 1); 366fcf3ce44SJohn Forte } 367fcf3ce44SJohn Forte 368fcf3ce44SJohn Forte HBASTATS.IpDropped++; 369fcf3ce44SJohn Forte 370fcf3ce44SJohn Forte return (0); 371fcf3ce44SJohn Forte 372*82527734SSukumar Swaminathan } /* emlxs_ip_handle_rcv_seq_list() */ 373fcf3ce44SJohn Forte 374fcf3ce44SJohn Forte 375fcf3ce44SJohn Forte 376fcf3ce44SJohn Forte /* 377fcf3ce44SJohn Forte * Process a create_xri command completion. 378fcf3ce44SJohn Forte */ 379fcf3ce44SJohn Forte extern int32_t 380*82527734SSukumar Swaminathan emlxs_handle_create_xri(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 381fcf3ce44SJohn Forte { 382fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 383fcf3ce44SJohn Forte IOCB *cmd; 384fcf3ce44SJohn Forte NODELIST *ndlp; 385fcf3ce44SJohn Forte fc_packet_t *pkt; 386fcf3ce44SJohn Forte emlxs_buf_t *sbp; 387fcf3ce44SJohn Forte 388fcf3ce44SJohn Forte cmd = &iocbq->iocb; 389fcf3ce44SJohn Forte 390fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 391fcf3ce44SJohn Forte 392fcf3ce44SJohn Forte if (!sbp) { 393fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg, 394fcf3ce44SJohn Forte "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x", 395*82527734SSukumar Swaminathan cmd->ULPCOMMAND, cmd->ULPIOTAG, cmd->ULPSTATUS, 396fcf3ce44SJohn Forte cmd->un.ulpWord[4]); 397fcf3ce44SJohn Forte 398fcf3ce44SJohn Forte return (EIO); 399fcf3ce44SJohn Forte } 400291a2b48SSukumar Swaminathan 401fcf3ce44SJohn Forte /* check for first xmit completion in sequence */ 402fcf3ce44SJohn Forte ndlp = (NODELIST *)sbp->node; 403fcf3ce44SJohn Forte 404*82527734SSukumar Swaminathan if (cmd->ULPSTATUS) { 405fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_bad_ip_completion_msg, 406fcf3ce44SJohn Forte "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x", 407*82527734SSukumar Swaminathan cmd->ULPCOMMAND, cmd->ULPIOTAG, cmd->ULPSTATUS, 408fcf3ce44SJohn Forte cmd->un.ulpWord[4]); 409fcf3ce44SJohn Forte 410*82527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 411*82527734SSukumar Swaminathan ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI; 412*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 413fcf3ce44SJohn Forte 414fcf3ce44SJohn Forte return (EIO); 415fcf3ce44SJohn Forte } 416291a2b48SSukumar Swaminathan 417*82527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 418*82527734SSukumar Swaminathan ndlp->nlp_Xri = cmd->ULPCONTEXT; 419*82527734SSukumar Swaminathan ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI; 420*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 421fcf3ce44SJohn Forte 422fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 423fcf3ce44SJohn Forte "create_xri completed: DID=0x%x Xri=0x%x iotag=0x%x", 424*82527734SSukumar Swaminathan ndlp->nlp_DID, ndlp->nlp_Xri, cmd->ULPIOTAG); 425fcf3ce44SJohn Forte 426fcf3ce44SJohn Forte pkt = sbp->pkt; 427fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 428fcf3ce44SJohn Forte 429fcf3ce44SJohn Forte return (0); 430fcf3ce44SJohn Forte 431*82527734SSukumar Swaminathan } /* emlxs_handle_create_xri() */ 432fcf3ce44SJohn Forte 433fcf3ce44SJohn Forte 434fcf3ce44SJohn Forte /* 435291a2b48SSukumar Swaminathan * Issue an iocb command to create an exchange with the remote Nport 436291a2b48SSukumar Swaminathan * specified by the NODELIST entry. 437fcf3ce44SJohn Forte */ 438fcf3ce44SJohn Forte extern int32_t 439*82527734SSukumar Swaminathan emlxs_create_xri(emlxs_port_t *port, CHANNEL *cp, NODELIST *ndlp) 440fcf3ce44SJohn Forte { 441fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 442fcf3ce44SJohn Forte IOCB *icmd; 443fcf3ce44SJohn Forte IOCBQ *iocbq; 444fcf3ce44SJohn Forte fc_packet_t *pkt; 445fcf3ce44SJohn Forte emlxs_buf_t *sbp; 446fcf3ce44SJohn Forte uint16_t iotag; 447fcf3ce44SJohn Forte 448fcf3ce44SJohn Forte /* Check if an XRI has already been requested */ 449*82527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 450*82527734SSukumar Swaminathan if (ndlp->nlp_Xri != 0 || 451*82527734SSukumar Swaminathan (ndlp->nlp_flag[cp->channelno] & NLP_RPI_XRI)) { 452*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 453fcf3ce44SJohn Forte return (0); 454fcf3ce44SJohn Forte } 455*82527734SSukumar Swaminathan ndlp->nlp_flag[cp->channelno] |= NLP_RPI_XRI; 456*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 457fcf3ce44SJohn Forte 458fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) { 459fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 460fcf3ce44SJohn Forte "create_xri failed: Unable to allocate pkt. did=0x%x", 461fcf3ce44SJohn Forte ndlp->nlp_DID); 462fcf3ce44SJohn Forte 463fcf3ce44SJohn Forte goto fail; 464fcf3ce44SJohn Forte } 465291a2b48SSukumar Swaminathan 466fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)pkt->pkt_fca_private; 467fcf3ce44SJohn Forte iocbq = &sbp->iocbq; 468fcf3ce44SJohn Forte 469*82527734SSukumar Swaminathan /* Clear the PACKET_ULP_OWNED flag */ 470*82527734SSukumar Swaminathan sbp->pkt_flags &= ~PACKET_ULP_OWNED; 471*82527734SSukumar Swaminathan 472fcf3ce44SJohn Forte /* Get the iotag by registering the packet */ 473*82527734SSukumar Swaminathan iotag = emlxs_register_pkt(cp, sbp); 474fcf3ce44SJohn Forte 475fcf3ce44SJohn Forte if (!iotag) { 476fcf3ce44SJohn Forte /* 477fcf3ce44SJohn Forte * No more command slots available, retry later 478fcf3ce44SJohn Forte */ 479fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 480fcf3ce44SJohn Forte 481fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 482fcf3ce44SJohn Forte "create_xri failed: Unable to allocate IOTAG. did=0x%x", 483fcf3ce44SJohn Forte ndlp->nlp_DID); 484fcf3ce44SJohn Forte 485fcf3ce44SJohn Forte goto fail; 486fcf3ce44SJohn Forte } 487291a2b48SSukumar Swaminathan 488fcf3ce44SJohn Forte icmd = &iocbq->iocb; 489*82527734SSukumar Swaminathan icmd->ULPIOTAG = iotag; 490*82527734SSukumar Swaminathan icmd->ULPCONTEXT = ndlp->nlp_Rpi; 491*82527734SSukumar Swaminathan icmd->ULPLE = 1; 492*82527734SSukumar Swaminathan icmd->ULPCOMMAND = CMD_CREATE_XRI_CR; 493*82527734SSukumar Swaminathan icmd->ULPOWNER = OWN_CHIP; 494fcf3ce44SJohn Forte 495fcf3ce44SJohn Forte /* Initalize iocbq */ 496fcf3ce44SJohn Forte iocbq->port = (void *)port; 497fcf3ce44SJohn Forte iocbq->node = (void *)ndlp; 498*82527734SSukumar Swaminathan iocbq->channel = (void *)cp; 499fcf3ce44SJohn Forte 500fcf3ce44SJohn Forte mutex_enter(&sbp->mtx); 501fcf3ce44SJohn Forte sbp->node = (void *)ndlp; 502*82527734SSukumar Swaminathan sbp->channel = cp; 503fcf3ce44SJohn Forte mutex_exit(&sbp->mtx); 504fcf3ce44SJohn Forte 505fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, 506291a2b48SSukumar Swaminathan "create_xri sent: DID=0x%x Xri=0x%x iotag=0x%x", ndlp->nlp_DID, 507291a2b48SSukumar Swaminathan ndlp->nlp_Xri, iotag); 508fcf3ce44SJohn Forte 509*82527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq); 510fcf3ce44SJohn Forte 511fcf3ce44SJohn Forte return (0); 512fcf3ce44SJohn Forte 513fcf3ce44SJohn Forte fail: 514fcf3ce44SJohn Forte 515fcf3ce44SJohn Forte /* Clear the XRI flag */ 516*82527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 517*82527734SSukumar Swaminathan ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI; 518*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 519fcf3ce44SJohn Forte 520fcf3ce44SJohn Forte return (1); 521fcf3ce44SJohn Forte 522*82527734SSukumar Swaminathan } /* emlxs_create_xri() */ 523