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*a9800bebSGarrett D'Amore * Copyright 2011 Emulex. All rights reserved. 2482527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 2782527734SSukumar Swaminathan 28291a2b48SSukumar Swaminathan #include <emlxs.h> 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 31fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_ELS_C); 32fcf3ce44SJohn Forte 33291a2b48SSukumar Swaminathan static void emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp); 34*a9800bebSGarrett D'Amore static void emlxs_handle_sol_fdisc(emlxs_port_t *port, emlxs_buf_t *sbp); 35291a2b48SSukumar Swaminathan static void emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp); 36291a2b48SSukumar Swaminathan static void emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp); 37291a2b48SSukumar Swaminathan static void emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp); 38291a2b48SSukumar Swaminathan static void emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp); 39291a2b48SSukumar Swaminathan 4082527734SSukumar Swaminathan static void emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp, 41291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 4282527734SSukumar Swaminathan static void emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, 43291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 4482527734SSukumar Swaminathan static void emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, 45291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 4682527734SSukumar Swaminathan static void emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp, 47291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 4882527734SSukumar Swaminathan static void emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp, 49291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 5082527734SSukumar Swaminathan static void emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp, 51291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 5282527734SSukumar Swaminathan static void emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp, 53291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 5482527734SSukumar Swaminathan static void emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp, 55291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 5682527734SSukumar Swaminathan static void emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp, 57291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 58*a9800bebSGarrett D'Amore static void emlxs_handle_unsol_echo_cmd(emlxs_port_t *port, CHANNEL *cp, 59*a9800bebSGarrett D'Amore IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 60*a9800bebSGarrett D'Amore static void emlxs_handle_unsol_rtv_cmd(emlxs_port_t *port, CHANNEL *cp, 61*a9800bebSGarrett D'Amore IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 62*a9800bebSGarrett D'Amore static void emlxs_handle_unsol_rls_cmd(emlxs_port_t *port, CHANNEL *cp, 63*a9800bebSGarrett D'Amore IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 64291a2b48SSukumar Swaminathan static void emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, 65291a2b48SSukumar Swaminathan IOCBQ *iocbq, uint32_t flag); 66291a2b48SSukumar Swaminathan static void emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, 67291a2b48SSukumar Swaminathan IOCBQ *iocbq, uint32_t flag); 68*a9800bebSGarrett D'Amore 69*a9800bebSGarrett D'Amore #if (EMLXS_MODREV < EMLXS_MODREV4) 70291a2b48SSukumar Swaminathan static void emlxs_send_rsnn(emlxs_port_t *port); 71fcf3ce44SJohn Forte 72*a9800bebSGarrett D'Amore #endif /* < EMLXS_MODREV4 */ 73fcf3ce44SJohn Forte 74fcf3ce44SJohn Forte 75fcf3ce44SJohn Forte 76fcf3ce44SJohn Forte /* Routine Declaration - Local */ 77fcf3ce44SJohn Forte /* End Routine Declaration - Local */ 78fcf3ce44SJohn Forte 79fcf3ce44SJohn Forte /* 80fcf3ce44SJohn Forte * emlxs_els_handle_event 81fcf3ce44SJohn Forte * 82291a2b48SSukumar Swaminathan * Description: Process an ELS Response Ring cmpl 83fcf3ce44SJohn Forte * 84fcf3ce44SJohn Forte */ 85fcf3ce44SJohn Forte extern int 8682527734SSukumar Swaminathan emlxs_els_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 87fcf3ce44SJohn Forte { 88fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 89fcf3ce44SJohn Forte IOCB *iocb; 90fcf3ce44SJohn Forte emlxs_buf_t *sbp; 91fcf3ce44SJohn Forte fc_packet_t *pkt; 92fcf3ce44SJohn Forte uint32_t *lp0; 93fcf3ce44SJohn Forte uint32_t command; 94fcf3ce44SJohn Forte NODELIST *ndlp; 95fcf3ce44SJohn Forte uint32_t did; 96fcf3ce44SJohn Forte ELS_PKT *els; 97fcf3ce44SJohn Forte 98fcf3ce44SJohn Forte iocb = &iocbq->iocb; 99fcf3ce44SJohn Forte 100fcf3ce44SJohn Forte HBASTATS.ElsEvent++; 101fcf3ce44SJohn Forte 102fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 103fcf3ce44SJohn Forte 104fcf3ce44SJohn Forte if (!sbp) { 105fcf3ce44SJohn Forte /* 106fcf3ce44SJohn Forte * completion with missing xmit command 107fcf3ce44SJohn Forte */ 108fcf3ce44SJohn Forte HBASTATS.ElsStray++; 109fcf3ce44SJohn Forte 110fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg, 111fcf3ce44SJohn Forte "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x", 11282527734SSukumar Swaminathan iocbq, (uint32_t)iocb->ULPCOMMAND, 11382527734SSukumar Swaminathan (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS, 114291a2b48SSukumar Swaminathan iocb->un.ulpWord[4]); 115fcf3ce44SJohn Forte 116fcf3ce44SJohn Forte return (1); 117fcf3ce44SJohn Forte } 118291a2b48SSukumar Swaminathan 11982527734SSukumar Swaminathan if (cp->channelno != hba->channel_els) { 120fcf3ce44SJohn Forte HBASTATS.ElsStray++; 121fcf3ce44SJohn Forte 122fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg, 12382527734SSukumar Swaminathan "Not ELS channel: channel=%d iocbq=%p cmd=0x%x iotag=0x%x " 12482527734SSukumar Swaminathan "status=0x%x perr=0x%x", cp->channelno, iocbq, 12582527734SSukumar Swaminathan (uint32_t)iocb->ULPCOMMAND, (uint32_t)iocb->ULPIOTAG, 12682527734SSukumar Swaminathan iocb->ULPSTATUS, iocb->un.ulpWord[4]); 127fcf3ce44SJohn Forte 128fcf3ce44SJohn Forte return (1); 129fcf3ce44SJohn Forte } 130291a2b48SSukumar Swaminathan 131fcf3ce44SJohn Forte port = sbp->iocbq.port; 132fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 133fcf3ce44SJohn Forte lp0 = (uint32_t *)pkt->pkt_cmd; 134fcf3ce44SJohn Forte command = *lp0 & ELS_CMD_MASK; 13582527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 136fcf3ce44SJohn Forte 137fcf3ce44SJohn Forte /* Check if a response buffer was provided */ 138fcf3ce44SJohn Forte if (pkt->pkt_rsplen) { 13982527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen, 140fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 141fcf3ce44SJohn Forte } 142291a2b48SSukumar Swaminathan 14382527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) { 144291a2b48SSukumar Swaminathan /* 145291a2b48SSukumar Swaminathan * ELS Reply completion 146291a2b48SSukumar Swaminathan */ 147fcf3ce44SJohn Forte case CMD_XMIT_ELS_RSP_CX: 148fcf3ce44SJohn Forte case CMD_XMIT_ELS_RSP64_CX: 149fcf3ce44SJohn Forte 150fcf3ce44SJohn Forte HBASTATS.ElsRspCompleted++; 151fcf3ce44SJohn Forte 152fcf3ce44SJohn Forte if (command == ELS_CMD_ACC) { 153fcf3ce44SJohn Forte emlxs_handle_acc(port, sbp, iocbq, 1); 154fcf3ce44SJohn Forte } else { 155fcf3ce44SJohn Forte emlxs_handle_reject(port, sbp, iocbq, 1); 156fcf3ce44SJohn Forte } 157fcf3ce44SJohn Forte 158fcf3ce44SJohn Forte break; 159fcf3ce44SJohn Forte 160291a2b48SSukumar Swaminathan /* 161291a2b48SSukumar Swaminathan * ELS command completion 162291a2b48SSukumar Swaminathan */ 163fcf3ce44SJohn Forte case CMD_ELS_REQUEST_CR: 164fcf3ce44SJohn Forte case CMD_ELS_REQUEST64_CR: 165fcf3ce44SJohn Forte case CMD_ELS_REQUEST_CX: 166fcf3ce44SJohn Forte case CMD_ELS_REQUEST64_CX: 167fcf3ce44SJohn Forte 168fcf3ce44SJohn Forte HBASTATS.ElsCmdCompleted++; 169fcf3ce44SJohn Forte 170fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_ELS_RSP_VALID; 171fcf3ce44SJohn Forte 172fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_resp; 173fcf3ce44SJohn Forte 174fcf3ce44SJohn Forte pkt->pkt_resp_resid = 175fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->un.elsreq64.bdl.bdeSize; 176fcf3ce44SJohn Forte pkt->pkt_data_resid = pkt->pkt_datalen; 177fcf3ce44SJohn Forte 178fcf3ce44SJohn Forte pkt->pkt_resp_fhdr.d_id = pkt->pkt_cmd_fhdr.s_id; 179fcf3ce44SJohn Forte pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id; 180fcf3ce44SJohn Forte 18182527734SSukumar Swaminathan if ((iocb->ULPSTATUS == 0) && (els->elsCode == 0x02)) { 182fcf3ce44SJohn Forte HBASTATS.ElsCmdGood++; 183fcf3ce44SJohn Forte 184fcf3ce44SJohn Forte if (!(sbp->pkt_flags & PACKET_ALLOCATED)) { 185fcf3ce44SJohn Forte /* 186291a2b48SSukumar Swaminathan * ULP patch - ULP expects 187291a2b48SSukumar Swaminathan * resp_resid = 0 on success 188fcf3ce44SJohn Forte */ 189fcf3ce44SJohn Forte pkt->pkt_resp_resid = 0; 190fcf3ce44SJohn Forte } 191291a2b48SSukumar Swaminathan 192fcf3ce44SJohn Forte switch (command) { 193fcf3ce44SJohn Forte case ELS_CMD_FDISC: /* Fabric login */ 194*a9800bebSGarrett D'Amore emlxs_handle_sol_fdisc(port, sbp); 195fcf3ce44SJohn Forte 196fcf3ce44SJohn Forte break; 197fcf3ce44SJohn Forte 198fcf3ce44SJohn Forte case ELS_CMD_FLOGI: /* Fabric login */ 199fcf3ce44SJohn Forte emlxs_handle_sol_flogi(port, sbp); 200fcf3ce44SJohn Forte 201fcf3ce44SJohn Forte break; 202fcf3ce44SJohn Forte 203fcf3ce44SJohn Forte case ELS_CMD_PLOGI: /* NPort login */ 204fcf3ce44SJohn Forte emlxs_handle_sol_plogi(port, sbp); 205fcf3ce44SJohn Forte 206fcf3ce44SJohn Forte break; 207fcf3ce44SJohn Forte 208fcf3ce44SJohn Forte case ELS_CMD_ADISC: /* Adisc */ 209fcf3ce44SJohn Forte emlxs_handle_sol_adisc(port, sbp); 210fcf3ce44SJohn Forte 211fcf3ce44SJohn Forte break; 212fcf3ce44SJohn Forte 213fcf3ce44SJohn Forte case ELS_CMD_LOGO: /* Logout */ 214fcf3ce44SJohn Forte emlxs_handle_sol_logo(port, sbp); 215fcf3ce44SJohn Forte 216fcf3ce44SJohn Forte break; 217fcf3ce44SJohn Forte 218fcf3ce44SJohn Forte case ELS_CMD_PRLI: /* Process Log In */ 219fcf3ce44SJohn Forte emlxs_handle_sol_prli(port, sbp); 220fcf3ce44SJohn Forte 221fcf3ce44SJohn Forte break; 222fcf3ce44SJohn Forte 223fcf3ce44SJohn Forte default: 224fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 225291a2b48SSukumar Swaminathan &emlxs_els_completion_msg, "%s: did=%x", 226fcf3ce44SJohn Forte emlxs_elscmd_xlate(command), did); 227fcf3ce44SJohn Forte 228fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 229fcf3ce44SJohn Forte 230fcf3ce44SJohn Forte break; 231fcf3ce44SJohn Forte } 232fcf3ce44SJohn Forte 233fcf3ce44SJohn Forte } else { 234fcf3ce44SJohn Forte HBASTATS.ElsCmdError++; 235fcf3ce44SJohn Forte 236fcf3ce44SJohn Forte /* Look for LS_REJECT */ 23782527734SSukumar Swaminathan if (iocb->ULPSTATUS == IOSTAT_LS_RJT) { 238fcf3ce44SJohn Forte pkt->pkt_state = FC_PKT_LS_RJT; 239fcf3ce44SJohn Forte pkt->pkt_action = FC_ACTION_RETRYABLE; 240fcf3ce44SJohn Forte pkt->pkt_reason = iocb->un.grsp.perr.statRsn; 241fcf3ce44SJohn Forte pkt->pkt_expln = iocb->un.grsp.perr.statBaExp; 242fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_STATE_VALID; 243fcf3ce44SJohn Forte 244291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 245291a2b48SSukumar Swaminathan ndlp = emlxs_node_find_did(port, did); 246291a2b48SSukumar Swaminathan if (ndlp) { 247291a2b48SSukumar Swaminathan emlxs_log_sd_lsrjt_event(port, 248291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_portname, 249291a2b48SSukumar Swaminathan command, pkt->pkt_reason, 250291a2b48SSukumar Swaminathan pkt->pkt_expln); 251291a2b48SSukumar Swaminathan } 252291a2b48SSukumar Swaminathan #endif 253291a2b48SSukumar Swaminathan 254fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 255fcf3ce44SJohn Forte &emlxs_els_completion_msg, 256fcf3ce44SJohn Forte "%s Rejected: did=%x rsn=%x exp=%x", 257fcf3ce44SJohn Forte emlxs_elscmd_xlate(command), did, 258fcf3ce44SJohn Forte pkt->pkt_reason, pkt->pkt_expln); 25982527734SSukumar Swaminathan } else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) { 260fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 261fcf3ce44SJohn Forte &emlxs_bad_els_completion_msg, 262fcf3ce44SJohn Forte "%s: did=%x Local Reject. %s", 263fcf3ce44SJohn Forte emlxs_elscmd_xlate(command), did, 264291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 265291a2b48SSukumar Swaminathan statLocalError)); 266fcf3ce44SJohn Forte } else { 267fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 268fcf3ce44SJohn Forte &emlxs_bad_els_completion_msg, 269fcf3ce44SJohn Forte "%s: did=%x %s (%02x%02x%02x%02x)", 270fcf3ce44SJohn Forte emlxs_elscmd_xlate(command), did, 27182527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 272fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 273fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 274fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 275fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError); 276fcf3ce44SJohn Forte } 277fcf3ce44SJohn Forte 278fcf3ce44SJohn Forte switch (command) { 279fcf3ce44SJohn Forte case ELS_CMD_PLOGI: /* NPort login failed */ 280fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 281fcf3ce44SJohn Forte 282fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 283fcf3ce44SJohn Forte /* Open the node again */ 284fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, 28582527734SSukumar Swaminathan hba->channel_fcp); 286fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, 28782527734SSukumar Swaminathan hba->channel_ip); 288fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 289fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_LS_RJT) { 290fcf3ce44SJohn Forte emlxs_dhc_state(port, ndlp, 291fcf3ce44SJohn Forte NODE_STATE_NOCHANGE, 292fcf3ce44SJohn Forte pkt->pkt_reason, 293fcf3ce44SJohn Forte pkt->pkt_expln); 294fcf3ce44SJohn Forte } 295291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 296fcf3ce44SJohn Forte } 297291a2b48SSukumar Swaminathan 298fcf3ce44SJohn Forte break; 299fcf3ce44SJohn Forte 300fcf3ce44SJohn Forte 301fcf3ce44SJohn Forte case ELS_CMD_PRLI: /* Process Log In failed */ 302fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 303fcf3ce44SJohn Forte 304fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 305fcf3ce44SJohn Forte /* Open the node again */ 306fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, 30782527734SSukumar Swaminathan hba->channel_fcp); 308fcf3ce44SJohn Forte } 309291a2b48SSukumar Swaminathan 310fcf3ce44SJohn Forte break; 311fcf3ce44SJohn Forte 312fcf3ce44SJohn Forte case ELS_CMD_FDISC: /* Fabric login */ 313fcf3ce44SJohn Forte case ELS_CMD_FLOGI: /* Fabric login */ 314fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_LS_RJT) { 315291a2b48SSukumar Swaminathan /* This will cause ULP to retry */ 316291a2b48SSukumar Swaminathan /* FLOGI requests */ 317fcf3ce44SJohn Forte pkt->pkt_reason = FC_REASON_QFULL; 318fcf3ce44SJohn Forte pkt->pkt_expln = 0; 319fcf3ce44SJohn Forte 320fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 321fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 322fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 323fcf3ce44SJohn Forte emlxs_dhc_state(port, ndlp, 324fcf3ce44SJohn Forte NODE_STATE_NOCHANGE, 325fcf3ce44SJohn Forte pkt->pkt_reason, 326fcf3ce44SJohn Forte pkt->pkt_expln); 327fcf3ce44SJohn Forte } 328291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 329fcf3ce44SJohn Forte } 330291a2b48SSukumar Swaminathan 331*a9800bebSGarrett D'Amore if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 332*a9800bebSGarrett D'Amore (void) emlxs_vpi_logi_failed_notify( 333*a9800bebSGarrett D'Amore sbp->port); 334*a9800bebSGarrett D'Amore } 335*a9800bebSGarrett D'Amore 336fcf3ce44SJohn Forte break; 337fcf3ce44SJohn Forte 338fcf3ce44SJohn Forte default: 339fcf3ce44SJohn Forte break; 340fcf3ce44SJohn Forte } 341fcf3ce44SJohn Forte 34282527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 343fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 344fcf3ce44SJohn Forte } 345fcf3ce44SJohn Forte 346fcf3ce44SJohn Forte break; 347fcf3ce44SJohn Forte 348fcf3ce44SJohn Forte default: 349fcf3ce44SJohn Forte 350fcf3ce44SJohn Forte HBASTATS.ElsStray++; 351fcf3ce44SJohn Forte 352fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_els_msg, 35382527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND); 354fcf3ce44SJohn Forte 35582527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 356fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 357fcf3ce44SJohn Forte 358fcf3ce44SJohn Forte break; 35982527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */ 360fcf3ce44SJohn Forte 361fcf3ce44SJohn Forte return (0); 362fcf3ce44SJohn Forte 36382527734SSukumar Swaminathan } /* emlxs_els_handle_event() */ 364fcf3ce44SJohn Forte 365fcf3ce44SJohn Forte 366fcf3ce44SJohn Forte extern int 36782527734SSukumar Swaminathan emlxs_els_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 368fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 369fcf3ce44SJohn Forte { 370fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 371fcf3ce44SJohn Forte uint32_t cmd_code; 372*a9800bebSGarrett D'Amore IOCB *iocb; 373fcf3ce44SJohn Forte 374fcf3ce44SJohn Forte HBASTATS.ElsCmdReceived++; 375fcf3ce44SJohn Forte 376*a9800bebSGarrett D'Amore iocb = &iocbq->iocb; 377fcf3ce44SJohn Forte cmd_code = *((uint32_t *)mp->virt) & ELS_CMD_MASK; 378fcf3ce44SJohn Forte 37982527734SSukumar Swaminathan if (!(port->flag & EMLXS_PORT_BOUND)) { 380e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 381e2ca2865SSukumar Swaminathan "%s: sid=%x. Port not bound: Rejecting.", 382e2ca2865SSukumar Swaminathan emlxs_elscmd_xlate(cmd_code), 383e2ca2865SSukumar Swaminathan iocbq->iocb.un.elsreq.remoteID); 38482527734SSukumar Swaminathan 38582527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 386e2ca2865SSukumar Swaminathan cmd_code, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 38782527734SSukumar Swaminathan 38882527734SSukumar Swaminathan return (0); 38982527734SSukumar Swaminathan } 39082527734SSukumar Swaminathan 391fcf3ce44SJohn Forte switch (cmd_code) { 392fcf3ce44SJohn Forte case ELS_CMD_RSCN: 393fcf3ce44SJohn Forte HBASTATS.ElsRscnReceived++; 39482527734SSukumar Swaminathan emlxs_handle_unsol_rscn(port, cp, iocbq, mp, size); 395fcf3ce44SJohn Forte break; 396fcf3ce44SJohn Forte 397fcf3ce44SJohn Forte case ELS_CMD_FLOGI: 398fcf3ce44SJohn Forte HBASTATS.ElsFlogiReceived++; 39982527734SSukumar Swaminathan emlxs_handle_unsol_flogi(port, cp, iocbq, mp, size); 400fcf3ce44SJohn Forte break; 401fcf3ce44SJohn Forte 402fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 403fcf3ce44SJohn Forte HBASTATS.ElsPlogiReceived++; 40482527734SSukumar Swaminathan emlxs_handle_unsol_plogi(port, cp, iocbq, mp, size); 405fcf3ce44SJohn Forte break; 406fcf3ce44SJohn Forte 407fcf3ce44SJohn Forte case ELS_CMD_PRLI: 408fcf3ce44SJohn Forte HBASTATS.ElsPrliReceived++; 40982527734SSukumar Swaminathan emlxs_handle_unsol_prli(port, cp, iocbq, mp, size); 410fcf3ce44SJohn Forte break; 411fcf3ce44SJohn Forte 412fcf3ce44SJohn Forte case ELS_CMD_PRLO: 413fcf3ce44SJohn Forte HBASTATS.ElsPrloReceived++; 41482527734SSukumar Swaminathan emlxs_handle_unsol_prlo(port, cp, iocbq, mp, size); 415fcf3ce44SJohn Forte break; 416fcf3ce44SJohn Forte 417fcf3ce44SJohn Forte case ELS_CMD_LOGO: 418fcf3ce44SJohn Forte HBASTATS.ElsLogoReceived++; 41982527734SSukumar Swaminathan emlxs_handle_unsol_logo(port, cp, iocbq, mp, size); 420fcf3ce44SJohn Forte break; 421fcf3ce44SJohn Forte 422fcf3ce44SJohn Forte case ELS_CMD_ADISC: 423fcf3ce44SJohn Forte HBASTATS.ElsAdiscReceived++; 42482527734SSukumar Swaminathan emlxs_handle_unsol_adisc(port, cp, iocbq, mp, size); 425fcf3ce44SJohn Forte break; 426fcf3ce44SJohn Forte 427fcf3ce44SJohn Forte case ELS_CMD_AUTH: 428fcf3ce44SJohn Forte HBASTATS.ElsAuthReceived++; 42982527734SSukumar Swaminathan emlxs_handle_unsol_auth(port, cp, iocbq, mp, size); 430fcf3ce44SJohn Forte break; 431fcf3ce44SJohn Forte 432*a9800bebSGarrett D'Amore case ELS_CMD_TEST: 433*a9800bebSGarrett D'Amore HBASTATS.ElsTestReceived++; 434*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 435*a9800bebSGarrett D'Amore "%s: sid=%x. Dropping.", 436*a9800bebSGarrett D'Amore emlxs_elscmd_xlate(cmd_code), 437*a9800bebSGarrett D'Amore iocbq->iocb.un.elsreq.remoteID); 438*a9800bebSGarrett D'Amore 439*a9800bebSGarrett D'Amore /* drop it */ 440*a9800bebSGarrett D'Amore emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT); 441*a9800bebSGarrett D'Amore break; 442*a9800bebSGarrett D'Amore 443*a9800bebSGarrett D'Amore case ELS_CMD_ESTC: 444*a9800bebSGarrett D'Amore HBASTATS.ElsEstcReceived++; 445*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 446*a9800bebSGarrett D'Amore "%s: sid=%x. Dropping.", 447*a9800bebSGarrett D'Amore emlxs_elscmd_xlate(cmd_code), 448*a9800bebSGarrett D'Amore iocbq->iocb.un.elsreq.remoteID); 449*a9800bebSGarrett D'Amore 450*a9800bebSGarrett D'Amore /* drop it */ 451*a9800bebSGarrett D'Amore emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT); 452*a9800bebSGarrett D'Amore break; 453*a9800bebSGarrett D'Amore 454*a9800bebSGarrett D'Amore case ELS_CMD_FARPR: 455*a9800bebSGarrett D'Amore HBASTATS.ElsFarprReceived++; 456*a9800bebSGarrett D'Amore 457*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 458*a9800bebSGarrett D'Amore "%s: sid=%x. Dropping.", 459*a9800bebSGarrett D'Amore emlxs_elscmd_xlate(cmd_code), 460*a9800bebSGarrett D'Amore iocbq->iocb.un.elsreq.remoteID); 461*a9800bebSGarrett D'Amore 462*a9800bebSGarrett D'Amore /* drop it */ 463*a9800bebSGarrett D'Amore emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT); 464*a9800bebSGarrett D'Amore break; 465*a9800bebSGarrett D'Amore 466*a9800bebSGarrett D'Amore case ELS_CMD_ECHO: 467*a9800bebSGarrett D'Amore HBASTATS.ElsEchoReceived++; 468*a9800bebSGarrett D'Amore emlxs_handle_unsol_echo_cmd(port, cp, iocbq, mp, size); 469*a9800bebSGarrett D'Amore break; 470*a9800bebSGarrett D'Amore 471*a9800bebSGarrett D'Amore case ELS_CMD_RLS: 472*a9800bebSGarrett D'Amore HBASTATS.ElsRlsReceived++; 473*a9800bebSGarrett D'Amore emlxs_handle_unsol_rls_cmd(port, cp, iocbq, mp, size); 474*a9800bebSGarrett D'Amore break; 475*a9800bebSGarrett D'Amore 476*a9800bebSGarrett D'Amore case ELS_CMD_RTV: 477*a9800bebSGarrett D'Amore HBASTATS.ElsRtvReceived++; 478*a9800bebSGarrett D'Amore emlxs_handle_unsol_rtv_cmd(port, cp, iocbq, mp, size); 479*a9800bebSGarrett D'Amore break; 480*a9800bebSGarrett D'Amore 481*a9800bebSGarrett D'Amore case ELS_CMD_ABTX: 482*a9800bebSGarrett D'Amore case ELS_CMD_RCS: 483*a9800bebSGarrett D'Amore case ELS_CMD_RES: 484*a9800bebSGarrett D'Amore case ELS_CMD_RSS: 485*a9800bebSGarrett D'Amore case ELS_CMD_RSI: 486*a9800bebSGarrett D'Amore case ELS_CMD_ESTS: 487*a9800bebSGarrett D'Amore case ELS_CMD_RRQ: 488*a9800bebSGarrett D'Amore case ELS_CMD_REC: 489*a9800bebSGarrett D'Amore HBASTATS.ElsGenReceived++; 490*a9800bebSGarrett D'Amore 491*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 492*a9800bebSGarrett D'Amore "%s: sid=%x. Rejecting.", 493*a9800bebSGarrett D'Amore emlxs_elscmd_xlate(cmd_code), 494*a9800bebSGarrett D'Amore iocbq->iocb.un.elsreq.remoteID); 495*a9800bebSGarrett D'Amore 496*a9800bebSGarrett D'Amore (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 497*a9800bebSGarrett D'Amore LSRJT_CMD_UNSUPPORTED, LSEXP_NOTHING_MORE); 498*a9800bebSGarrett D'Amore break; 499*a9800bebSGarrett D'Amore 500fcf3ce44SJohn Forte default: 501fcf3ce44SJohn Forte HBASTATS.ElsGenReceived++; 50282527734SSukumar Swaminathan emlxs_handle_unsol_gen_cmd(port, cp, iocbq, mp, size); 503fcf3ce44SJohn Forte break; 504fcf3ce44SJohn Forte } 505fcf3ce44SJohn Forte 506fcf3ce44SJohn Forte return (0); 507fcf3ce44SJohn Forte 50882527734SSukumar Swaminathan } /* emlxs_els_handle_unsol_req() */ 509fcf3ce44SJohn Forte 510fcf3ce44SJohn Forte 511fcf3ce44SJohn Forte static void 512fcf3ce44SJohn Forte emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp) 513fcf3ce44SJohn Forte { 514fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 515fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 516fcf3ce44SJohn Forte emlxs_port_t *vport; 517fcf3ce44SJohn Forte SERV_PARM *sp; 518fcf3ce44SJohn Forte fc_packet_t *pkt; 519fcf3ce44SJohn Forte MAILBOXQ *mbox; 520fcf3ce44SJohn Forte uint32_t did; 521fcf3ce44SJohn Forte IOCBQ *iocbq; 522fcf3ce44SJohn Forte IOCB *iocb; 523fcf3ce44SJohn Forte char buffer[64]; 524fcf3ce44SJohn Forte uint32_t i; 52582527734SSukumar Swaminathan int rc; 526*a9800bebSGarrett D'Amore uint16_t altBbCredit; 527fcf3ce44SJohn Forte 528fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 529fcf3ce44SJohn Forte sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t)); 53082527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 531fcf3ce44SJohn Forte iocbq = &sbp->iocbq; 532fcf3ce44SJohn Forte iocb = &iocbq->iocb; 533fcf3ce44SJohn Forte 534*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_PORT_LOCK); 535fcf3ce44SJohn Forte 536*a9800bebSGarrett D'Amore /* Save the fabric service parameters and did */ 537*a9800bebSGarrett D'Amore port->did = iocb->un.elsreq.myID; 538*a9800bebSGarrett D'Amore bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM)); 539*a9800bebSGarrett D'Amore 540*a9800bebSGarrett D'Amore if (sp->cmn.fPort) { 541fcf3ce44SJohn Forte hba->flag |= FC_FABRIC_ATTACHED; 542fcf3ce44SJohn Forte hba->flag &= ~FC_PT_TO_PT; 543fcf3ce44SJohn Forte 54482527734SSukumar Swaminathan pkt->pkt_resp_fhdr.s_id = LE_SWAP24_LO(FABRIC_DID); 54582527734SSukumar Swaminathan pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did); 546fcf3ce44SJohn Forte 547fcf3ce44SJohn Forte /* Save E_D_TOV ticks in nanoseconds */ 548fcf3ce44SJohn Forte if (sp->cmn.edtovResolution) { 549fcf3ce44SJohn Forte hba->fc_edtov = 55082527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000; 551fcf3ce44SJohn Forte } else { 55282527734SSukumar Swaminathan hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov); 553fcf3ce44SJohn Forte } 554fcf3ce44SJohn Forte 555fcf3ce44SJohn Forte /* Save R_A_TOV ticks */ 556291a2b48SSukumar Swaminathan hba->fc_ratov = 55782527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000; 558fcf3ce44SJohn Forte 559*a9800bebSGarrett D'Amore /* 560*a9800bebSGarrett D'Amore * If we are a N-port connected to a Fabric, 561*a9800bebSGarrett D'Amore * fixup sparam's so logins to devices on remote 562*a9800bebSGarrett D'Amore * loops work. 563*a9800bebSGarrett D'Amore */ 564*a9800bebSGarrett D'Amore altBbCredit = (hba->topology != TOPOLOGY_LOOP)? 1:0; 565*a9800bebSGarrett D'Amore hba->sparam.cmn.altBbCredit = altBbCredit; 566fcf3ce44SJohn Forte 567*a9800bebSGarrett D'Amore /* Set this bit in all the port sparam copies */ 568*a9800bebSGarrett D'Amore for (i = 0; i < MAX_VPORTS; i++) { 569*a9800bebSGarrett D'Amore vport = &VPORT(i); 570291a2b48SSukumar Swaminathan 571*a9800bebSGarrett D'Amore if (!(vport->flag & EMLXS_PORT_BOUND)) { 572*a9800bebSGarrett D'Amore continue; 573fcf3ce44SJohn Forte } 574*a9800bebSGarrett D'Amore 575*a9800bebSGarrett D'Amore vport->sparam.cmn.altBbCredit = altBbCredit; 576fcf3ce44SJohn Forte } 57782527734SSukumar Swaminathan 578fcf3ce44SJohn Forte if (sp->cmn.rspMultipleNPort) { 579fcf3ce44SJohn Forte hba->flag |= FC_NPIV_SUPPORTED; 580fcf3ce44SJohn Forte 581fcf3ce44SJohn Forte if (cfg[CFG_NPIV_DELAY].current) { 582fcf3ce44SJohn Forte /* 583291a2b48SSukumar Swaminathan * PATCH: for NPIV support on 584291a2b48SSukumar Swaminathan * Brocade switch firmware 5.10b 585fcf3ce44SJohn Forte */ 586fcf3ce44SJohn Forte if ((hba->flag & FC_NPIV_ENABLED) && 587fcf3ce44SJohn Forte ((sp->nodeName.IEEE[0] == 0x00) && 588fcf3ce44SJohn Forte (sp->nodeName.IEEE[1] == 0x05) && 589fcf3ce44SJohn Forte (sp->nodeName.IEEE[2] == 0x1e))) { 590fcf3ce44SJohn Forte hba->flag |= FC_NPIV_DELAY_REQUIRED; 591fcf3ce44SJohn Forte } 592fcf3ce44SJohn Forte } 593fcf3ce44SJohn Forte } else { 594fcf3ce44SJohn Forte hba->flag |= FC_NPIV_UNSUPPORTED; 595fcf3ce44SJohn Forte } 596fcf3ce44SJohn Forte 597fcf3ce44SJohn Forte if (!(hba->flag & FC_NPIV_ENABLED)) { 598fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Disabled "); 599fcf3ce44SJohn Forte } else if (hba->flag & FC_NPIV_SUPPORTED) { 600fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Supported "); 601fcf3ce44SJohn Forte } else { 602fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Unsupported "); 603fcf3ce44SJohn Forte } 604fcf3ce44SJohn Forte 605fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 606fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 607fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 608fcf3ce44SJohn Forte } else if (cfg[CFG_AUTH_ENABLE].current && 609fcf3ce44SJohn Forte (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) { 610fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 611fcf3ce44SJohn Forte } else { 612fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 613fcf3ce44SJohn Forte } 614291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 615fcf3ce44SJohn Forte 616fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 617fcf3ce44SJohn Forte 618fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 619291a2b48SSukumar Swaminathan "FLOGI: did=%x sid=%x %s", did, port->did, buffer); 620fcf3ce44SJohn Forte 621*a9800bebSGarrett D'Amore if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 622*a9800bebSGarrett D'Amore /* Deferred completion */ 623*a9800bebSGarrett D'Amore (void) emlxs_vpi_logi_cmpl_notify(sbp->port, sbp); 624*a9800bebSGarrett D'Amore return; 625*a9800bebSGarrett D'Amore } 626*a9800bebSGarrett D'Amore 62782527734SSukumar Swaminathan if (!(mbox = (MAILBOXQ *)emlxs_mem_get(hba, 62882527734SSukumar Swaminathan MEM_MBOX, 1))) { 62982527734SSukumar Swaminathan emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 63082527734SSukumar Swaminathan IOERR_NO_RESOURCES, 1); 63182527734SSukumar Swaminathan return; 63282527734SSukumar Swaminathan } 63382527734SSukumar Swaminathan 634*a9800bebSGarrett D'Amore /* Update our service parms */ 63582527734SSukumar Swaminathan emlxs_mb_config_link(hba, mbox); 63682527734SSukumar Swaminathan 63782527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0); 63882527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 639*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbox); 640fcf3ce44SJohn Forte } 641291a2b48SSukumar Swaminathan 642fcf3ce44SJohn Forte /* Preset the state for the reg_did */ 643fcf3ce44SJohn Forte emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 644fcf3ce44SJohn Forte 64582527734SSukumar Swaminathan if (emlxs_mb_reg_did(port, FABRIC_DID, &port->fabric_sparam, 646fcf3ce44SJohn Forte sbp, NULL, NULL) == 0) { 647291a2b48SSukumar Swaminathan /* Deferred completion of this pkt until */ 648291a2b48SSukumar Swaminathan /* login is complete */ 649fcf3ce44SJohn Forte return; 650fcf3ce44SJohn Forte } 651291a2b48SSukumar Swaminathan 652fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 653fcf3ce44SJohn Forte IOERR_NO_RESOURCES, 1); 654fcf3ce44SJohn Forte 655fcf3ce44SJohn Forte } else { /* No switch */ 656291a2b48SSukumar Swaminathan 657fcf3ce44SJohn Forte hba->flag &= ~FC_FABRIC_ATTACHED; 658fcf3ce44SJohn Forte hba->flag |= FC_PT_TO_PT; 659fcf3ce44SJohn Forte 660fcf3ce44SJohn Forte /* Save E_D_TOV ticks in nanoseconds */ 661fcf3ce44SJohn Forte if (sp->cmn.edtovResolution) { 662fcf3ce44SJohn Forte hba->fc_edtov = 66382527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000; 664fcf3ce44SJohn Forte } else { 66582527734SSukumar Swaminathan hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov); 666fcf3ce44SJohn Forte } 667fcf3ce44SJohn Forte 668fcf3ce44SJohn Forte /* Save R_A_TOV ticks */ 669291a2b48SSukumar Swaminathan hba->fc_ratov = 67082527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000; 671fcf3ce44SJohn Forte 672fcf3ce44SJohn Forte hba->flag &= ~FC_NPIV_SUPPORTED; 673fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Disabled. P2P"); 67482527734SSukumar Swaminathan 67582527734SSukumar Swaminathan port->rdid = did; 676fcf3ce44SJohn Forte 677fcf3ce44SJohn Forte /* Clear the fabric service parameters */ 678fcf3ce44SJohn Forte bzero((void *)&port->fabric_sparam, sizeof (SERV_PARM)); 679fcf3ce44SJohn Forte 680fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 681fcf3ce44SJohn Forte 682fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 683291a2b48SSukumar Swaminathan "FLOGI: did=%x sid=%x %s", did, port->did, buffer); 684fcf3ce44SJohn Forte 685fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 686fcf3ce44SJohn Forte } 687fcf3ce44SJohn Forte 688fcf3ce44SJohn Forte return; 689fcf3ce44SJohn Forte 69082527734SSukumar Swaminathan } /* emlxs_handle_sol_flogi() */ 691fcf3ce44SJohn Forte 692fcf3ce44SJohn Forte 693fcf3ce44SJohn Forte static void 694*a9800bebSGarrett D'Amore emlxs_handle_sol_fdisc(emlxs_port_t *port, emlxs_buf_t *sbp) 695fcf3ce44SJohn Forte { 696fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 697fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 698fcf3ce44SJohn Forte SERV_PARM *sp; 699fcf3ce44SJohn Forte fc_packet_t *pkt; 700fcf3ce44SJohn Forte MAILBOXQ *mbox; 701fcf3ce44SJohn Forte uint32_t did; 702fcf3ce44SJohn Forte IOCBQ *iocbq; 703fcf3ce44SJohn Forte IOCB *iocb; 704fcf3ce44SJohn Forte char buffer[64]; 70582527734SSukumar Swaminathan int rc; 706fcf3ce44SJohn Forte 707fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 708fcf3ce44SJohn Forte sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t)); 70982527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 710fcf3ce44SJohn Forte iocbq = &sbp->iocbq; 711fcf3ce44SJohn Forte iocb = &iocbq->iocb; 712fcf3ce44SJohn Forte 713fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 714fcf3ce44SJohn Forte 715*a9800bebSGarrett D'Amore /* Save the fabric service parameters and did */ 716fcf3ce44SJohn Forte port->did = iocb->un.elsreq.myID; 717fcf3ce44SJohn Forte bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM)); 718fcf3ce44SJohn Forte 719*a9800bebSGarrett D'Amore pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did); 720*a9800bebSGarrett D'Amore 721fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 722fcf3ce44SJohn Forte 723fcf3ce44SJohn Forte buffer[0] = 0; 724fcf3ce44SJohn Forte 725fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 726fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 727fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 728291a2b48SSukumar Swaminathan } else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_NPIV].current) { 729fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 730fcf3ce44SJohn Forte } else { 731fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 732fcf3ce44SJohn Forte } 733291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 734fcf3ce44SJohn Forte 735fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 736*a9800bebSGarrett D'Amore "FDISC: did=%x sid=%x %s", did, port->did, buffer); 737fcf3ce44SJohn Forte 73882527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 739*a9800bebSGarrett D'Amore (void) emlxs_vpi_logi_cmpl_notify(sbp->port, sbp); 74082527734SSukumar Swaminathan return; 74182527734SSukumar Swaminathan } 74282527734SSukumar Swaminathan 743fcf3ce44SJohn Forte /* Update our service parms */ 74482527734SSukumar Swaminathan if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) { 74582527734SSukumar Swaminathan emlxs_mb_config_link(hba, mbox); 746fcf3ce44SJohn Forte 74782527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, 74882527734SSukumar Swaminathan MBX_NOWAIT, 0); 74982527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 750*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbox); 751fcf3ce44SJohn Forte } 752fcf3ce44SJohn Forte } 753291a2b48SSukumar Swaminathan 754fcf3ce44SJohn Forte /* Preset the state for the reg_did */ 755fcf3ce44SJohn Forte emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 756fcf3ce44SJohn Forte 75782527734SSukumar Swaminathan if (emlxs_mb_reg_did(port, FABRIC_DID, &port->fabric_sparam, sbp, 758fcf3ce44SJohn Forte NULL, NULL) == 0) { 759fcf3ce44SJohn Forte /* 760fcf3ce44SJohn Forte * Deferred completion of this pkt until login is complete 761fcf3ce44SJohn Forte */ 762fcf3ce44SJohn Forte 763fcf3ce44SJohn Forte return; 764fcf3ce44SJohn Forte } 765291a2b48SSukumar Swaminathan 766fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1); 767fcf3ce44SJohn Forte 768fcf3ce44SJohn Forte return; 769fcf3ce44SJohn Forte 770*a9800bebSGarrett D'Amore } /* emlxs_handle_sol_fdisc() */ 771fcf3ce44SJohn Forte 772fcf3ce44SJohn Forte 773fcf3ce44SJohn Forte static void 774fcf3ce44SJohn Forte emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp) 775fcf3ce44SJohn Forte { 776fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 777fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 778fcf3ce44SJohn Forte SERV_PARM *sp; 779fcf3ce44SJohn Forte fc_packet_t *pkt; 780fcf3ce44SJohn Forte uint32_t did; 781fcf3ce44SJohn Forte uint32_t sid; 782fcf3ce44SJohn Forte NODELIST *ndlp; 783fcf3ce44SJohn Forte char buffer[64]; 784fcf3ce44SJohn Forte 785fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 786fcf3ce44SJohn Forte sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t)); 78782527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 78882527734SSukumar Swaminathan sid = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.s_id); 789fcf3ce44SJohn Forte 790fcf3ce44SJohn Forte buffer[0] = 0; 791fcf3ce44SJohn Forte 792fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 793fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 794fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 795fcf3ce44SJohn Forte } else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current && 796fcf3ce44SJohn Forte (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) { 797fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 798fcf3ce44SJohn Forte } else { 799fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 800fcf3ce44SJohn Forte } 801291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 802fcf3ce44SJohn Forte 803fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 804291a2b48SSukumar Swaminathan "PLOGI: sid=%x did=%x %s", sid, did, buffer); 805fcf3ce44SJohn Forte 806fcf3ce44SJohn Forte /* Preset the pkt state for reg_did */ 807fcf3ce44SJohn Forte emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 808fcf3ce44SJohn Forte 809fcf3ce44SJohn Forte /* 810fcf3ce44SJohn Forte * Do register login to Firmware before calling packet completion 811fcf3ce44SJohn Forte */ 812fcf3ce44SJohn Forte if (emlxs_mb_reg_did(port, did, sp, sbp, NULL, NULL) == 0) { 813fcf3ce44SJohn Forte /* 814fcf3ce44SJohn Forte * Deferred completion of this pkt until login is complete 815fcf3ce44SJohn Forte */ 816fcf3ce44SJohn Forte return; 817fcf3ce44SJohn Forte } 818291a2b48SSukumar Swaminathan 819fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 820fcf3ce44SJohn Forte 821fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 822fcf3ce44SJohn Forte /* Open the node again */ 82382527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 82482527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_ip); 825fcf3ce44SJohn Forte } 826291a2b48SSukumar Swaminathan 827fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1); 828fcf3ce44SJohn Forte 829fcf3ce44SJohn Forte return; 830fcf3ce44SJohn Forte 83182527734SSukumar Swaminathan } /* emlxs_handle_sol_plogi() */ 832fcf3ce44SJohn Forte 833fcf3ce44SJohn Forte 834fcf3ce44SJohn Forte static void 835fcf3ce44SJohn Forte emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp) 836fcf3ce44SJohn Forte { 83782527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 838fcf3ce44SJohn Forte fc_packet_t *pkt; 839fcf3ce44SJohn Forte uint32_t did; 840fcf3ce44SJohn Forte NODELIST *ndlp; 841fcf3ce44SJohn Forte 842fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 84382527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 844fcf3ce44SJohn Forte 845291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "ADISC: did=%x", 846fcf3ce44SJohn Forte did); 847fcf3ce44SJohn Forte 848fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 849fcf3ce44SJohn Forte 850fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 851fcf3ce44SJohn Forte /* Open the node again */ 85282527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 85382527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_ip); 85482527734SSukumar Swaminathan 85582527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 856*a9800bebSGarrett D'Amore 857*a9800bebSGarrett D'Amore emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 858*a9800bebSGarrett D'Amore 859*a9800bebSGarrett D'Amore if (emlxs_rpi_resume_notify(port, 860*a9800bebSGarrett D'Amore ndlp->rpip, sbp) == 0) { 86182527734SSukumar Swaminathan /* 86282527734SSukumar Swaminathan * Delay ADISC cmpl to ULP till 86382527734SSukumar Swaminathan * after RESUME_RPI 86482527734SSukumar Swaminathan */ 86582527734SSukumar Swaminathan return; 86682527734SSukumar Swaminathan } 86782527734SSukumar Swaminathan } 868fcf3ce44SJohn Forte } 869291a2b48SSukumar Swaminathan 870fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 871fcf3ce44SJohn Forte 872fcf3ce44SJohn Forte return; 873fcf3ce44SJohn Forte 87482527734SSukumar Swaminathan } /* emlxs_handle_sol_adisc() */ 875fcf3ce44SJohn Forte 876fcf3ce44SJohn Forte 877fcf3ce44SJohn Forte static void 878fcf3ce44SJohn Forte emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp) 879fcf3ce44SJohn Forte { 880fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 881fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 882fcf3ce44SJohn Forte fc_packet_t *pkt; 883fcf3ce44SJohn Forte NODELIST *ndlp; 884fcf3ce44SJohn Forte uint32_t did; 885fcf3ce44SJohn Forte PRLI *npr; 886fcf3ce44SJohn Forte uint32_t task_retry_id; 887fcf3ce44SJohn Forte 888fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 889fcf3ce44SJohn Forte npr = (PRLI *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t)); 89082527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 891fcf3ce44SJohn Forte 892fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 893fcf3ce44SJohn Forte 894fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 895fcf3ce44SJohn Forte /* Check for FCP support */ 896fcf3ce44SJohn Forte if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) && 897fcf3ce44SJohn Forte (npr->prliType == PRLI_FCP_TYPE)) { 898*a9800bebSGarrett D'Amore /* Clear FCP2 support if no ADISC support requested */ 899*a9800bebSGarrett D'Amore if (cfg[CFG_ADISC_SUPPORT].current == 0) { 900*a9800bebSGarrett D'Amore npr->ConfmComplAllowed = 0; 901*a9800bebSGarrett D'Amore npr->TaskRetryIdReq = 0; 902*a9800bebSGarrett D'Amore npr->Retry = 0; 903*a9800bebSGarrett D'Amore } 904*a9800bebSGarrett D'Amore 905fcf3ce44SJohn Forte /* Check for target */ 906fcf3ce44SJohn Forte if (npr->targetFunc) { 907fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE; 908fcf3ce44SJohn Forte } else { 909fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE; 910fcf3ce44SJohn Forte } 911fcf3ce44SJohn Forte 912fcf3ce44SJohn Forte /* Check for initiator */ 913fcf3ce44SJohn Forte if (npr->initiatorFunc) { 914fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE; 915fcf3ce44SJohn Forte } else { 916fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE; 917fcf3ce44SJohn Forte } 918fcf3ce44SJohn Forte 919291a2b48SSukumar Swaminathan /* If TRI support is not required then force */ 920291a2b48SSukumar Swaminathan /* the task_retry_id value to one */ 921fcf3ce44SJohn Forte if (cfg[CFG_TRI_REQUIRED].current == 0) { 922fcf3ce44SJohn Forte task_retry_id = 1; 923fcf3ce44SJohn Forte } else { 924fcf3ce44SJohn Forte task_retry_id = npr->TaskRetryIdReq; 925fcf3ce44SJohn Forte } 926fcf3ce44SJohn Forte 927fcf3ce44SJohn Forte /* Check for FCP2 target support */ 928fcf3ce44SJohn Forte /* Retry and TaskRetryId bits are both required here */ 929fcf3ce44SJohn Forte if (npr->targetFunc && npr->Retry && task_retry_id) { 930fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; 931fcf3ce44SJohn Forte } else { 932fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; 933fcf3ce44SJohn Forte } 934fcf3ce44SJohn Forte } 935291a2b48SSukumar Swaminathan 936fcf3ce44SJohn Forte /* Open the node again */ 93782527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 938fcf3ce44SJohn Forte 939fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 940291a2b48SSukumar Swaminathan "PRLI: did=%x info=%02x", did, ndlp->nlp_fcp_info); 941fcf3ce44SJohn Forte 942fcf3ce44SJohn Forte /* 943fcf3ce44SJohn Forte * Report PRLI completion 944fcf3ce44SJohn Forte */ 945fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 946fcf3ce44SJohn Forte 947fcf3ce44SJohn Forte } else { 948fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 949291a2b48SSukumar Swaminathan "PRLI: did=%x: Node not found. Failing.", did); 950fcf3ce44SJohn Forte 951fcf3ce44SJohn Forte /* 952fcf3ce44SJohn Forte * Report PRLI failed 953fcf3ce44SJohn Forte */ 954fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 955fcf3ce44SJohn Forte IOERR_INVALID_RPI, 1); 956fcf3ce44SJohn Forte } 957fcf3ce44SJohn Forte return; 958fcf3ce44SJohn Forte 95982527734SSukumar Swaminathan } /* emlxs_handle_sol_prli() */ 960fcf3ce44SJohn Forte 961fcf3ce44SJohn Forte 962fcf3ce44SJohn Forte static void 963fcf3ce44SJohn Forte emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp) 964fcf3ce44SJohn Forte { 96582527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 966fcf3ce44SJohn Forte fc_packet_t *pkt; 967fcf3ce44SJohn Forte uint32_t did; 968fcf3ce44SJohn Forte NODELIST *ndlp; 969fcf3ce44SJohn Forte 970fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 97182527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 972fcf3ce44SJohn Forte 973291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "LOGO: did=%x", 974fcf3ce44SJohn Forte did); 975fcf3ce44SJohn Forte 976fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 977fcf3ce44SJohn Forte 978fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 979fcf3ce44SJohn Forte /* Close the node for any further normal IO */ 98082527734SSukumar Swaminathan emlxs_node_close(port, ndlp, hba->channel_fcp, 60); 98182527734SSukumar Swaminathan emlxs_node_close(port, ndlp, hba->channel_ip, 60); 982fcf3ce44SJohn Forte 983fcf3ce44SJohn Forte /* Flush tx queues */ 984fcf3ce44SJohn Forte (void) emlxs_tx_node_flush(port, ndlp, 0, 0, 0); 985fcf3ce44SJohn Forte 986fcf3ce44SJohn Forte /* Flush chip queues */ 987fcf3ce44SJohn Forte (void) emlxs_chipq_node_flush(port, 0, ndlp, 0); 988fcf3ce44SJohn Forte } 989291a2b48SSukumar Swaminathan 990fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 991fcf3ce44SJohn Forte 992fcf3ce44SJohn Forte return; 993fcf3ce44SJohn Forte 99482527734SSukumar Swaminathan } /* emlxs_handle_sol_logo() */ 995fcf3ce44SJohn Forte 996fcf3ce44SJohn Forte 997fcf3ce44SJohn Forte /* ARGSUSED */ 998fcf3ce44SJohn Forte static void 99982527734SSukumar Swaminathan emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1000fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1001fcf3ce44SJohn Forte { 1002fcf3ce44SJohn Forte uint32_t *lp; 1003fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1004fcf3ce44SJohn Forte uint8_t *bp; 1005fcf3ce44SJohn Forte IOCB *iocb; 1006fcf3ce44SJohn Forte uint32_t count; 1007fcf3ce44SJohn Forte uint32_t sid; 1008fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1009fcf3ce44SJohn Forte 1010fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1011fcf3ce44SJohn Forte bp = mp->virt; 1012291a2b48SSukumar Swaminathan lp = (uint32_t *)bp + 1; 1013fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1014fcf3ce44SJohn Forte 1015291a2b48SSukumar Swaminathan /* Log the legacy rscn event for physical port only */ 1016291a2b48SSukumar Swaminathan if (port->vpi == 0) { 1017291a2b48SSukumar Swaminathan emlxs_log_rscn_event(port, bp, size); 1018291a2b48SSukumar Swaminathan } 1019291a2b48SSukumar Swaminathan 1020291a2b48SSukumar Swaminathan /* Log the vport rscn event for all ports */ 1021291a2b48SSukumar Swaminathan emlxs_log_vportrscn_event(port, bp, size); 1022fcf3ce44SJohn Forte 1023fcf3ce44SJohn Forte count = ((size - 4) / 4); 1024fcf3ce44SJohn Forte 1025fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 1); 1026fcf3ce44SJohn Forte 1027fcf3ce44SJohn Forte if (ubp == NULL) { 1028fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1029fcf3ce44SJohn Forte "RSCN rcvd: sid=%x %d page(s): %08X, %08X. Rejecting.", 103082527734SSukumar Swaminathan sid, count, LE_SWAP32(*lp), 103182527734SSukumar Swaminathan ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0)); 1032fcf3ce44SJohn Forte 1033fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1034291a2b48SSukumar Swaminathan ELS_CMD_RSCN, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1035fcf3ce44SJohn Forte 1036fcf3ce44SJohn Forte goto drop_it; 1037fcf3ce44SJohn Forte } 1038291a2b48SSukumar Swaminathan 1039fcf3ce44SJohn Forte bcopy(bp, ubp->ub_buffer, size); 1040fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1041fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_RSCN; 1042fcf3ce44SJohn Forte 1043fcf3ce44SJohn Forte /* 1044fcf3ce44SJohn Forte * Setup frame header 1045fcf3ce44SJohn Forte */ 1046fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1047fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 104882527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 104982527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1050fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 105182527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1052fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1053fcf3ce44SJohn Forte 1054fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1055291a2b48SSukumar Swaminathan "RSCN: sid=%x %d page(s): %08X, %08X buffer=%p token=%x.", sid, 105682527734SSukumar Swaminathan count, LE_SWAP32(*lp), 105782527734SSukumar Swaminathan ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0), ubp, ub_priv->token); 1058fcf3ce44SJohn Forte 1059fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1060fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1061291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1062fcf3ce44SJohn Forte 1063fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1064fcf3ce44SJohn Forte 1065fcf3ce44SJohn Forte drop_it: 1066fcf3ce44SJohn Forte 1067fcf3ce44SJohn Forte return; 1068fcf3ce44SJohn Forte 106982527734SSukumar Swaminathan } /* emlxs_handle_unsol_rscn() */ 1070fcf3ce44SJohn Forte 1071fcf3ce44SJohn Forte 1072fcf3ce44SJohn Forte /* This is shared by FCT driver */ 1073fcf3ce44SJohn Forte extern uint32_t 1074291a2b48SSukumar Swaminathan emlxs_process_unsol_flogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp, 1075291a2b48SSukumar Swaminathan uint32_t size, char *buffer) 1076fcf3ce44SJohn Forte { 1077fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1078fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1079fcf3ce44SJohn Forte uint8_t *bp; 1080fcf3ce44SJohn Forte IOCB *iocb; 1081fcf3ce44SJohn Forte uint32_t sid; 1082fcf3ce44SJohn Forte SERV_PARM *sp; 1083fcf3ce44SJohn Forte 1084fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1085fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1086fcf3ce44SJohn Forte 1087fcf3ce44SJohn Forte /* Check payload size */ 1088fcf3ce44SJohn Forte if (size < (sizeof (SERV_PARM) + 4)) { 1089fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1090291a2b48SSukumar Swaminathan "FLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid, 1091291a2b48SSukumar Swaminathan size, (sizeof (SERV_PARM) + 4)); 1092fcf3ce44SJohn Forte 1093fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1094fcf3ce44SJohn Forte ELS_CMD_FLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE); 1095fcf3ce44SJohn Forte 1096fcf3ce44SJohn Forte return (1); 1097fcf3ce44SJohn Forte } 1098291a2b48SSukumar Swaminathan 1099fcf3ce44SJohn Forte bp = mp->virt; 1100fcf3ce44SJohn Forte sp = (SERV_PARM *)(bp + sizeof (uint32_t)); 1101fcf3ce44SJohn Forte 1102fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1103fcf3ce44SJohn Forte 1104fcf3ce44SJohn Forte hba->flag &= ~FC_FABRIC_ATTACHED; 1105fcf3ce44SJohn Forte hba->flag |= FC_PT_TO_PT; 1106fcf3ce44SJohn Forte 1107fcf3ce44SJohn Forte /* Save E_D_TOV ticks in nanoseconds */ 1108fcf3ce44SJohn Forte if (sp->cmn.edtovResolution) { 1109fcf3ce44SJohn Forte hba->fc_edtov = 111082527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000; 1111fcf3ce44SJohn Forte } else { 111282527734SSukumar Swaminathan hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov); 1113fcf3ce44SJohn Forte } 1114fcf3ce44SJohn Forte 1115fcf3ce44SJohn Forte /* Save R_A_TOV ticks */ 111682527734SSukumar Swaminathan hba->fc_ratov = (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000; 1117fcf3ce44SJohn Forte 1118fcf3ce44SJohn Forte buffer[0] = 0; 1119fcf3ce44SJohn Forte 1120fcf3ce44SJohn Forte hba->flag &= ~FC_NPIV_SUPPORTED; 1121fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Disabled. P2P "); 112282527734SSukumar Swaminathan 112382527734SSukumar Swaminathan port->rdid = sid; 1124fcf3ce44SJohn Forte 1125fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1126fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 1127fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 1128fcf3ce44SJohn Forte } else if (cfg[CFG_AUTH_ENABLE].current && 1129fcf3ce44SJohn Forte (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) { 1130fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 1131fcf3ce44SJohn Forte } else { 1132fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 1133fcf3ce44SJohn Forte } 1134291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 1135fcf3ce44SJohn Forte 1136fcf3ce44SJohn Forte /* Clear the fabric service parameters */ 1137291a2b48SSukumar Swaminathan bzero((void *)&port->fabric_sparam, sizeof (SERV_PARM)); 1138fcf3ce44SJohn Forte 1139fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1140fcf3ce44SJohn Forte 1141fcf3ce44SJohn Forte return (0); 1142fcf3ce44SJohn Forte 114382527734SSukumar Swaminathan } /* emlxs_process_unsol_flogi() */ 1144fcf3ce44SJohn Forte 1145fcf3ce44SJohn Forte 1146fcf3ce44SJohn Forte /* ARGSUSED */ 1147fcf3ce44SJohn Forte static void 114882527734SSukumar Swaminathan emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1149fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1150fcf3ce44SJohn Forte { 1151fcf3ce44SJohn Forte uint8_t *bp; 1152fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1153fcf3ce44SJohn Forte IOCB *iocb; 1154fcf3ce44SJohn Forte uint32_t sid; 1155fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1156fcf3ce44SJohn Forte char buffer[64]; 1157fcf3ce44SJohn Forte 1158fcf3ce44SJohn Forte buffer[0] = 0; 1159fcf3ce44SJohn Forte 1160fcf3ce44SJohn Forte /* Perform processing of FLOGI payload */ 1161fcf3ce44SJohn Forte if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) { 1162fcf3ce44SJohn Forte return; 1163fcf3ce44SJohn Forte } 1164291a2b48SSukumar Swaminathan 1165fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1166fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1167fcf3ce44SJohn Forte bp = mp->virt; 1168fcf3ce44SJohn Forte size = sizeof (SERV_PARM) + 4; 1169fcf3ce44SJohn Forte 1170fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1171fcf3ce44SJohn Forte 1172fcf3ce44SJohn Forte if (ubp == NULL) { 1173fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1174291a2b48SSukumar Swaminathan "FLOGI rcvd: sid=%x. Rejecting.", sid); 1175fcf3ce44SJohn Forte 1176fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1177fcf3ce44SJohn Forte ELS_CMD_FLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1178fcf3ce44SJohn Forte 1179fcf3ce44SJohn Forte goto drop_it; 1180fcf3ce44SJohn Forte } 1181291a2b48SSukumar Swaminathan 1182fcf3ce44SJohn Forte /* 1183fcf3ce44SJohn Forte * Setup unsolicited buffer and pass it up 1184fcf3ce44SJohn Forte */ 1185fcf3ce44SJohn Forte bcopy(bp, ubp->ub_buffer, size); 1186fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1187fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_FLOGI; 1188fcf3ce44SJohn Forte 1189fcf3ce44SJohn Forte /* 1190fcf3ce44SJohn Forte * Setup frame header 1191fcf3ce44SJohn Forte */ 1192fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1193fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 119482527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 119582527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1196fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 119782527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1198fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1199fcf3ce44SJohn Forte 1200fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1201291a2b48SSukumar Swaminathan "FLOGI: sid=%x buffer=%p token=%x %s", sid, ubp, ub_priv->token, 1202291a2b48SSukumar Swaminathan buffer); 1203fcf3ce44SJohn Forte 1204fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1205fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1206291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1207fcf3ce44SJohn Forte 1208fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1209fcf3ce44SJohn Forte 1210fcf3ce44SJohn Forte drop_it: 1211fcf3ce44SJohn Forte 1212fcf3ce44SJohn Forte return; 1213fcf3ce44SJohn Forte 121482527734SSukumar Swaminathan } /* emlxs_handle_unsol_flogi() */ 1215fcf3ce44SJohn Forte 1216fcf3ce44SJohn Forte 1217fcf3ce44SJohn Forte 1218fcf3ce44SJohn Forte /* This is shared by FCT driver */ 1219fcf3ce44SJohn Forte extern uint32_t 1220291a2b48SSukumar Swaminathan emlxs_process_unsol_plogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp, 1221291a2b48SSukumar Swaminathan uint32_t size, char *buffer) 1222fcf3ce44SJohn Forte { 1223fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1224fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1225fcf3ce44SJohn Forte uint8_t *bp; 1226fcf3ce44SJohn Forte IOCB *iocb; 1227fcf3ce44SJohn Forte uint32_t sid; 1228fcf3ce44SJohn Forte SERV_PARM *sp; 1229fcf3ce44SJohn Forte MAILBOXQ *mbox; 1230291a2b48SSukumar Swaminathan emlxs_vvl_fmt_t vvl; 123182527734SSukumar Swaminathan int rc; 1232fcf3ce44SJohn Forte 1233fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1234fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1235fcf3ce44SJohn Forte 1236fcf3ce44SJohn Forte if (size < (sizeof (SERV_PARM) + 4)) { 1237fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1238291a2b48SSukumar Swaminathan "PLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid, 1239291a2b48SSukumar Swaminathan size, (sizeof (SERV_PARM) + 4)); 1240fcf3ce44SJohn Forte 1241fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1242fcf3ce44SJohn Forte ELS_CMD_PLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE); 1243fcf3ce44SJohn Forte 1244fcf3ce44SJohn Forte return (1); 1245fcf3ce44SJohn Forte } 1246291a2b48SSukumar Swaminathan 1247fcf3ce44SJohn Forte bp = mp->virt; 1248fcf3ce44SJohn Forte sp = (SERV_PARM *)(bp + sizeof (uint32_t)); 1249fcf3ce44SJohn Forte 1250291a2b48SSukumar Swaminathan bzero((char *)&vvl, sizeof (emlxs_vvl_fmt_t)); 1251fcf3ce44SJohn Forte 125282527734SSukumar Swaminathan if (sp->VALID_VENDOR_VERSION) { 1253fcf3ce44SJohn Forte 1254291a2b48SSukumar Swaminathan bcopy((caddr_t *)&sp->vendorVersion[0], 1255291a2b48SSukumar Swaminathan (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t)); 125682527734SSukumar Swaminathan vvl.un0.word0 = LE_SWAP32(vvl.un0.word0); 125782527734SSukumar Swaminathan vvl.un1.word1 = LE_SWAP32(vvl.un1.word1); 1258291a2b48SSukumar Swaminathan } 1259291a2b48SSukumar Swaminathan 1260291a2b48SSukumar Swaminathan if (port->flag & EMLXS_PORT_RESTRICTED) { 1261291a2b48SSukumar Swaminathan uint32_t reject_it = 0; 1262291a2b48SSukumar Swaminathan 1263291a2b48SSukumar Swaminathan /* If remote port is the virtual port, then reject it */ 1264291a2b48SSukumar Swaminathan if ((vvl.un0.w0.oui == 0x0000C9) && (vvl.un1.w1.vport)) { 1265291a2b48SSukumar Swaminathan reject_it = 1; 1266fcf3ce44SJohn Forte } 1267291a2b48SSukumar Swaminathan 1268291a2b48SSukumar Swaminathan /* If we are a virtual port and the remote device */ 1269291a2b48SSukumar Swaminathan /* is not a switch, then reject it */ 127082527734SSukumar Swaminathan else if (port->vpi && ((sid & FABRIC_DID_MASK) != 127182527734SSukumar Swaminathan FABRIC_DID_MASK)) { 1272fcf3ce44SJohn Forte reject_it = 1; 1273fcf3ce44SJohn Forte } 1274291a2b48SSukumar Swaminathan 1275fcf3ce44SJohn Forte if (reject_it) { 1276fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1277fcf3ce44SJohn Forte "PLOGI rcvd: sid=%x. Restricted. Rejecting.", 1278fcf3ce44SJohn Forte sid); 1279fcf3ce44SJohn Forte 1280fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1281fcf3ce44SJohn Forte ELS_CMD_PLOGI, LSRJT_UNABLE_TPC, 1282fcf3ce44SJohn Forte LSEXP_NOTHING_MORE); 1283fcf3ce44SJohn Forte 1284*a9800bebSGarrett D'Amore /* Clear temporary RPI in firmware */ 1285*a9800bebSGarrett D'Amore if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) { 1286*a9800bebSGarrett D'Amore (void) emlxs_mb_reg_did(port, sid, sp, 1287*a9800bebSGarrett D'Amore NULL, NULL, (IOCBQ *)1); 1288*a9800bebSGarrett D'Amore } 1289fcf3ce44SJohn Forte 1290fcf3ce44SJohn Forte return (1); 1291fcf3ce44SJohn Forte } 1292fcf3ce44SJohn Forte } 1293fcf3ce44SJohn Forte 1294fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1295fcf3ce44SJohn Forte if (emlxs_dhc_verify_login(port, sid, sp)) { 1296fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1297291a2b48SSukumar Swaminathan "PLOGI: sid=%x. FCSP disabled. Rejecting.", sid); 1298fcf3ce44SJohn Forte 1299fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1300fcf3ce44SJohn Forte ELS_CMD_PLOGI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 1301fcf3ce44SJohn Forte 1302fcf3ce44SJohn Forte return (1); 1303fcf3ce44SJohn Forte } 1304291a2b48SSukumar Swaminathan 1305fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 1306fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 1307fcf3ce44SJohn Forte } else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current && 1308fcf3ce44SJohn Forte (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) { 1309fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 1310fcf3ce44SJohn Forte } else { 1311fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 1312fcf3ce44SJohn Forte } 1313291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 1314fcf3ce44SJohn Forte 1315fcf3ce44SJohn Forte /* Check if this was a point to point Plogi */ 1316fcf3ce44SJohn Forte if (hba->flag & FC_PT_TO_PT) { 1317fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1318fcf3ce44SJohn Forte 1319fcf3ce44SJohn Forte /* Save our new port ID */ 1320fcf3ce44SJohn Forte port->did = iocb->un.elsreq.myID; 1321fcf3ce44SJohn Forte 1322fcf3ce44SJohn Forte /* Save E_D_TOV ticks in nanoseconds */ 1323fcf3ce44SJohn Forte if (sp->cmn.edtovResolution) { 1324fcf3ce44SJohn Forte hba->fc_edtov = 132582527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000; 1326fcf3ce44SJohn Forte } else { 132782527734SSukumar Swaminathan hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov); 1328fcf3ce44SJohn Forte } 1329fcf3ce44SJohn Forte 1330fcf3ce44SJohn Forte /* Save R_A_TOV ticks */ 1331291a2b48SSukumar Swaminathan hba->fc_ratov = 133282527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000; 1333fcf3ce44SJohn Forte 1334fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1335fcf3ce44SJohn Forte 1336fcf3ce44SJohn Forte /* Update our service parms */ 1337291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, 133882527734SSukumar Swaminathan MEM_MBOX, 1))) { 133982527734SSukumar Swaminathan emlxs_mb_config_link(hba, mbox); 1340fcf3ce44SJohn Forte 134182527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, 134282527734SSukumar Swaminathan MBX_NOWAIT, 0); 134382527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 1344*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbox); 1345fcf3ce44SJohn Forte } 1346291a2b48SSukumar Swaminathan 1347fcf3ce44SJohn Forte } 1348fcf3ce44SJohn Forte } 1349291a2b48SSukumar Swaminathan 1350fcf3ce44SJohn Forte return (0); 1351fcf3ce44SJohn Forte 135282527734SSukumar Swaminathan } /* emlxs_process_unsol_plogi() */ 1353fcf3ce44SJohn Forte 1354fcf3ce44SJohn Forte 1355fcf3ce44SJohn Forte /* ARGSUSED */ 1356fcf3ce44SJohn Forte static void 135782527734SSukumar Swaminathan emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1358fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1359fcf3ce44SJohn Forte { 1360fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1361fcf3ce44SJohn Forte uint8_t *bp; 1362fcf3ce44SJohn Forte IOCB *iocb; 1363fcf3ce44SJohn Forte uint32_t sid; 1364fcf3ce44SJohn Forte uint32_t did; 1365fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1366fcf3ce44SJohn Forte SERV_PARM *sp; 1367fcf3ce44SJohn Forte char buffer[64]; 1368fcf3ce44SJohn Forte 1369fcf3ce44SJohn Forte buffer[0] = 0; 1370fcf3ce44SJohn Forte 1371fcf3ce44SJohn Forte /* Perform processing of PLOGI payload */ 1372fcf3ce44SJohn Forte if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) { 1373fcf3ce44SJohn Forte return; 1374fcf3ce44SJohn Forte } 1375291a2b48SSukumar Swaminathan 1376fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1377fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1378fcf3ce44SJohn Forte did = iocb->un.elsreq.myID; 1379fcf3ce44SJohn Forte bp = mp->virt; 1380fcf3ce44SJohn Forte sp = (SERV_PARM *)(bp + sizeof (uint32_t)); 1381fcf3ce44SJohn Forte size = sizeof (SERV_PARM) + 4; 1382fcf3ce44SJohn Forte 1383291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1384291a2b48SSukumar Swaminathan emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_PLOGI_RCV, 1385291a2b48SSukumar Swaminathan (HBA_WWN *)&sp->portName, (HBA_WWN *)&sp->nodeName); 1386291a2b48SSukumar Swaminathan #endif 1387291a2b48SSukumar Swaminathan 1388fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1389fcf3ce44SJohn Forte 1390fcf3ce44SJohn Forte if (ubp == NULL) { 1391fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1392291a2b48SSukumar Swaminathan "PLOGI rcvd: sid=%x. Rejecting.", sid); 1393fcf3ce44SJohn Forte 1394fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1395fcf3ce44SJohn Forte ELS_CMD_PLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1396fcf3ce44SJohn Forte 1397fcf3ce44SJohn Forte goto drop_it; 1398fcf3ce44SJohn Forte } 1399291a2b48SSukumar Swaminathan 1400fcf3ce44SJohn Forte /* 1401fcf3ce44SJohn Forte * Setup unsolicited buffer and pass it up 1402fcf3ce44SJohn Forte */ 1403fcf3ce44SJohn Forte bcopy(bp, ubp->ub_buffer, size); 1404fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1405fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_PLOGI; 1406fcf3ce44SJohn Forte 1407fcf3ce44SJohn Forte /* 1408fcf3ce44SJohn Forte * Setup frame header 1409fcf3ce44SJohn Forte */ 1410fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1411fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 141282527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 141382527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1414fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 141582527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1416fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1417fcf3ce44SJohn Forte 1418fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1419291a2b48SSukumar Swaminathan "PLOGI: sid=%x did=%x buffer=%p token=%x %s", sid, did, ubp, 1420291a2b48SSukumar Swaminathan ub_priv->token, buffer); 1421fcf3ce44SJohn Forte 1422fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1423fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1424291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1425fcf3ce44SJohn Forte 1426fcf3ce44SJohn Forte /* Create a new node and defer callback */ 1427fcf3ce44SJohn Forte if (emlxs_mb_reg_did(port, sid, sp, NULL, ubp, NULL) == 0) { 1428fcf3ce44SJohn Forte /* 1429fcf3ce44SJohn Forte * Defer completion of this pkt until login is complete 1430fcf3ce44SJohn Forte */ 1431fcf3ce44SJohn Forte goto drop_it; 1432fcf3ce44SJohn Forte } 1433291a2b48SSukumar Swaminathan 1434fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1435fcf3ce44SJohn Forte 1436fcf3ce44SJohn Forte drop_it: 1437fcf3ce44SJohn Forte 1438fcf3ce44SJohn Forte return; 1439fcf3ce44SJohn Forte 144082527734SSukumar Swaminathan } /* emlxs_handle_unsol_plogi() */ 1441fcf3ce44SJohn Forte 1442fcf3ce44SJohn Forte 1443fcf3ce44SJohn Forte /* ARGSUSED */ 1444fcf3ce44SJohn Forte static void 144582527734SSukumar Swaminathan emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1446fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1447fcf3ce44SJohn Forte { 144882527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 144982527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 1450fcf3ce44SJohn Forte IOCB *iocb; 1451fcf3ce44SJohn Forte uint32_t sid; 1452fcf3ce44SJohn Forte NODELIST *ndlp; 1453fcf3ce44SJohn Forte PRLI *npr; 1454fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1455fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1456*a9800bebSGarrett D'Amore uint32_t task_retry_id; 1457fcf3ce44SJohn Forte 1458fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1459fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1460fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, sid); 1461fcf3ce44SJohn Forte 1462fcf3ce44SJohn Forte if (!ndlp || !ndlp->nlp_active) { 1463fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1464291a2b48SSukumar Swaminathan "PRLI: sid=%x: Node not found. Rejecting.", sid); 1465fcf3ce44SJohn Forte 1466fcf3ce44SJohn Forte /* Auto reply to PRLI's */ 1467fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1468fcf3ce44SJohn Forte ELS_CMD_PRLI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 1469fcf3ce44SJohn Forte 1470fcf3ce44SJohn Forte goto drop_it; 1471fcf3ce44SJohn Forte } 1472291a2b48SSukumar Swaminathan 1473fcf3ce44SJohn Forte /* If node exists then save FCP2 support */ 1474fcf3ce44SJohn Forte npr = (PRLI *)((caddr_t)mp->virt + sizeof (uint32_t)); 1475fcf3ce44SJohn Forte 1476fcf3ce44SJohn Forte /* Check for FCP2 support */ 1477fcf3ce44SJohn Forte if ((npr->prliType == PRLI_FCP_TYPE) && npr->targetFunc) { 1478*a9800bebSGarrett D'Amore /* Clear FCP2 support if no ADISC support is requested */ 1479*a9800bebSGarrett D'Amore if (cfg[CFG_ADISC_SUPPORT].current == 0) { 1480*a9800bebSGarrett D'Amore npr->ConfmComplAllowed = 0; 1481*a9800bebSGarrett D'Amore npr->TaskRetryIdReq = 0; 1482*a9800bebSGarrett D'Amore npr->Retry = 0; 1483*a9800bebSGarrett D'Amore } 1484*a9800bebSGarrett D'Amore 1485fcf3ce44SJohn Forte /* Check for target */ 1486fcf3ce44SJohn Forte if (npr->targetFunc) { 1487fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE; 1488fcf3ce44SJohn Forte } else { 1489fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE; 1490fcf3ce44SJohn Forte } 1491fcf3ce44SJohn Forte 1492fcf3ce44SJohn Forte /* Check for initiator */ 1493fcf3ce44SJohn Forte if (npr->initiatorFunc) { 1494fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE; 1495fcf3ce44SJohn Forte } else { 1496fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE; 1497fcf3ce44SJohn Forte } 1498fcf3ce44SJohn Forte 1499*a9800bebSGarrett D'Amore /* If TRI support is not required then force */ 1500*a9800bebSGarrett D'Amore /* the task_retry_id value to one */ 1501*a9800bebSGarrett D'Amore if (cfg[CFG_TRI_REQUIRED].current == 0) { 1502*a9800bebSGarrett D'Amore task_retry_id = 1; 1503*a9800bebSGarrett D'Amore } else { 1504*a9800bebSGarrett D'Amore task_retry_id = npr->TaskRetryIdReq; 1505*a9800bebSGarrett D'Amore } 1506*a9800bebSGarrett D'Amore 1507fcf3ce44SJohn Forte /* Check for FCP2 target support */ 1508*a9800bebSGarrett D'Amore /* Retry and TaskRetryId bits are both required here */ 1509*a9800bebSGarrett D'Amore if (npr->targetFunc && npr->Retry && task_retry_id) { 1510fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; 1511fcf3ce44SJohn Forte } else { 1512fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; 1513fcf3ce44SJohn Forte } 1514fcf3ce44SJohn Forte } 1515fcf3ce44SJohn Forte 151682527734SSukumar Swaminathan #ifdef ULP_PATCH3 151782527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH3) { 151882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 151982527734SSukumar Swaminathan "PRLI: sid=%x. Accepting.", sid); 1520fcf3ce44SJohn Forte 152182527734SSukumar Swaminathan /* Auto reply to PRLI's */ 152282527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, 152382527734SSukumar Swaminathan ELS_CMD_PRLI, 0, 0); 152482527734SSukumar Swaminathan goto drop_it; 152582527734SSukumar Swaminathan } 152682527734SSukumar Swaminathan #endif /* ULP_PATCH3 */ 1527fcf3ce44SJohn Forte 1528fcf3ce44SJohn Forte /* Tell ULP about it */ 1529fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1530fcf3ce44SJohn Forte 1531fcf3ce44SJohn Forte if (ubp == NULL) { 1532fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1533291a2b48SSukumar Swaminathan "PRLI rcvd: sid=%x. Rejecting.", sid); 1534fcf3ce44SJohn Forte 1535fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1536fcf3ce44SJohn Forte ELS_CMD_PRLI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1537fcf3ce44SJohn Forte 1538fcf3ce44SJohn Forte goto drop_it; 1539fcf3ce44SJohn Forte } 1540291a2b48SSukumar Swaminathan 1541fcf3ce44SJohn Forte /* 1542fcf3ce44SJohn Forte * Setup unsolicited buffer and pass it up 1543fcf3ce44SJohn Forte */ 1544fcf3ce44SJohn Forte bcopy(mp->virt, ubp->ub_buffer, size); 1545fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1546fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_PRLI; 1547fcf3ce44SJohn Forte 1548fcf3ce44SJohn Forte /* 1549fcf3ce44SJohn Forte * Setup frame header 1550fcf3ce44SJohn Forte */ 1551fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1552fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 155382527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 155482527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1555fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 155682527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1557fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1558fcf3ce44SJohn Forte 1559fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1560291a2b48SSukumar Swaminathan "PRLI: sid=%x buffer=%p token=%x info=%02x", sid, ubp, 1561291a2b48SSukumar Swaminathan ub_priv->token, ndlp->nlp_fcp_info); 1562fcf3ce44SJohn Forte 1563fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1564fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1565291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1566fcf3ce44SJohn Forte 1567fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1568fcf3ce44SJohn Forte 1569fcf3ce44SJohn Forte drop_it: 1570fcf3ce44SJohn Forte 1571fcf3ce44SJohn Forte return; 1572fcf3ce44SJohn Forte 157382527734SSukumar Swaminathan } /* emlxs_handle_unsol_prli() */ 1574fcf3ce44SJohn Forte 1575fcf3ce44SJohn Forte 1576fcf3ce44SJohn Forte /* ARGSUSED */ 1577fcf3ce44SJohn Forte static void 157882527734SSukumar Swaminathan emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1579fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1580fcf3ce44SJohn Forte { 1581fcf3ce44SJohn Forte IOCB *iocb; 1582fcf3ce44SJohn Forte uint32_t sid; 1583fcf3ce44SJohn Forte NODELIST *ndlp; 1584fcf3ce44SJohn Forte 1585fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1586fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1587fcf3ce44SJohn Forte 1588fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1589fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, sid); 1590fcf3ce44SJohn Forte 1591fcf3ce44SJohn Forte if (!ndlp || !ndlp->nlp_active) { 1592fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1593291a2b48SSukumar Swaminathan "AUTH: sid=%x: Node not found. Rejecting.", sid); 1594fcf3ce44SJohn Forte 1595fcf3ce44SJohn Forte /* Auto reply to AUTH_ELS's */ 1596fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1597fcf3ce44SJohn Forte ELS_CMD_AUTH, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 1598fcf3ce44SJohn Forte 1599fcf3ce44SJohn Forte goto drop_it; 1600fcf3ce44SJohn Forte } 1601291a2b48SSukumar Swaminathan 1602291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "AUTH: sid=%x", sid); 1603fcf3ce44SJohn Forte 160482527734SSukumar Swaminathan (void) emlxs_dhchap_state_machine(port, cp, iocbq, mp, ndlp, 1605fcf3ce44SJohn Forte NODE_EVENT_RCV_AUTH_MSG); 1606fcf3ce44SJohn Forte #else 1607fcf3ce44SJohn Forte 1608fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1609291a2b48SSukumar Swaminathan "AUTH: sid=%x: Rejecting.", sid); 1610fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, ELS_CMD_AUTH, 1611fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 1612fcf3ce44SJohn Forte 1613291a2b48SSukumar Swaminathan #endif /* DHCAHP_SUPPORT */ 1614fcf3ce44SJohn Forte 1615fcf3ce44SJohn Forte drop_it: 1616fcf3ce44SJohn Forte 1617fcf3ce44SJohn Forte return; 1618fcf3ce44SJohn Forte 161982527734SSukumar Swaminathan } /* emlxs_handle_unsol_auth() */ 1620fcf3ce44SJohn Forte 1621fcf3ce44SJohn Forte 1622fcf3ce44SJohn Forte /* ARGSUSED */ 1623fcf3ce44SJohn Forte static void 162482527734SSukumar Swaminathan emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1625fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1626fcf3ce44SJohn Forte { 1627291a2b48SSukumar Swaminathan IOCB *iocb; 1628291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1629291a2b48SSukumar Swaminathan NODELIST *ndlp; 1630291a2b48SSukumar Swaminathan #endif 1631291a2b48SSukumar Swaminathan uint32_t sid; 1632fcf3ce44SJohn Forte 1633fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1634fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1635fcf3ce44SJohn Forte 1636291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1637291a2b48SSukumar Swaminathan ndlp = emlxs_node_find_did(port, sid); 1638291a2b48SSukumar Swaminathan 1639291a2b48SSukumar Swaminathan if (ndlp) { 1640291a2b48SSukumar Swaminathan emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_ADISC_RCV, 1641291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_portname, 1642291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_nodename); 1643291a2b48SSukumar Swaminathan } 1644291a2b48SSukumar Swaminathan #endif 1645291a2b48SSukumar Swaminathan 1646fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1647291a2b48SSukumar Swaminathan "ADISC: sid=%x: Accepting.", sid); 1648fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_ADISC, 0, 0); 1649fcf3ce44SJohn Forte 1650fcf3ce44SJohn Forte return; 1651fcf3ce44SJohn Forte 165282527734SSukumar Swaminathan } /* emlxs_handle_unsol_adisc() */ 1653fcf3ce44SJohn Forte 1654fcf3ce44SJohn Forte 1655fcf3ce44SJohn Forte /* ARGSUSED */ 1656fcf3ce44SJohn Forte static void 165782527734SSukumar Swaminathan emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1658fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1659fcf3ce44SJohn Forte { 166082527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 166182527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 1662fcf3ce44SJohn Forte IOCB *iocb; 1663fcf3ce44SJohn Forte uint32_t sid; 1664fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1665fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1666fcf3ce44SJohn Forte NODELIST *ndlp; 1667fcf3ce44SJohn Forte 1668fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1669fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1670fcf3ce44SJohn Forte 1671fcf3ce44SJohn Forte /* Get the node */ 1672fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, sid); 1673fcf3ce44SJohn Forte 1674291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1675291a2b48SSukumar Swaminathan if (ndlp) { 1676291a2b48SSukumar Swaminathan emlxs_log_sd_prlo_event(port, (HBA_WWN *)&ndlp->nlp_portname); 1677291a2b48SSukumar Swaminathan } 1678291a2b48SSukumar Swaminathan #endif 1679291a2b48SSukumar Swaminathan 1680291a2b48SSukumar Swaminathan #ifdef ULP_PATCH4 168182527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH4) { 1682291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6 168382527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) { 168482527734SSukumar Swaminathan /* Check if this is a SCSI target */ 168582527734SSukumar Swaminathan if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) { 168682527734SSukumar Swaminathan /* This is a SCSI target */ 168782527734SSukumar Swaminathan 168882527734SSukumar Swaminathan /* If only one node is present, then we can */ 168982527734SSukumar Swaminathan /* conclude that we are direct attached */ 169082527734SSukumar Swaminathan /* to a target */ 169182527734SSukumar Swaminathan if (port->node_count == 1) { 169282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 169382527734SSukumar Swaminathan &emlxs_unsol_els_msg, 169482527734SSukumar Swaminathan "PRLO: sid=%x. Accepting and " \ 169582527734SSukumar Swaminathan "reseting link.", 169682527734SSukumar Swaminathan sid); 1697291a2b48SSukumar Swaminathan 169882527734SSukumar Swaminathan /* Send Acc */ 169982527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, 170082527734SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0); 1701fcf3ce44SJohn Forte 170282527734SSukumar Swaminathan /* Spawn a thread to reset the link */ 170382527734SSukumar Swaminathan emlxs_thread_spawn(hba, 170482527734SSukumar Swaminathan emlxs_reset_link_thread, 170582527734SSukumar Swaminathan NULL, NULL); 1706fcf3ce44SJohn Forte 170782527734SSukumar Swaminathan goto drop_it; 1708fcf3ce44SJohn Forte 170982527734SSukumar Swaminathan } 171082527734SSukumar Swaminathan /* Check if fabric is present */ 171182527734SSukumar Swaminathan else if (hba->flag & FC_FABRIC_ATTACHED) { 171282527734SSukumar Swaminathan /* Auto reply to PRLO */ 171382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 171482527734SSukumar Swaminathan &emlxs_unsol_els_msg, 171582527734SSukumar Swaminathan "PRLO: sid=%x. Accepting and " \ 171682527734SSukumar Swaminathan "generating RSCN.", 171782527734SSukumar Swaminathan sid); 1718fcf3ce44SJohn Forte 171982527734SSukumar Swaminathan /* Send Acc */ 172082527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, 172182527734SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0); 1722fcf3ce44SJohn Forte 172382527734SSukumar Swaminathan /* Generate an RSCN to wakeup ULP */ 172482527734SSukumar Swaminathan (void) emlxs_generate_rscn(port, sid); 1725fcf3ce44SJohn Forte 172682527734SSukumar Swaminathan goto drop_it; 172782527734SSukumar Swaminathan } 172882527734SSukumar Swaminathan } 1729fcf3ce44SJohn Forte } 1730291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */ 1731fcf3ce44SJohn Forte 173282527734SSukumar Swaminathan /* Auto reply to PRLO */ 173382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 173482527734SSukumar Swaminathan "PRLO: sid=%x. Accepting.", sid); 1735fcf3ce44SJohn Forte 173682527734SSukumar Swaminathan /* Send Acc */ 173782527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, 173882527734SSukumar Swaminathan ELS_CMD_PRLO, 0, 0); 1739fcf3ce44SJohn Forte 174082527734SSukumar Swaminathan goto drop_it; 174182527734SSukumar Swaminathan } 174282527734SSukumar Swaminathan #endif /* ULP_PATCH4 */ 1743fcf3ce44SJohn Forte 1744fcf3ce44SJohn Forte /* Tell ULP about it */ 1745fcf3ce44SJohn Forte 1746fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1747fcf3ce44SJohn Forte 1748fcf3ce44SJohn Forte if (ubp == NULL) { 1749fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1750291a2b48SSukumar Swaminathan "PRLO recvd: sid=%x. Rejecting.", sid); 1751fcf3ce44SJohn Forte 1752fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1753fcf3ce44SJohn Forte ELS_CMD_PRLO, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1754fcf3ce44SJohn Forte 1755fcf3ce44SJohn Forte goto drop_it; 1756fcf3ce44SJohn Forte } 1757291a2b48SSukumar Swaminathan 1758fcf3ce44SJohn Forte /* 1759fcf3ce44SJohn Forte * Setup unsolicited buffer and pass it up 1760fcf3ce44SJohn Forte */ 1761fcf3ce44SJohn Forte bcopy(mp->virt, ubp->ub_buffer, size); 1762fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1763fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_PRLO; 1764fcf3ce44SJohn Forte 1765fcf3ce44SJohn Forte /* 1766fcf3ce44SJohn Forte * Setup frame header 1767fcf3ce44SJohn Forte */ 1768fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1769fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 177082527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 177182527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1772fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 177382527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1774fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1775fcf3ce44SJohn Forte 1776fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1777291a2b48SSukumar Swaminathan "PRLO: sid=%x buffeiocbr=%p token=%x.", sid, ubp, ub_priv->token); 1778fcf3ce44SJohn Forte 1779fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1780fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1781291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1782fcf3ce44SJohn Forte 1783fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1784fcf3ce44SJohn Forte 1785fcf3ce44SJohn Forte drop_it: 1786fcf3ce44SJohn Forte 1787fcf3ce44SJohn Forte return; 1788fcf3ce44SJohn Forte 178982527734SSukumar Swaminathan } /* emlxs_handle_unsol_prlo() */ 1790fcf3ce44SJohn Forte 1791fcf3ce44SJohn Forte 1792fcf3ce44SJohn Forte /* ARGSUSED */ 1793fcf3ce44SJohn Forte static void 179482527734SSukumar Swaminathan emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1795fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1796fcf3ce44SJohn Forte { 1797fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 179882527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 1799fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1800fcf3ce44SJohn Forte IOCB *iocb; 1801fcf3ce44SJohn Forte uint32_t sid; 1802fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1803fcf3ce44SJohn Forte uint32_t reply_sent = 0; 1804fcf3ce44SJohn Forte NODELIST *ndlp; 1805fcf3ce44SJohn Forte 1806fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1807fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1808fcf3ce44SJohn Forte 1809fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, sid); 1810fcf3ce44SJohn Forte 1811291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1812291a2b48SSukumar Swaminathan if (ndlp) { 1813291a2b48SSukumar Swaminathan emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_LOGO_RCV, 1814291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_portname, 1815291a2b48SSukumar Swaminathan (HBA_WWN *)((uint32_t *)mp->virt + 2)); 1816291a2b48SSukumar Swaminathan } 1817291a2b48SSukumar Swaminathan #endif 1818291a2b48SSukumar Swaminathan 1819291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6 182082527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) { 182182527734SSukumar Swaminathan /* Check if this is a SCSI target */ 182282527734SSukumar Swaminathan if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) { 182382527734SSukumar Swaminathan /* This is a SCSI target */ 1824291a2b48SSukumar Swaminathan 182582527734SSukumar Swaminathan /* If only one node is present, then we can */ 182682527734SSukumar Swaminathan /* conclude that we are direct attached to a target */ 182782527734SSukumar Swaminathan if (port->node_count == 1) { 182882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 182982527734SSukumar Swaminathan "LOGO: sid=%x. Accepting and "\ 183082527734SSukumar Swaminathan "reseting link.", sid); 1831fcf3ce44SJohn Forte 183282527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, 183382527734SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_LOGO, 0, 0); 1834fcf3ce44SJohn Forte 183582527734SSukumar Swaminathan /* Spawn a thread to reset the link */ 183682527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_reset_link_thread, 183782527734SSukumar Swaminathan NULL, NULL); 1838fcf3ce44SJohn Forte 1839fcf3ce44SJohn Forte goto drop_it; 1840fcf3ce44SJohn Forte } 184182527734SSukumar Swaminathan /* Check if fabric node is present */ 184282527734SSukumar Swaminathan else if (hba->flag & FC_FABRIC_ATTACHED) { 184382527734SSukumar Swaminathan /* Send reply ourselves */ 184482527734SSukumar Swaminathan /* We will block all attempts */ 184582527734SSukumar Swaminathan /* for ULP to reply to a LOGO */ 184682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 184782527734SSukumar Swaminathan "LOGO: sid=%x. Accepting and " \ 184882527734SSukumar Swaminathan "generating RSCN.", sid); 184982527734SSukumar Swaminathan 185082527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, 185182527734SSukumar Swaminathan ELS_CMD_LOGO, 0, 0); 185282527734SSukumar Swaminathan 185382527734SSukumar Swaminathan /* Generate an RSCN to wakeup ULP */ 185482527734SSukumar Swaminathan if (emlxs_generate_rscn(port, sid) 185582527734SSukumar Swaminathan == FC_SUCCESS) { 185682527734SSukumar Swaminathan goto drop_it; 185782527734SSukumar Swaminathan } 1858291a2b48SSukumar Swaminathan 185982527734SSukumar Swaminathan reply_sent = 1; 186082527734SSukumar Swaminathan } 1861fcf3ce44SJohn Forte } 1862291a2b48SSukumar Swaminathan } 1863291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */ 1864fcf3ce44SJohn Forte 1865fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 1); 1866fcf3ce44SJohn Forte 1867fcf3ce44SJohn Forte if (ubp == NULL) { 1868fcf3ce44SJohn Forte if (!reply_sent) { 1869fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1870291a2b48SSukumar Swaminathan "LOGO rcvd: sid=%x. Rejecting.", sid); 1871fcf3ce44SJohn Forte 1872fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1873fcf3ce44SJohn Forte ELS_CMD_LOGO, LSRJT_LOGICAL_BSY, 1874fcf3ce44SJohn Forte LSEXP_OUT_OF_RESOURCE); 1875fcf3ce44SJohn Forte } 1876291a2b48SSukumar Swaminathan 1877fcf3ce44SJohn Forte goto drop_it; 1878fcf3ce44SJohn Forte 1879fcf3ce44SJohn Forte } 1880291a2b48SSukumar Swaminathan 1881fcf3ce44SJohn Forte /* Setup unsolicited buffer and pass it up */ 1882fcf3ce44SJohn Forte bcopy(mp->virt, ubp->ub_buffer, size); 1883fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1884fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_LOGO; 1885fcf3ce44SJohn Forte 1886fcf3ce44SJohn Forte /* Setup frame header */ 1887fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1888fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 188982527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 189082527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1891fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 189282527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1893fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1894fcf3ce44SJohn Forte 1895fcf3ce44SJohn Forte #ifdef ULP_PATCH2 189682527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH2) { 189782527734SSukumar Swaminathan if (!reply_sent) { 189882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 189982527734SSukumar Swaminathan "LOGO: sid=%x buffer=%p token=%x. Accepting.", 190082527734SSukumar Swaminathan sid, ubp, ub_priv->token); 1901fcf3ce44SJohn Forte 190282527734SSukumar Swaminathan ub_priv->flags |= EMLXS_UB_REPLY; 1903fcf3ce44SJohn Forte 190482527734SSukumar Swaminathan /* Send Acc */ 190582527734SSukumar Swaminathan /* Send reply ourselves because ULP */ 190682527734SSukumar Swaminathan /* doesn't always reply to these */ 190782527734SSukumar Swaminathan /* We ll block attempts for ULP to reply to a LOGO */ 190882527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, 190982527734SSukumar Swaminathan ELS_CMD_LOGO, 0, 0); 191082527734SSukumar Swaminathan reply_sent = 1; 191182527734SSukumar Swaminathan } 1912fcf3ce44SJohn Forte } 191382527734SSukumar Swaminathan #endif /* ULP_PATCH2 */ 1914fcf3ce44SJohn Forte 1915fcf3ce44SJohn Forte if (!reply_sent) { 1916fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1917291a2b48SSukumar Swaminathan "LOGO: sid=%x buffer=%p token=%x.", sid, ubp, 1918291a2b48SSukumar Swaminathan ub_priv->token); 1919fcf3ce44SJohn Forte } 1920fcf3ce44SJohn Forte 1921fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1922fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1923291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1924fcf3ce44SJohn Forte 1925*a9800bebSGarrett D'Amore /* Unregister the node */ 192682527734SSukumar Swaminathan if ((sid & FABRIC_DID_MASK) == FABRIC_DID_MASK) { 1927*a9800bebSGarrett D'Amore if (ndlp) { 1928*a9800bebSGarrett D'Amore if (emlxs_mb_unreg_node(port, ndlp, NULL, 1929*a9800bebSGarrett D'Amore ubp, NULL) == 0) { 1930*a9800bebSGarrett D'Amore /* 1931*a9800bebSGarrett D'Amore * Deferred completion of this ubp 1932*a9800bebSGarrett D'Amore * until unreg login is complete 1933*a9800bebSGarrett D'Amore */ 1934*a9800bebSGarrett D'Amore return; 1935*a9800bebSGarrett D'Amore } 1936fcf3ce44SJohn Forte } 1937fcf3ce44SJohn Forte } 1938291a2b48SSukumar Swaminathan 1939fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1940fcf3ce44SJohn Forte 1941fcf3ce44SJohn Forte drop_it: 1942fcf3ce44SJohn Forte 1943fcf3ce44SJohn Forte return; 1944fcf3ce44SJohn Forte 194582527734SSukumar Swaminathan } /* emlxs_handle_unsol_logo() */ 1946291a2b48SSukumar Swaminathan 1947fcf3ce44SJohn Forte 1948fcf3ce44SJohn Forte 1949fcf3ce44SJohn Forte /* ARGSUSED */ 1950fcf3ce44SJohn Forte static void 195182527734SSukumar Swaminathan emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1952fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1953fcf3ce44SJohn Forte { 1954fcf3ce44SJohn Forte uint8_t *bp; 1955fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1956fcf3ce44SJohn Forte IOCB *iocb; 1957fcf3ce44SJohn Forte uint32_t *lp; 1958fcf3ce44SJohn Forte uint32_t cmd; 1959fcf3ce44SJohn Forte uint32_t sid; 1960fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1961fcf3ce44SJohn Forte 1962fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1963fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1964fcf3ce44SJohn Forte 1965fcf3ce44SJohn Forte bp = mp->virt; 1966fcf3ce44SJohn Forte lp = (uint32_t *)bp; 1967fcf3ce44SJohn Forte cmd = *lp & ELS_CMD_MASK; 1968fcf3ce44SJohn Forte 1969fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1970fcf3ce44SJohn Forte 1971fcf3ce44SJohn Forte if (ubp == NULL) { 1972fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1973291a2b48SSukumar Swaminathan "%s rcvd: sid=%x: Rejecting.", emlxs_elscmd_xlate(cmd), 1974291a2b48SSukumar Swaminathan sid); 1975fcf3ce44SJohn Forte 1976fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd, 1977fcf3ce44SJohn Forte LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1978fcf3ce44SJohn Forte 1979fcf3ce44SJohn Forte goto drop_it; 1980fcf3ce44SJohn Forte } 1981291a2b48SSukumar Swaminathan 1982fcf3ce44SJohn Forte bcopy(bp, ubp->ub_buffer, size); 1983fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1984fcf3ce44SJohn Forte ub_priv->cmd = cmd; 1985fcf3ce44SJohn Forte 1986fcf3ce44SJohn Forte /* Setup frame header */ 1987fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1988fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 198982527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 199082527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1991fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 199282527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1993fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1994fcf3ce44SJohn Forte 1995fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1996291a2b48SSukumar Swaminathan "%s: sid=%x buffer=%p token=%x.", emlxs_elscmd_xlate(cmd), sid, 1997291a2b48SSukumar Swaminathan ubp, ub_priv->token); 1998fcf3ce44SJohn Forte 1999fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 2000fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 2001291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 2002fcf3ce44SJohn Forte 2003fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 2004fcf3ce44SJohn Forte 2005fcf3ce44SJohn Forte drop_it: 2006fcf3ce44SJohn Forte 2007fcf3ce44SJohn Forte return; 2008fcf3ce44SJohn Forte 200982527734SSukumar Swaminathan } /* emlxs_handle_unsol_gen_cmd() */ 2010fcf3ce44SJohn Forte 2011fcf3ce44SJohn Forte 2012*a9800bebSGarrett D'Amore /* ARGSUSED */ 2013*a9800bebSGarrett D'Amore static void 2014*a9800bebSGarrett D'Amore emlxs_handle_unsol_echo_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 2015*a9800bebSGarrett D'Amore MATCHMAP *mp, uint32_t size) 2016*a9800bebSGarrett D'Amore { 2017*a9800bebSGarrett D'Amore emlxs_hba_t *hba = HBA; 2018*a9800bebSGarrett D'Amore uint8_t *bp; 2019*a9800bebSGarrett D'Amore IOCB *iocb; 2020*a9800bebSGarrett D'Amore uint32_t *lp; 2021*a9800bebSGarrett D'Amore uint32_t sid; 2022*a9800bebSGarrett D'Amore fc_packet_t *pkt; 2023*a9800bebSGarrett D'Amore uint32_t cmd; 2024*a9800bebSGarrett D'Amore 2025*a9800bebSGarrett D'Amore iocb = &iocbq->iocb; 2026*a9800bebSGarrett D'Amore sid = iocb->un.elsreq.remoteID; 2027*a9800bebSGarrett D'Amore 2028*a9800bebSGarrett D'Amore bp = mp->virt; 2029*a9800bebSGarrett D'Amore lp = (uint32_t *)bp; 2030*a9800bebSGarrett D'Amore cmd = *lp & ELS_CMD_MASK; 2031*a9800bebSGarrett D'Amore 2032*a9800bebSGarrett D'Amore if (!(pkt = emlxs_pkt_alloc(port, 2033*a9800bebSGarrett D'Amore size, 0, 0, KM_NOSLEEP))) { 2034*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2035*a9800bebSGarrett D'Amore "ECHO: sid=%x. Unable to allocate pkt. Rejecting.", 2036*a9800bebSGarrett D'Amore sid); 2037*a9800bebSGarrett D'Amore 2038*a9800bebSGarrett D'Amore (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 2039*a9800bebSGarrett D'Amore ELS_CMD_ECHO, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 2040*a9800bebSGarrett D'Amore return; 2041*a9800bebSGarrett D'Amore } 2042*a9800bebSGarrett D'Amore 2043*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2044*a9800bebSGarrett D'Amore "ECHO: sid=%x. Accepting.", 2045*a9800bebSGarrett D'Amore sid); 2046*a9800bebSGarrett D'Amore 2047*a9800bebSGarrett D'Amore /* Common initialization */ 2048*a9800bebSGarrett D'Amore pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2049*a9800bebSGarrett D'Amore pkt->pkt_timeout = (2 * hba->fc_ratov); 2050*a9800bebSGarrett D'Amore 2051*a9800bebSGarrett D'Amore if ((uint32_t)iocb->ULPCLASS == CLASS2) { 2052*a9800bebSGarrett D'Amore pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 2053*a9800bebSGarrett D'Amore pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 2054*a9800bebSGarrett D'Amore } 2055*a9800bebSGarrett D'Amore 2056*a9800bebSGarrett D'Amore /* Build the fc header */ 2057*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.d_id = 2058*a9800bebSGarrett D'Amore LE_SWAP24_LO(iocb->un.elsreq.remoteID); 2059*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.r_ctl = 2060*a9800bebSGarrett D'Amore R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 2061*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 2062*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2063*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.f_ctl = 2064*a9800bebSGarrett D'Amore F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2065*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.seq_id = 0; 2066*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.df_ctl = 0; 2067*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.seq_cnt = 0; 2068*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff; 2069*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2070*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.ro = 0; 2071*a9800bebSGarrett D'Amore 2072*a9800bebSGarrett D'Amore /* Build the response */ 2073*a9800bebSGarrett D'Amore *lp = ELS_CMD_ACC; 2074*a9800bebSGarrett D'Amore bcopy(lp, pkt->pkt_cmd, size); 2075*a9800bebSGarrett D'Amore 2076*a9800bebSGarrett D'Amore if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2077*a9800bebSGarrett D'Amore /* Free the pkt */ 2078*a9800bebSGarrett D'Amore emlxs_pkt_free(pkt); 2079*a9800bebSGarrett D'Amore emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT); 2080*a9800bebSGarrett D'Amore } 2081*a9800bebSGarrett D'Amore 2082*a9800bebSGarrett D'Amore return; 2083*a9800bebSGarrett D'Amore 2084*a9800bebSGarrett D'Amore } /* emlxs_handle_unsol_echo_cmd() */ 2085*a9800bebSGarrett D'Amore 2086*a9800bebSGarrett D'Amore 2087*a9800bebSGarrett D'Amore /* ARGSUSED */ 2088*a9800bebSGarrett D'Amore static void 2089*a9800bebSGarrett D'Amore emlxs_handle_unsol_rtv_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 2090*a9800bebSGarrett D'Amore MATCHMAP *mp, uint32_t size) 2091*a9800bebSGarrett D'Amore { 2092*a9800bebSGarrett D'Amore emlxs_hba_t *hba = HBA; 2093*a9800bebSGarrett D'Amore uint8_t *bp; 2094*a9800bebSGarrett D'Amore IOCB *iocb; 2095*a9800bebSGarrett D'Amore uint32_t *lp; 2096*a9800bebSGarrett D'Amore uint32_t sid; 2097*a9800bebSGarrett D'Amore fc_packet_t *pkt; 2098*a9800bebSGarrett D'Amore uint32_t cmd; 2099*a9800bebSGarrett D'Amore SERV_PARM *sp; 2100*a9800bebSGarrett D'Amore 2101*a9800bebSGarrett D'Amore iocb = &iocbq->iocb; 2102*a9800bebSGarrett D'Amore sid = iocb->un.elsreq.remoteID; 2103*a9800bebSGarrett D'Amore 2104*a9800bebSGarrett D'Amore bp = mp->virt; 2105*a9800bebSGarrett D'Amore lp = (uint32_t *)bp; 2106*a9800bebSGarrett D'Amore cmd = *lp & ELS_CMD_MASK; 2107*a9800bebSGarrett D'Amore 2108*a9800bebSGarrett D'Amore if (!(pkt = emlxs_pkt_alloc(port, 2109*a9800bebSGarrett D'Amore (4 * sizeof (uint32_t)), 0, 0, KM_NOSLEEP))) { 2110*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2111*a9800bebSGarrett D'Amore "RTV: sid=%x. Unable to allocate pkt. Rejecting.", 2112*a9800bebSGarrett D'Amore sid); 2113*a9800bebSGarrett D'Amore 2114*a9800bebSGarrett D'Amore (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 2115*a9800bebSGarrett D'Amore ELS_CMD_RTV, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 2116*a9800bebSGarrett D'Amore return; 2117*a9800bebSGarrett D'Amore } 2118*a9800bebSGarrett D'Amore 2119*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2120*a9800bebSGarrett D'Amore "RTV: sid=%x. Accepting.", 2121*a9800bebSGarrett D'Amore emlxs_elscmd_xlate(cmd), 2122*a9800bebSGarrett D'Amore sid); 2123*a9800bebSGarrett D'Amore 2124*a9800bebSGarrett D'Amore /* Common initialization */ 2125*a9800bebSGarrett D'Amore pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2126*a9800bebSGarrett D'Amore pkt->pkt_timeout = (2 * hba->fc_ratov); 2127*a9800bebSGarrett D'Amore 2128*a9800bebSGarrett D'Amore if ((uint32_t)iocb->ULPCLASS == CLASS2) { 2129*a9800bebSGarrett D'Amore pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 2130*a9800bebSGarrett D'Amore pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 2131*a9800bebSGarrett D'Amore } 2132*a9800bebSGarrett D'Amore 2133*a9800bebSGarrett D'Amore /* Build the fc header */ 2134*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.d_id = 2135*a9800bebSGarrett D'Amore LE_SWAP24_LO(iocb->un.elsreq.remoteID); 2136*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.r_ctl = 2137*a9800bebSGarrett D'Amore R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 2138*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 2139*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2140*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.f_ctl = 2141*a9800bebSGarrett D'Amore F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2142*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.seq_id = 0; 2143*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.df_ctl = 0; 2144*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.seq_cnt = 0; 2145*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff; 2146*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2147*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.ro = 0; 2148*a9800bebSGarrett D'Amore 2149*a9800bebSGarrett D'Amore /* Build the response */ 2150*a9800bebSGarrett D'Amore sp = (SERV_PARM *)&port->sparam; 2151*a9800bebSGarrett D'Amore lp = (uint32_t *)pkt->pkt_cmd; 2152*a9800bebSGarrett D'Amore lp[0] = ELS_CMD_ACC; 2153*a9800bebSGarrett D'Amore lp[1] = LE_SWAP32(sp->cmn.w2.r_a_tov); 2154*a9800bebSGarrett D'Amore lp[2] = LE_SWAP32(sp->cmn.e_d_tov); 2155*a9800bebSGarrett D'Amore lp[3] = LE_SWAP32(sp->cmn.edtovResolution << 26); 2156*a9800bebSGarrett D'Amore 2157*a9800bebSGarrett D'Amore if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2158*a9800bebSGarrett D'Amore /* Free the pkt */ 2159*a9800bebSGarrett D'Amore emlxs_pkt_free(pkt); 2160*a9800bebSGarrett D'Amore emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT); 2161*a9800bebSGarrett D'Amore } 2162*a9800bebSGarrett D'Amore 2163*a9800bebSGarrett D'Amore return; 2164*a9800bebSGarrett D'Amore 2165*a9800bebSGarrett D'Amore } /* emlxs_handle_unsol_rtv_cmd() */ 2166*a9800bebSGarrett D'Amore 2167*a9800bebSGarrett D'Amore 2168*a9800bebSGarrett D'Amore /* ARGSUSED */ 2169*a9800bebSGarrett D'Amore static void 2170*a9800bebSGarrett D'Amore emlxs_rls_rsp_thread(emlxs_hba_t *hba, void *arg1, void *arg2) 2171*a9800bebSGarrett D'Amore { 2172*a9800bebSGarrett D'Amore emlxs_port_t *port = (emlxs_port_t *)arg1; 2173*a9800bebSGarrett D'Amore fc_packet_t *pkt = (fc_packet_t *)arg2; 2174*a9800bebSGarrett D'Amore MAILBOXQ *mbq = NULL; 2175*a9800bebSGarrett D'Amore MAILBOX *mb; 2176*a9800bebSGarrett D'Amore la_els_rls_acc_t *rls; 2177*a9800bebSGarrett D'Amore uint32_t rval; 2178*a9800bebSGarrett D'Amore 2179*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2180*a9800bebSGarrett D'Amore "RLS: sid=%x. Accepting.", 2181*a9800bebSGarrett D'Amore LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id)); 2182*a9800bebSGarrett D'Amore 2183*a9800bebSGarrett D'Amore if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) { 2184*a9800bebSGarrett D'Amore goto dropit; 2185*a9800bebSGarrett D'Amore } 2186*a9800bebSGarrett D'Amore mb = (MAILBOX *)mbq; 2187*a9800bebSGarrett D'Amore 2188*a9800bebSGarrett D'Amore /* Read current link status */ 2189*a9800bebSGarrett D'Amore emlxs_mb_read_lnk_stat(hba, mbq); 2190*a9800bebSGarrett D'Amore rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0); 2191*a9800bebSGarrett D'Amore 2192*a9800bebSGarrett D'Amore if (rval != MBX_SUCCESS) { 2193*a9800bebSGarrett D'Amore goto dropit; 2194*a9800bebSGarrett D'Amore } 2195*a9800bebSGarrett D'Amore 2196*a9800bebSGarrett D'Amore /* Build the response */ 2197*a9800bebSGarrett D'Amore rls = (la_els_rls_acc_t *)pkt->pkt_cmd; 2198*a9800bebSGarrett D'Amore rls->ls_code.ls_code = 0x02; 2199*a9800bebSGarrett D'Amore rls->rls_link_params.rls_link_fail = 2200*a9800bebSGarrett D'Amore mb->un.varRdLnk.linkFailureCnt; 2201*a9800bebSGarrett D'Amore rls->rls_link_params.rls_sync_loss = 2202*a9800bebSGarrett D'Amore mb->un.varRdLnk.lossSyncCnt; 2203*a9800bebSGarrett D'Amore rls->rls_link_params.rls_sig_loss = 2204*a9800bebSGarrett D'Amore mb->un.varRdLnk.lossSignalCnt; 2205*a9800bebSGarrett D'Amore rls->rls_link_params.rls_prim_seq_err = 2206*a9800bebSGarrett D'Amore mb->un.varRdLnk.primSeqErrCnt; 2207*a9800bebSGarrett D'Amore rls->rls_link_params.rls_invalid_word = 2208*a9800bebSGarrett D'Amore mb->un.varRdLnk.invalidXmitWord; 2209*a9800bebSGarrett D'Amore rls->rls_link_params.rls_invalid_crc = 2210*a9800bebSGarrett D'Amore mb->un.varRdLnk.crcCnt; 2211*a9800bebSGarrett D'Amore 2212*a9800bebSGarrett D'Amore LE_SWAP32_BUFFER((uint8_t *)rls, sizeof (la_els_rls_acc_t)); 2213*a9800bebSGarrett D'Amore 2214*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 2215*a9800bebSGarrett D'Amore mbq = NULL; 2216*a9800bebSGarrett D'Amore 2217*a9800bebSGarrett D'Amore if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) { 2218*a9800bebSGarrett D'Amore goto dropit; 2219*a9800bebSGarrett D'Amore } 2220*a9800bebSGarrett D'Amore 2221*a9800bebSGarrett D'Amore return; 2222*a9800bebSGarrett D'Amore 2223*a9800bebSGarrett D'Amore dropit: 2224*a9800bebSGarrett D'Amore 2225*a9800bebSGarrett D'Amore emlxs_abort_els_exchange(hba, port, pkt->pkt_cmd_fhdr.rx_id); 2226*a9800bebSGarrett D'Amore 2227*a9800bebSGarrett D'Amore emlxs_pkt_free(pkt); 2228*a9800bebSGarrett D'Amore 2229*a9800bebSGarrett D'Amore if (mbq) { 2230*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 2231*a9800bebSGarrett D'Amore } 2232*a9800bebSGarrett D'Amore 2233*a9800bebSGarrett D'Amore return; 2234*a9800bebSGarrett D'Amore 2235*a9800bebSGarrett D'Amore } /* emlxs_rls_rsp_thread() */ 2236*a9800bebSGarrett D'Amore 2237*a9800bebSGarrett D'Amore 2238*a9800bebSGarrett D'Amore /* ARGSUSED */ 2239*a9800bebSGarrett D'Amore static void 2240*a9800bebSGarrett D'Amore emlxs_handle_unsol_rls_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 2241*a9800bebSGarrett D'Amore MATCHMAP *mp, uint32_t size) 2242*a9800bebSGarrett D'Amore { 2243*a9800bebSGarrett D'Amore emlxs_hba_t *hba = HBA; 2244*a9800bebSGarrett D'Amore uint8_t *bp; 2245*a9800bebSGarrett D'Amore IOCB *iocb; 2246*a9800bebSGarrett D'Amore uint32_t *lp; 2247*a9800bebSGarrett D'Amore uint32_t sid; 2248*a9800bebSGarrett D'Amore fc_packet_t *pkt; 2249*a9800bebSGarrett D'Amore uint32_t cmd; 2250*a9800bebSGarrett D'Amore 2251*a9800bebSGarrett D'Amore iocb = &iocbq->iocb; 2252*a9800bebSGarrett D'Amore sid = iocb->un.elsreq.remoteID; 2253*a9800bebSGarrett D'Amore 2254*a9800bebSGarrett D'Amore bp = mp->virt; 2255*a9800bebSGarrett D'Amore lp = (uint32_t *)bp; 2256*a9800bebSGarrett D'Amore cmd = *lp++ & ELS_CMD_MASK; 2257*a9800bebSGarrett D'Amore 2258*a9800bebSGarrett D'Amore if (!(pkt = emlxs_pkt_alloc(port, 2259*a9800bebSGarrett D'Amore sizeof (la_els_rls_acc_t), 0, 0, KM_NOSLEEP))) { 2260*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2261*a9800bebSGarrett D'Amore "RLS: sid=%x. Unable to allocate pkt. Rejecting.", 2262*a9800bebSGarrett D'Amore sid); 2263*a9800bebSGarrett D'Amore 2264*a9800bebSGarrett D'Amore (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 2265*a9800bebSGarrett D'Amore ELS_CMD_RLS, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 2266*a9800bebSGarrett D'Amore return; 2267*a9800bebSGarrett D'Amore } 2268*a9800bebSGarrett D'Amore 2269*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2270*a9800bebSGarrett D'Amore "RLS: sid=%x. Scheduling response.", 2271*a9800bebSGarrett D'Amore sid); 2272*a9800bebSGarrett D'Amore 2273*a9800bebSGarrett D'Amore /* Common initialization */ 2274*a9800bebSGarrett D'Amore pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2275*a9800bebSGarrett D'Amore pkt->pkt_timeout = (2 * hba->fc_ratov); 2276*a9800bebSGarrett D'Amore 2277*a9800bebSGarrett D'Amore if ((uint32_t)iocb->ULPCLASS == CLASS2) { 2278*a9800bebSGarrett D'Amore pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 2279*a9800bebSGarrett D'Amore pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 2280*a9800bebSGarrett D'Amore } 2281*a9800bebSGarrett D'Amore 2282*a9800bebSGarrett D'Amore /* Build the fc header */ 2283*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.d_id = 2284*a9800bebSGarrett D'Amore LE_SWAP24_LO(iocb->un.elsreq.remoteID); 2285*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.r_ctl = 2286*a9800bebSGarrett D'Amore R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 2287*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 2288*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2289*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.f_ctl = 2290*a9800bebSGarrett D'Amore F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2291*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.seq_id = 0; 2292*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.df_ctl = 0; 2293*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.seq_cnt = 0; 2294*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff; 2295*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2296*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.ro = 0; 2297*a9800bebSGarrett D'Amore 2298*a9800bebSGarrett D'Amore /* We must spawn a separate thread to send the */ 2299*a9800bebSGarrett D'Amore /* read link status mailbox command becasue we are */ 2300*a9800bebSGarrett D'Amore /* normally in a hardware interrupt context here. */ 2301*a9800bebSGarrett D'Amore emlxs_thread_spawn(hba, emlxs_rls_rsp_thread, 2302*a9800bebSGarrett D'Amore (void *)port, (void *)pkt); 2303*a9800bebSGarrett D'Amore 2304*a9800bebSGarrett D'Amore return; 2305*a9800bebSGarrett D'Amore 2306*a9800bebSGarrett D'Amore } /* emlxs_handle_unsol_rls_cmd() */ 2307*a9800bebSGarrett D'Amore 2308*a9800bebSGarrett D'Amore 2309fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */ 2310fcf3ce44SJohn Forte /* ARGSUSED */ 2311fcf3ce44SJohn Forte static void 2312291a2b48SSukumar Swaminathan emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq, 2313291a2b48SSukumar Swaminathan uint32_t flag) 2314fcf3ce44SJohn Forte { 231582527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 2316fcf3ce44SJohn Forte fc_packet_t *pkt; 2317fcf3ce44SJohn Forte IOCB *iocb; 2318fcf3ce44SJohn Forte uint32_t did; 2319fcf3ce44SJohn Forte NODELIST *ndlp; 2320fcf3ce44SJohn Forte uint32_t ucmd; 2321fcf3ce44SJohn Forte uint32_t cmd; 2322fcf3ce44SJohn Forte uint32_t *lp; 2323fcf3ce44SJohn Forte 2324fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2325fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 232682527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 2327fcf3ce44SJohn Forte ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT; 2328fcf3ce44SJohn Forte lp = (uint32_t *)pkt->pkt_cmd; 2329fcf3ce44SJohn Forte cmd = *lp & ELS_CMD_MASK; 2330fcf3ce44SJohn Forte 2331fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 2332291a2b48SSukumar Swaminathan "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd), 233382527734SSukumar Swaminathan emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS), 2334fcf3ce44SJohn Forte emlxs_error_xlate(iocb->un.grsp.perr.statLocalError)); 2335fcf3ce44SJohn Forte 2336fcf3ce44SJohn Forte switch (ucmd) { 2337fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 2338fcf3ce44SJohn Forte case ELS_CMD_ADISC: 2339fcf3ce44SJohn Forte 2340fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 2341fcf3ce44SJohn Forte 2342fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 2343fcf3ce44SJohn Forte /* Open the node again */ 234482527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 234582527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_ip); 2346fcf3ce44SJohn Forte } 2347291a2b48SSukumar Swaminathan 2348fcf3ce44SJohn Forte break; 2349fcf3ce44SJohn Forte 2350fcf3ce44SJohn Forte case ELS_CMD_PRLI: 2351fcf3ce44SJohn Forte 2352fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 2353fcf3ce44SJohn Forte 2354fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 2355fcf3ce44SJohn Forte /* Open the node again */ 235682527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 2357fcf3ce44SJohn Forte } 2358291a2b48SSukumar Swaminathan 2359fcf3ce44SJohn Forte break; 2360fcf3ce44SJohn Forte } 2361fcf3ce44SJohn Forte 236282527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2363fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2364fcf3ce44SJohn Forte 2365fcf3ce44SJohn Forte return; 2366fcf3ce44SJohn Forte 236782527734SSukumar Swaminathan } /* emlxs_handle_acc() */ 2368fcf3ce44SJohn Forte 2369fcf3ce44SJohn Forte 2370fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */ 2371fcf3ce44SJohn Forte /* ARGSUSED */ 2372fcf3ce44SJohn Forte static void 2373291a2b48SSukumar Swaminathan emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq, 2374291a2b48SSukumar Swaminathan uint32_t flag) 2375fcf3ce44SJohn Forte { 237682527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 2377291a2b48SSukumar Swaminathan fc_packet_t *pkt; 2378291a2b48SSukumar Swaminathan NODELIST *ndlp; 2379291a2b48SSukumar Swaminathan IOCB *iocb; 2380291a2b48SSukumar Swaminathan uint32_t did; 2381291a2b48SSukumar Swaminathan uint32_t ucmd; 2382291a2b48SSukumar Swaminathan uint32_t cmd; 2383291a2b48SSukumar Swaminathan uint32_t *lp; 2384fcf3ce44SJohn Forte 2385fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2386fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 238782527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 2388fcf3ce44SJohn Forte ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT; 2389fcf3ce44SJohn Forte lp = (uint32_t *)pkt->pkt_cmd; 2390fcf3ce44SJohn Forte cmd = *lp & ELS_CMD_MASK; 2391fcf3ce44SJohn Forte 2392291a2b48SSukumar Swaminathan ndlp = emlxs_node_find_did(port, did); 2393291a2b48SSukumar Swaminathan 2394fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 2395291a2b48SSukumar Swaminathan "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd), 239682527734SSukumar Swaminathan emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS), 2397fcf3ce44SJohn Forte emlxs_error_xlate(iocb->un.grsp.perr.statLocalError)); 2398fcf3ce44SJohn Forte 2399fcf3ce44SJohn Forte switch (ucmd) { 2400fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 2401fcf3ce44SJohn Forte 2402fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 2403fcf3ce44SJohn Forte /* Open the node again */ 240482527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 240582527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_ip); 2406fcf3ce44SJohn Forte } 2407291a2b48SSukumar Swaminathan 2408fcf3ce44SJohn Forte break; 2409fcf3ce44SJohn Forte 2410fcf3ce44SJohn Forte case ELS_CMD_PRLI: 2411fcf3ce44SJohn Forte 2412fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 2413fcf3ce44SJohn Forte /* Open the node again */ 241482527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 2415fcf3ce44SJohn Forte } 2416291a2b48SSukumar Swaminathan 2417fcf3ce44SJohn Forte break; 2418fcf3ce44SJohn Forte } 2419fcf3ce44SJohn Forte 242082527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2421fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2422fcf3ce44SJohn Forte 2423fcf3ce44SJohn Forte return; 2424fcf3ce44SJohn Forte 242582527734SSukumar Swaminathan } /* emlxs_handle_reject() */ 2426fcf3ce44SJohn Forte 2427fcf3ce44SJohn Forte 2428fcf3ce44SJohn Forte /* ARGSUSED */ 2429fcf3ce44SJohn Forte extern int32_t 2430fcf3ce44SJohn Forte emlxs_els_reply(emlxs_port_t *port, IOCBQ *iocbq, uint32_t type, 2431fcf3ce44SJohn Forte uint32_t type2, uint32_t reason, uint32_t explain) 2432fcf3ce44SJohn Forte { 2433fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2434fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 2435fcf3ce44SJohn Forte fc_packet_t *pkt; 2436fcf3ce44SJohn Forte ELS_PKT *els; 2437fcf3ce44SJohn Forte IOCB *iocb; 2438fcf3ce44SJohn Forte 2439fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2440fcf3ce44SJohn Forte 2441fcf3ce44SJohn Forte switch (type) { 2442fcf3ce44SJohn Forte case ELS_CMD_ACC: /* Accept Response */ 2443fcf3ce44SJohn Forte 2444fcf3ce44SJohn Forte /* Allocate the pkt */ 2445fcf3ce44SJohn Forte switch (type2) { 2446fcf3ce44SJohn Forte case ELS_CMD_FLOGI: 2447*a9800bebSGarrett D'Amore pkt = emlxs_pkt_alloc(port, 2448291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (SERV_PARM), 0, 2449*a9800bebSGarrett D'Amore 0, KM_NOSLEEP); 2450fcf3ce44SJohn Forte break; 2451fcf3ce44SJohn Forte 2452fcf3ce44SJohn Forte case ELS_CMD_ADISC: 2453*a9800bebSGarrett D'Amore pkt = emlxs_pkt_alloc(port, 2454291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (ADISC), 0, 0, 2455*a9800bebSGarrett D'Amore KM_NOSLEEP); 2456fcf3ce44SJohn Forte break; 2457fcf3ce44SJohn Forte 2458fcf3ce44SJohn Forte case ELS_CMD_PRLI: 2459*a9800bebSGarrett D'Amore pkt = emlxs_pkt_alloc(port, 2460291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (PRLI), 0, 0, 2461*a9800bebSGarrett D'Amore KM_NOSLEEP); 2462fcf3ce44SJohn Forte break; 2463fcf3ce44SJohn Forte 2464fcf3ce44SJohn Forte case ELS_CMD_PRLO: 2465*a9800bebSGarrett D'Amore pkt = emlxs_pkt_alloc(port, 2466291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (PRLO), 0, 0, 2467*a9800bebSGarrett D'Amore KM_NOSLEEP); 2468fcf3ce44SJohn Forte break; 2469fcf3ce44SJohn Forte 2470fcf3ce44SJohn Forte case ELS_CMD_AUTH: 2471fcf3ce44SJohn Forte default: 2472*a9800bebSGarrett D'Amore pkt = emlxs_pkt_alloc(port, sizeof (uint32_t), 2473*a9800bebSGarrett D'Amore 0, 0, KM_NOSLEEP); 2474*a9800bebSGarrett D'Amore } 2475fcf3ce44SJohn Forte 2476*a9800bebSGarrett D'Amore if (!pkt) { 2477*a9800bebSGarrett D'Amore goto dropit; 2478fcf3ce44SJohn Forte } 2479fcf3ce44SJohn Forte 2480fcf3ce44SJohn Forte /* Common initialization */ 2481fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2482fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 2483fcf3ce44SJohn Forte 248482527734SSukumar Swaminathan if ((uint32_t)iocb->ULPCLASS == CLASS2) { 2485fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 2486fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 2487fcf3ce44SJohn Forte } 2488291a2b48SSukumar Swaminathan 2489fcf3ce44SJohn Forte /* Build the fc header */ 2490fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = 249182527734SSukumar Swaminathan LE_SWAP24_LO(iocb->un.elsreq.remoteID); 2492291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 2493291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 249482527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 2495fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2496291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 2497291a2b48SSukumar Swaminathan F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2498fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2499fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2500fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2501fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff; 250282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2503fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2504fcf3ce44SJohn Forte 2505fcf3ce44SJohn Forte /* 2506291a2b48SSukumar Swaminathan * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2507291a2b48SSukumar Swaminathan * "%s ACC send. oxid=%x", emlxs_elscmd_xlate(type2), 2508fcf3ce44SJohn Forte * pkt->pkt_cmd_fhdr.ox_id); 2509fcf3ce44SJohn Forte */ 2510fcf3ce44SJohn Forte 2511fcf3ce44SJohn Forte /* Build the command */ 2512291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_cmd; 2513fcf3ce44SJohn Forte els->elsCode = 0x02; 2514fcf3ce44SJohn Forte 2515fcf3ce44SJohn Forte /* Build the payload */ 2516fcf3ce44SJohn Forte switch (type2) { 2517fcf3ce44SJohn Forte case ELS_CMD_ADISC: 2518fcf3ce44SJohn Forte 2519fcf3ce44SJohn Forte els->un.adisc.hardAL_PA = 2520fcf3ce44SJohn Forte (uint8_t)cfg[CFG_ASSIGN_ALPA].current; 2521fcf3ce44SJohn Forte bcopy(&port->wwnn, &els->un.adisc.nodeName, 2522fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2523fcf3ce44SJohn Forte bcopy(&port->wwpn, &els->un.adisc.portName, 2524fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 252582527734SSukumar Swaminathan els->un.adisc.DID = LE_SWAP24_LO(port->did); 2526fcf3ce44SJohn Forte 2527fcf3ce44SJohn Forte break; 2528fcf3ce44SJohn Forte 2529fcf3ce44SJohn Forte case ELS_CMD_PRLI: 2530fcf3ce44SJohn Forte 2531fcf3ce44SJohn Forte els->elsByte1 = 0x10; 2532fcf3ce44SJohn Forte els->elsByte2 = 0; 2533fcf3ce44SJohn Forte els->elsByte3 = 0x14; 2534fcf3ce44SJohn Forte 2535fcf3ce44SJohn Forte els->un.prli.prliType = PRLI_FCP_TYPE; 2536fcf3ce44SJohn Forte els->un.prli.estabImagePair = 1; 2537fcf3ce44SJohn Forte els->un.prli.acceptRspCode = PRLI_REQ_EXECUTED; 2538fcf3ce44SJohn Forte 2539fcf3ce44SJohn Forte if (port->ini_mode) { 2540fcf3ce44SJohn Forte els->un.prli.initiatorFunc = 1; 2541fcf3ce44SJohn Forte } 2542291a2b48SSukumar Swaminathan 2543fcf3ce44SJohn Forte if (port->tgt_mode) { 2544fcf3ce44SJohn Forte els->un.prli.targetFunc = 1; 2545fcf3ce44SJohn Forte } 2546291a2b48SSukumar Swaminathan 2547fcf3ce44SJohn Forte els->un.prli.readXferRdyDis = 1; 2548fcf3ce44SJohn Forte 2549*a9800bebSGarrett D'Amore if ((hba->vpd.feaLevelHigh >= 0x02) && 2550*a9800bebSGarrett D'Amore (cfg[CFG_ADISC_SUPPORT].current != 0)) { 2551fcf3ce44SJohn Forte els->un.prli.ConfmComplAllowed = 1; 2552fcf3ce44SJohn Forte els->un.prli.Retry = 1; 2553fcf3ce44SJohn Forte els->un.prli.TaskRetryIdReq = 1; 2554fcf3ce44SJohn Forte } else { 2555fcf3ce44SJohn Forte els->un.prli.ConfmComplAllowed = 0; 2556fcf3ce44SJohn Forte els->un.prli.Retry = 0; 2557fcf3ce44SJohn Forte els->un.prli.TaskRetryIdReq = 0; 2558fcf3ce44SJohn Forte } 2559fcf3ce44SJohn Forte 2560fcf3ce44SJohn Forte break; 2561fcf3ce44SJohn Forte 2562fcf3ce44SJohn Forte case ELS_CMD_PRLO: 2563fcf3ce44SJohn Forte 2564fcf3ce44SJohn Forte els->elsByte1 = 0x10; 2565fcf3ce44SJohn Forte els->elsByte2 = 0; 2566fcf3ce44SJohn Forte els->elsByte3 = 0x14; 2567fcf3ce44SJohn Forte 2568fcf3ce44SJohn Forte els->un.prlo.prloType = PRLO_FCP_TYPE; 2569fcf3ce44SJohn Forte els->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED; 2570fcf3ce44SJohn Forte 2571fcf3ce44SJohn Forte break; 2572fcf3ce44SJohn Forte 2573fcf3ce44SJohn Forte 2574fcf3ce44SJohn Forte } /* switch(type2) */ 2575fcf3ce44SJohn Forte break; 2576fcf3ce44SJohn Forte 2577fcf3ce44SJohn Forte case ELS_CMD_LS_RJT: /* reject response */ 2578fcf3ce44SJohn Forte 2579fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 2580fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (LS_RJT), 0, 0, KM_NOSLEEP))) { 2581*a9800bebSGarrett D'Amore goto dropit; 2582fcf3ce44SJohn Forte } 2583291a2b48SSukumar Swaminathan 2584fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2585fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 2586fcf3ce44SJohn Forte 258782527734SSukumar Swaminathan if ((uint32_t)iocb->ULPCLASS == CLASS2) { 2588fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 2589fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 2590fcf3ce44SJohn Forte } 2591291a2b48SSukumar Swaminathan 2592fcf3ce44SJohn Forte /* Build the fc header */ 2593fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = 259482527734SSukumar Swaminathan LE_SWAP24_LO(iocb->un.elsreq.remoteID); 2595291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 2596291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 259782527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 2598fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2599291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 2600291a2b48SSukumar Swaminathan F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2601fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2602fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2603fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2604fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff; 260582527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2606fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2607fcf3ce44SJohn Forte 2608fcf3ce44SJohn Forte /* 2609291a2b48SSukumar Swaminathan * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2610291a2b48SSukumar Swaminathan * "%s LS_RJT send. oxid=%x", emlxs_elscmd_xlate(type2), 2611fcf3ce44SJohn Forte * pkt->pkt_cmd_fhdr.ox_id); 2612fcf3ce44SJohn Forte */ 2613fcf3ce44SJohn Forte 2614fcf3ce44SJohn Forte /* Build the command */ 2615291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_cmd; 2616fcf3ce44SJohn Forte els->elsCode = 0x01; 2617fcf3ce44SJohn Forte els->un.lsRjt.un.b.lsRjtRsvd0 = 0; 2618fcf3ce44SJohn Forte els->un.lsRjt.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; 2619fcf3ce44SJohn Forte els->un.lsRjt.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; 2620fcf3ce44SJohn Forte els->un.lsRjt.un.b.vendorUnique = 0x01; 2621fcf3ce44SJohn Forte 2622fcf3ce44SJohn Forte break; 2623fcf3ce44SJohn Forte } 2624fcf3ce44SJohn Forte 2625*a9800bebSGarrett D'Amore if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2626fcf3ce44SJohn Forte /* Free the pkt */ 2627fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 2628*a9800bebSGarrett D'Amore goto dropit; 2629fcf3ce44SJohn Forte } 2630291a2b48SSukumar Swaminathan 2631*a9800bebSGarrett D'Amore return (0); 2632*a9800bebSGarrett D'Amore 2633*a9800bebSGarrett D'Amore dropit: 2634*a9800bebSGarrett D'Amore 2635*a9800bebSGarrett D'Amore emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT); 2636*a9800bebSGarrett D'Amore return (1); 2637fcf3ce44SJohn Forte 263882527734SSukumar Swaminathan } /* emlxs_els_reply() */ 2639fcf3ce44SJohn Forte 2640fcf3ce44SJohn Forte 2641fcf3ce44SJohn Forte #ifdef ULP_PATCH6 2642fcf3ce44SJohn Forte 2643fcf3ce44SJohn Forte extern uint32_t 2644fcf3ce44SJohn Forte emlxs_generate_rscn(emlxs_port_t *port, uint32_t d_id) 2645fcf3ce44SJohn Forte { 2646fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 2647fcf3ce44SJohn Forte fc_rscn_t *rscn; 2648fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 2649fcf3ce44SJohn Forte uint32_t *page; 2650fcf3ce44SJohn Forte 2651fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, 8, FC_ELS_DATA, 1); 2652fcf3ce44SJohn Forte 2653fcf3ce44SJohn Forte if (ubp == NULL) { 2654fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 2655291a2b48SSukumar Swaminathan "RSCN create: sid=0xfffffd 1 page(s): %08X, 00000000. " 2656291a2b48SSukumar Swaminathan "Creation failed.", d_id); 2657fcf3ce44SJohn Forte 2658fcf3ce44SJohn Forte return ((uint32_t)FC_FAILURE); 2659fcf3ce44SJohn Forte } 2660291a2b48SSukumar Swaminathan 2661fcf3ce44SJohn Forte /* Simulate an RSCN payload */ 2662fcf3ce44SJohn Forte rscn = (fc_rscn_t *)ubp->ub_buffer; 2663fcf3ce44SJohn Forte rscn->rscn_code = 0x61; 2664fcf3ce44SJohn Forte rscn->rscn_len = 0x04; 2665fcf3ce44SJohn Forte rscn->rscn_payload_len = 0x0008; 2666fcf3ce44SJohn Forte page = ((uint32_t *)rscn); 2667fcf3ce44SJohn Forte page++; 2668fcf3ce44SJohn Forte *page = d_id; 2669fcf3ce44SJohn Forte 2670fcf3ce44SJohn Forte #ifdef EMLXS_I386 2671fcf3ce44SJohn Forte /* Put payload in BE format */ 267282527734SSukumar Swaminathan rscn->rscn_payload_len = LE_SWAP16(rscn->rscn_payload_len); 267382527734SSukumar Swaminathan *page = LE_SWAP32(d_id); 2674291a2b48SSukumar Swaminathan #endif /* EMLXS_I386 */ 2675fcf3ce44SJohn Forte 2676fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 2677fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_RSCN; 2678fcf3ce44SJohn Forte ub_priv->flags |= EMLXS_UB_INTERCEPT; 2679fcf3ce44SJohn Forte 2680fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 2681fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 2682fcf3ce44SJohn Forte ubp->ub_frame.s_id = 0xfffffd; 268382527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(port->did); 2684fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 2685fcf3ce44SJohn Forte ubp->ub_frame.rx_id = 0xffff; 2686fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 2687fcf3ce44SJohn Forte 2688fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2689291a2b48SSukumar Swaminathan "RSCN: sid=fffffd 1 page(s): %08X, 00000000 buffer=%p " 2690291a2b48SSukumar Swaminathan "token=%x. Created.", d_id, ubp, ub_priv->token); 2691fcf3ce44SJohn Forte 2692fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 2693fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 2694291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 2695fcf3ce44SJohn Forte 2696fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 2697fcf3ce44SJohn Forte 2698fcf3ce44SJohn Forte return (FC_SUCCESS); 2699fcf3ce44SJohn Forte 270082527734SSukumar Swaminathan } /* emlxs_generate_rscn() */ 2701fcf3ce44SJohn Forte 2702291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */ 2703fcf3ce44SJohn Forte 2704fcf3ce44SJohn Forte 2705fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 2706fcf3ce44SJohn Forte extern int 270782527734SSukumar Swaminathan emlxs_menlo_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 2708fcf3ce44SJohn Forte { 2709fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2710fcf3ce44SJohn Forte IOCB *iocb; 2711fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2712fcf3ce44SJohn Forte fc_packet_t *pkt; 2713fcf3ce44SJohn Forte uint32_t cmd_code = 0; 2714fcf3ce44SJohn Forte uint32_t rsp_code = 0; 2715fcf3ce44SJohn Forte menlo_cmd_t *cmd; 2716fcf3ce44SJohn Forte uint32_t *rsp; 2717fcf3ce44SJohn Forte 2718fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2719fcf3ce44SJohn Forte 2720fcf3ce44SJohn Forte HBASTATS.CtEvent++; 2721fcf3ce44SJohn Forte 2722fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 2723fcf3ce44SJohn Forte 2724fcf3ce44SJohn Forte if (!sbp) { 2725fcf3ce44SJohn Forte /* 2726fcf3ce44SJohn Forte * completion with missing xmit command 2727fcf3ce44SJohn Forte */ 2728fcf3ce44SJohn Forte HBASTATS.CtStray++; 2729fcf3ce44SJohn Forte 2730fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg, 2731fcf3ce44SJohn Forte "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x", 273282527734SSukumar Swaminathan iocbq, (uint32_t)iocb->ULPCOMMAND, 273382527734SSukumar Swaminathan (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS, 2734291a2b48SSukumar Swaminathan iocb->un.ulpWord[4]); 2735fcf3ce44SJohn Forte 2736fcf3ce44SJohn Forte return (1); 2737fcf3ce44SJohn Forte } 2738291a2b48SSukumar Swaminathan 273982527734SSukumar Swaminathan if (cp->channelno != hba->channel_ct) { 2740fcf3ce44SJohn Forte HBASTATS.CtStray++; 2741fcf3ce44SJohn Forte 2742fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg, 274382527734SSukumar Swaminathan "Invalid IO channel:%d iocbq=%p", cp->channelno, iocbq); 2744fcf3ce44SJohn Forte 2745fcf3ce44SJohn Forte return (1); 2746fcf3ce44SJohn Forte } 2747291a2b48SSukumar Swaminathan 2748fcf3ce44SJohn Forte port = sbp->iocbq.port; 2749fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 2750fcf3ce44SJohn Forte 2751fcf3ce44SJohn Forte cmd = (menlo_cmd_t *)pkt->pkt_cmd; 275282527734SSukumar Swaminathan cmd_code = BE_SWAP32(cmd->code); 2753fcf3ce44SJohn Forte 2754fcf3ce44SJohn Forte /* Check if a response buffer was provided */ 2755fcf3ce44SJohn Forte if (pkt->pkt_rsplen) { 275682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen, 2757fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 2758fcf3ce44SJohn Forte } 2759291a2b48SSukumar Swaminathan 276082527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) { 2761291a2b48SSukumar Swaminathan /* 2762291a2b48SSukumar Swaminathan * MENLO Command completion 2763291a2b48SSukumar Swaminathan */ 2764fcf3ce44SJohn Forte case CMD_GEN_REQUEST64_CR: 2765fcf3ce44SJohn Forte case CMD_GEN_REQUEST64_CX: 2766fcf3ce44SJohn Forte 2767fcf3ce44SJohn Forte HBASTATS.CtCmdCompleted++; 2768fcf3ce44SJohn Forte 2769fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_CT_RSP_VALID; 2770fcf3ce44SJohn Forte 2771fcf3ce44SJohn Forte rsp = (uint32_t *)pkt->pkt_resp; 2772fcf3ce44SJohn Forte rsp_code = *rsp; 277382527734SSukumar Swaminathan rsp_code = BE_SWAP32(rsp_code); 2774fcf3ce44SJohn Forte 277582527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) { 2776fcf3ce44SJohn Forte pkt->pkt_resp_resid = 2777fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen; 2778fcf3ce44SJohn Forte } else 2779fcf3ce44SJohn Forte { 2780fcf3ce44SJohn Forte pkt->pkt_resp_resid = 2781fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize; 2782fcf3ce44SJohn Forte } 2783fcf3ce44SJohn Forte 2784fcf3ce44SJohn Forte pkt->pkt_data_resid = pkt->pkt_datalen; 278582527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2786fcf3ce44SJohn Forte 278782527734SSukumar Swaminathan if ((iocb->ULPSTATUS == 0) && (rsp_code == MENLO_RSP_SUCCESS)) { 2788fcf3ce44SJohn Forte HBASTATS.CtCmdGood++; 2789fcf3ce44SJohn Forte 2790fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2791fcf3ce44SJohn Forte "%s: %s rxid=0x%x", 2792fcf3ce44SJohn Forte emlxs_menlo_cmd_xlate(cmd_code), 2793fcf3ce44SJohn Forte emlxs_menlo_rsp_xlate(rsp_code), 279482527734SSukumar Swaminathan iocb->ULPCONTEXT); 2795fcf3ce44SJohn Forte 2796fcf3ce44SJohn Forte } else { 2797fcf3ce44SJohn Forte HBASTATS.CtCmdError++; 2798fcf3ce44SJohn Forte 2799fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2800fcf3ce44SJohn Forte "%s: %s %s %s rxid=0x%x", 2801fcf3ce44SJohn Forte emlxs_menlo_cmd_xlate(cmd_code), 2802fcf3ce44SJohn Forte emlxs_menlo_rsp_xlate(rsp_code), 280382527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2804291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 280582527734SSukumar Swaminathan statLocalError), iocb->ULPCONTEXT); 2806fcf3ce44SJohn Forte } 2807fcf3ce44SJohn Forte 280882527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2809fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2810fcf3ce44SJohn Forte 2811fcf3ce44SJohn Forte break; 2812fcf3ce44SJohn Forte 2813fcf3ce44SJohn Forte default: 2814fcf3ce44SJohn Forte 2815fcf3ce44SJohn Forte HBASTATS.CtStray++; 2816fcf3ce44SJohn Forte 2817fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg, 281882527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND); 2819fcf3ce44SJohn Forte 282082527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2821fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2822fcf3ce44SJohn Forte 2823fcf3ce44SJohn Forte break; 2824fcf3ce44SJohn Forte 282582527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */ 2826fcf3ce44SJohn Forte 2827fcf3ce44SJohn Forte return (0); 2828fcf3ce44SJohn Forte 282982527734SSukumar Swaminathan } /* emlxs_menlo_handle_event() */ 2830fcf3ce44SJohn Forte 2831291a2b48SSukumar Swaminathan #endif /* MENLO_SUPPORT */ 2832fcf3ce44SJohn Forte 2833fcf3ce44SJohn Forte 2834fcf3ce44SJohn Forte extern int 283582527734SSukumar Swaminathan emlxs_ct_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 2836fcf3ce44SJohn Forte { 2837fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2838fcf3ce44SJohn Forte IOCB *iocb; 2839fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2840fcf3ce44SJohn Forte fc_packet_t *pkt; 2841fcf3ce44SJohn Forte uint32_t *rsp; 2842fcf3ce44SJohn Forte SLI_CT_REQUEST *CtRsp; 2843fcf3ce44SJohn Forte SLI_CT_REQUEST *CtCmd; 2844fcf3ce44SJohn Forte uint32_t cmd_code = 0; 2845fcf3ce44SJohn Forte uint32_t rsp_code = 0; 2846fcf3ce44SJohn Forte 2847fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2848fcf3ce44SJohn Forte 2849fcf3ce44SJohn Forte HBASTATS.CtEvent++; 2850fcf3ce44SJohn Forte 2851fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 2852fcf3ce44SJohn Forte 2853fcf3ce44SJohn Forte if (!sbp) { 2854fcf3ce44SJohn Forte /* 2855fcf3ce44SJohn Forte * completion with missing xmit command 2856fcf3ce44SJohn Forte */ 2857fcf3ce44SJohn Forte HBASTATS.CtStray++; 2858fcf3ce44SJohn Forte 2859fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg, 2860fcf3ce44SJohn Forte "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x", 286182527734SSukumar Swaminathan iocbq, (uint32_t)iocb->ULPCOMMAND, 286282527734SSukumar Swaminathan (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS, 2863291a2b48SSukumar Swaminathan iocb->un.ulpWord[4]); 2864fcf3ce44SJohn Forte 2865fcf3ce44SJohn Forte return (1); 2866fcf3ce44SJohn Forte } 2867291a2b48SSukumar Swaminathan 286882527734SSukumar Swaminathan if (cp->channelno != hba->channel_ct) { 2869fcf3ce44SJohn Forte HBASTATS.CtStray++; 2870fcf3ce44SJohn Forte 2871fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg, 287282527734SSukumar Swaminathan "Invalid channel: channel=%d iocbq=%p", cp->channelno, 287382527734SSukumar Swaminathan iocbq); 2874fcf3ce44SJohn Forte 2875fcf3ce44SJohn Forte return (1); 2876fcf3ce44SJohn Forte } 2877291a2b48SSukumar Swaminathan 2878fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 2879fcf3ce44SJohn Forte port = sbp->iocbq.port; 2880291a2b48SSukumar Swaminathan CtCmd = (SLI_CT_REQUEST *)pkt->pkt_cmd; 288182527734SSukumar Swaminathan cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp); 2882fcf3ce44SJohn Forte 2883fcf3ce44SJohn Forte if (cmd_code == SLI_CT_LOOPBACK) { 2884fcf3ce44SJohn Forte HBASTATS.CtEvent--; 288582527734SSukumar Swaminathan return (emlxs_dfc_handle_event(hba, cp, iocbq)); 2886fcf3ce44SJohn Forte } 2887fcf3ce44SJohn Forte 2888fcf3ce44SJohn Forte /* Check if a response buffer was provided */ 2889fcf3ce44SJohn Forte if (pkt->pkt_rsplen) { 289082527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen, 2891fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 2892fcf3ce44SJohn Forte } 2893291a2b48SSukumar Swaminathan 289482527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) { 2895291a2b48SSukumar Swaminathan /* 2896291a2b48SSukumar Swaminathan * CT Reply completion 2897291a2b48SSukumar Swaminathan */ 2898fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE_CX: 2899fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE64_CX: 2900fcf3ce44SJohn Forte 2901fcf3ce44SJohn Forte HBASTATS.CtRspCompleted++; 2902fcf3ce44SJohn Forte 2903fcf3ce44SJohn Forte switch (CtCmd->FsType) { 2904fcf3ce44SJohn Forte case 0xFC: /* Name server */ 2905fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2906291a2b48SSukumar Swaminathan "%s: %s %s", emlxs_ctcmd_xlate(cmd_code), 290782527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2908291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2909291a2b48SSukumar Swaminathan statLocalError)); 2910fcf3ce44SJohn Forte break; 2911fcf3ce44SJohn Forte 2912fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 2913fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2914291a2b48SSukumar Swaminathan "%s: %s %s", emlxs_mscmd_xlate(cmd_code), 291582527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2916291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2917291a2b48SSukumar Swaminathan statLocalError)); 2918fcf3ce44SJohn Forte break; 2919fcf3ce44SJohn Forte 2920fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 2921fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2922291a2b48SSukumar Swaminathan "%s: %s %s", emlxs_rmcmd_xlate(cmd_code), 292382527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2924291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2925291a2b48SSukumar Swaminathan statLocalError)); 2926fcf3ce44SJohn Forte break; 2927fcf3ce44SJohn Forte 2928fcf3ce44SJohn Forte default: 2929fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2930291a2b48SSukumar Swaminathan "%s: %s %s", emlxs_ctcmd_xlate(cmd_code), 293182527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2932291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2933291a2b48SSukumar Swaminathan statLocalError)); 2934fcf3ce44SJohn Forte } 2935fcf3ce44SJohn Forte 293682527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2937fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2938fcf3ce44SJohn Forte 2939fcf3ce44SJohn Forte break; 2940fcf3ce44SJohn Forte 2941291a2b48SSukumar Swaminathan /* 2942291a2b48SSukumar Swaminathan * CT Command completion 2943291a2b48SSukumar Swaminathan */ 2944fcf3ce44SJohn Forte case CMD_GEN_REQUEST64_CR: 2945fcf3ce44SJohn Forte case CMD_GEN_REQUEST64_CX: 2946fcf3ce44SJohn Forte 2947fcf3ce44SJohn Forte HBASTATS.CtCmdCompleted++; 2948fcf3ce44SJohn Forte 2949fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_CT_RSP_VALID; 2950fcf3ce44SJohn Forte 2951fcf3ce44SJohn Forte rsp = (uint32_t *)pkt->pkt_resp; 2952fcf3ce44SJohn Forte CtRsp = (SLI_CT_REQUEST *)pkt->pkt_resp; 295382527734SSukumar Swaminathan rsp_code = LE_SWAP16(CtRsp->CommandResponse.bits.CmdRsp); 2954fcf3ce44SJohn Forte 295582527734SSukumar Swaminathan if (hba->sli_mode >= EMLXS_HBA_SLI3_MODE) { 2956fcf3ce44SJohn Forte pkt->pkt_resp_resid = 2957fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen; 2958fcf3ce44SJohn Forte } else 2959fcf3ce44SJohn Forte { 2960fcf3ce44SJohn Forte pkt->pkt_resp_resid = 2961fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize; 2962fcf3ce44SJohn Forte } 2963fcf3ce44SJohn Forte 2964fcf3ce44SJohn Forte pkt->pkt_data_resid = pkt->pkt_datalen; 2965fcf3ce44SJohn Forte 2966fcf3ce44SJohn Forte /* 2967291a2b48SSukumar Swaminathan * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2968291a2b48SSukumar Swaminathan * "INFO: pkt_resid=%d %d %d %x", pkt->pkt_resp_resid, 2969fcf3ce44SJohn Forte * pkt->pkt_rsplen, iocb->un.genreq64.bdl.bdeSize, 2970fcf3ce44SJohn Forte * iocb->un.genreq64.bdl.bdeFlags); 2971fcf3ce44SJohn Forte */ 2972fcf3ce44SJohn Forte 297382527734SSukumar Swaminathan if ((iocb->ULPSTATUS == 0) && 2974fcf3ce44SJohn Forte (rsp_code == SLI_CT_RESPONSE_FS_ACC)) { 2975fcf3ce44SJohn Forte HBASTATS.CtCmdGood++; 2976fcf3ce44SJohn Forte 2977fcf3ce44SJohn Forte if (!(sbp->pkt_flags & PACKET_ALLOCATED)) { 2978291a2b48SSukumar Swaminathan /* ULP patch - ULP expects */ 2979291a2b48SSukumar Swaminathan /* resp_resid = 0 on success */ 2980fcf3ce44SJohn Forte pkt->pkt_resp_resid = 0; 2981fcf3ce44SJohn Forte } 2982291a2b48SSukumar Swaminathan 2983fcf3ce44SJohn Forte switch (CtCmd->FsType) { 2984fcf3ce44SJohn Forte case 0xFC: /* Name server */ 2985fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2986fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2987fcf3ce44SJohn Forte "%s: %s: Rsn=%x Exp=%x [%08x,%08x]", 2988fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 2989fcf3ce44SJohn Forte emlxs_ctcmd_xlate(rsp_code), 2990fcf3ce44SJohn Forte CtRsp->ReasonCode, CtRsp->Explanation, 299182527734SSukumar Swaminathan LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5])); 2992fcf3ce44SJohn Forte 2993fcf3ce44SJohn Forte #if (EMLXS_MODREV < EMLXS_MODREV4) 2994fcf3ce44SJohn Forte if (cmd_code == SLI_CTNS_RNN_ID) { 2995fcf3ce44SJohn Forte emlxs_send_rsnn(port); 2996fcf3ce44SJohn Forte } 2997291a2b48SSukumar Swaminathan #endif /* < EMLXS_MODREV4 */ 2998fcf3ce44SJohn Forte 2999fcf3ce44SJohn Forte break; 3000fcf3ce44SJohn Forte 3001fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 3002fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3003fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3004fcf3ce44SJohn Forte "%s: %s: Rsn=%x Exp=%x [%08x,%08x]", 3005fcf3ce44SJohn Forte emlxs_mscmd_xlate(cmd_code), 3006fcf3ce44SJohn Forte emlxs_mscmd_xlate(rsp_code), 3007fcf3ce44SJohn Forte CtRsp->ReasonCode, CtRsp->Explanation, 300882527734SSukumar Swaminathan LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5])); 3009fcf3ce44SJohn Forte break; 3010fcf3ce44SJohn Forte 3011fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 3012fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3013fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3014fcf3ce44SJohn Forte "%s: %s: Rsn=%x Exp=%x [%08x,%08x]", 3015fcf3ce44SJohn Forte emlxs_rmcmd_xlate(cmd_code), 3016fcf3ce44SJohn Forte emlxs_rmcmd_xlate(rsp_code), 3017fcf3ce44SJohn Forte CtRsp->ReasonCode, CtRsp->Explanation, 301882527734SSukumar Swaminathan LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5])); 3019fcf3ce44SJohn Forte break; 3020fcf3ce44SJohn Forte 3021fcf3ce44SJohn Forte default: 3022fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3023fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3024fcf3ce44SJohn Forte "%s: %s: Rsn=%x Exp=%x [%08x,%08x]", 3025fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 3026fcf3ce44SJohn Forte emlxs_ctcmd_xlate(rsp_code), 3027fcf3ce44SJohn Forte CtRsp->ReasonCode, CtRsp->Explanation, 302882527734SSukumar Swaminathan LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5])); 3029fcf3ce44SJohn Forte } 3030fcf3ce44SJohn Forte } else { 3031fcf3ce44SJohn Forte HBASTATS.CtCmdError++; 3032fcf3ce44SJohn Forte 3033fcf3ce44SJohn Forte if (rsp_code == SLI_CT_RESPONSE_FS_RJT) { 3034fcf3ce44SJohn Forte pkt->pkt_state = FC_PKT_FS_RJT; 3035fcf3ce44SJohn Forte pkt->pkt_action = FC_ACTION_RETRYABLE; 3036fcf3ce44SJohn Forte pkt->pkt_reason = CtRsp->ReasonCode; 3037fcf3ce44SJohn Forte pkt->pkt_expln = CtRsp->Explanation; 3038fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_STATE_VALID; 3039fcf3ce44SJohn Forte 3040fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3041fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3042fcf3ce44SJohn Forte "%s: Rejected. rsn=%x exp=%x", 3043fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 3044291a2b48SSukumar Swaminathan pkt->pkt_reason, pkt->pkt_expln); 304582527734SSukumar Swaminathan } else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) { 3046fcf3ce44SJohn Forte switch (CtCmd->FsType) { 3047fcf3ce44SJohn Forte case 0xFC: /* Name server */ 3048fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3049fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3050fcf3ce44SJohn Forte "%s: %s %s", 3051fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 3052291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 305382527734SSukumar Swaminathan ULPSTATUS), 3054291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp. 3055291a2b48SSukumar Swaminathan perr.statLocalError)); 3056fcf3ce44SJohn Forte break; 3057fcf3ce44SJohn Forte 3058fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 3059fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3060fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3061fcf3ce44SJohn Forte "%s: %s %s", 3062fcf3ce44SJohn Forte emlxs_mscmd_xlate(cmd_code), 3063291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 306482527734SSukumar Swaminathan ULPSTATUS), 3065291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp. 3066291a2b48SSukumar Swaminathan perr.statLocalError)); 3067fcf3ce44SJohn Forte break; 3068fcf3ce44SJohn Forte 3069fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 3070fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3071fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3072fcf3ce44SJohn Forte "%s: %s %s", 3073fcf3ce44SJohn Forte emlxs_rmcmd_xlate(cmd_code), 3074291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 307582527734SSukumar Swaminathan ULPSTATUS), 3076291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp. 3077291a2b48SSukumar Swaminathan perr.statLocalError)); 3078fcf3ce44SJohn Forte break; 3079fcf3ce44SJohn Forte 3080fcf3ce44SJohn Forte default: 3081fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3082fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3083fcf3ce44SJohn Forte "%s: %s %s", 3084fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 3085291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 308682527734SSukumar Swaminathan ULPSTATUS), 3087291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp. 3088291a2b48SSukumar Swaminathan perr.statLocalError)); 3089fcf3ce44SJohn Forte } 3090fcf3ce44SJohn Forte } else { 3091fcf3ce44SJohn Forte switch (CtCmd->FsType) { 3092fcf3ce44SJohn Forte case 0xFC: /* Name server */ 3093fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3094fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3095fcf3ce44SJohn Forte "%s: %s (%02x%02x%02x%02x)", 3096fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 3097291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 309882527734SSukumar Swaminathan ULPSTATUS), 3099fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 3100fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 3101fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 3102291a2b48SSukumar Swaminathan iocb->un.grsp.perr. 3103291a2b48SSukumar Swaminathan statLocalError); 3104fcf3ce44SJohn Forte break; 3105fcf3ce44SJohn Forte 3106fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 3107fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3108fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3109fcf3ce44SJohn Forte "%s: %s (%02x%02x%02x%02x)", 3110fcf3ce44SJohn Forte emlxs_mscmd_xlate(cmd_code), 3111291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 311282527734SSukumar Swaminathan ULPSTATUS), 3113fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 3114fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 3115fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 3116291a2b48SSukumar Swaminathan iocb->un.grsp.perr. 3117291a2b48SSukumar Swaminathan statLocalError); 3118fcf3ce44SJohn Forte break; 3119fcf3ce44SJohn Forte 3120fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 3121fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3122fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3123fcf3ce44SJohn Forte "%s: %s (%02x%02x%02x%02x)", 3124fcf3ce44SJohn Forte emlxs_rmcmd_xlate(cmd_code), 3125291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 312682527734SSukumar Swaminathan ULPSTATUS), 3127fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 3128fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 3129fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 3130291a2b48SSukumar Swaminathan iocb->un.grsp.perr. 3131291a2b48SSukumar Swaminathan statLocalError); 3132fcf3ce44SJohn Forte break; 3133fcf3ce44SJohn Forte 3134fcf3ce44SJohn Forte default: 3135fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3136fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 3137fcf3ce44SJohn Forte "%s: %s (%02x%02x%02x%02x)", 3138fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 3139291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 314082527734SSukumar Swaminathan ULPSTATUS), 3141fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 3142fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 3143fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 3144291a2b48SSukumar Swaminathan iocb->un.grsp.perr. 3145291a2b48SSukumar Swaminathan statLocalError); 3146fcf3ce44SJohn Forte } 3147fcf3ce44SJohn Forte } 3148fcf3ce44SJohn Forte } 3149fcf3ce44SJohn Forte 315082527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 3151fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 3152fcf3ce44SJohn Forte 3153fcf3ce44SJohn Forte break; 3154fcf3ce44SJohn Forte 3155fcf3ce44SJohn Forte default: 3156fcf3ce44SJohn Forte 3157fcf3ce44SJohn Forte HBASTATS.CtStray++; 3158fcf3ce44SJohn Forte 3159fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg, 316082527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND); 3161fcf3ce44SJohn Forte 316282527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 3163fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 3164fcf3ce44SJohn Forte 3165fcf3ce44SJohn Forte break; 316682527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */ 3167fcf3ce44SJohn Forte 3168fcf3ce44SJohn Forte return (0); 3169fcf3ce44SJohn Forte 317082527734SSukumar Swaminathan } /* emlxs_ct_handle_event() */ 3171fcf3ce44SJohn Forte 3172fcf3ce44SJohn Forte 3173fcf3ce44SJohn Forte extern int 317482527734SSukumar Swaminathan emlxs_ct_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 3175fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 3176fcf3ce44SJohn Forte { 3177fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3178fcf3ce44SJohn Forte IOCB *iocb; 3179fcf3ce44SJohn Forte SLI_CT_REQUEST *CtCmd; 3180fcf3ce44SJohn Forte uint32_t cmd_code; 3181fcf3ce44SJohn Forte 3182fcf3ce44SJohn Forte iocb = &iocbq->iocb; 3183fcf3ce44SJohn Forte 3184fcf3ce44SJohn Forte CtCmd = (SLI_CT_REQUEST *)mp->virt; 318582527734SSukumar Swaminathan cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp); 3186fcf3ce44SJohn Forte 3187fcf3ce44SJohn Forte if (cmd_code == SLI_CT_LOOPBACK) { 3188fcf3ce44SJohn Forte int rval; 3189fcf3ce44SJohn Forte 319082527734SSukumar Swaminathan rval = emlxs_dfc_handle_unsol_req(port, cp, iocbq, mp, size); 3191fcf3ce44SJohn Forte 3192fcf3ce44SJohn Forte return (rval); 3193fcf3ce44SJohn Forte } 3194fcf3ce44SJohn Forte 3195fcf3ce44SJohn Forte HBASTATS.CtCmdReceived++; 3196fcf3ce44SJohn Forte 3197fcf3ce44SJohn Forte switch (CtCmd->FsType) { 3198fcf3ce44SJohn Forte case 0xFC: /* Name server */ 3199fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 3200291a2b48SSukumar Swaminathan "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code), 320182527734SSukumar Swaminathan CtCmd, size, iocb->ULPCONTEXT); 3202fcf3ce44SJohn Forte break; 3203fcf3ce44SJohn Forte 3204fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 3205fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 3206291a2b48SSukumar Swaminathan "%s: pl=%p size=%d rxid=%x", emlxs_mscmd_xlate(cmd_code), 320782527734SSukumar Swaminathan CtCmd, size, iocb->ULPCONTEXT); 3208fcf3ce44SJohn Forte break; 3209fcf3ce44SJohn Forte 3210fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 3211fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 3212291a2b48SSukumar Swaminathan "%s: pl=%p size=%d rxid=%x", emlxs_rmcmd_xlate(cmd_code), 321382527734SSukumar Swaminathan CtCmd, size, iocb->ULPCONTEXT); 3214fcf3ce44SJohn Forte break; 3215fcf3ce44SJohn Forte 3216fcf3ce44SJohn Forte default: 3217fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 3218291a2b48SSukumar Swaminathan "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code), 321982527734SSukumar Swaminathan CtCmd, size, iocb->ULPCONTEXT); 3220fcf3ce44SJohn Forte } 3221fcf3ce44SJohn Forte 3222728bdc9bSSukumar Swaminathan if (emlxs_log_ct_event(port, (uint8_t *)mp->virt, size, 322382527734SSukumar Swaminathan iocb->ULPCONTEXT)) { 3224728bdc9bSSukumar Swaminathan /* Abort the exchange */ 322582527734SSukumar Swaminathan emlxs_abort_ct_exchange(hba, port, iocb->ULPCONTEXT); 3226728bdc9bSSukumar Swaminathan } 3227fcf3ce44SJohn Forte 3228fcf3ce44SJohn Forte return (0); 3229fcf3ce44SJohn Forte 323082527734SSukumar Swaminathan } /* emlxs_ct_handle_unsol_req() */ 3231fcf3ce44SJohn Forte 3232fcf3ce44SJohn Forte 3233*a9800bebSGarrett D'Amore #if (EMLXS_MODREV < EMLXS_MODREV4) 3234fcf3ce44SJohn Forte static void 3235fcf3ce44SJohn Forte emlxs_send_rsnn(emlxs_port_t *port) 3236fcf3ce44SJohn Forte { 3237fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3238fcf3ce44SJohn Forte fc_packet_t *pkt; 3239fcf3ce44SJohn Forte SLI_CT_REQUEST *ct; 3240fcf3ce44SJohn Forte 3241291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, sizeof (SLI_CT_REQUEST), 3242291a2b48SSukumar Swaminathan sizeof (SLI_CT_REQUEST), 0, KM_NOSLEEP))) { 3243fcf3ce44SJohn Forte return; 3244fcf3ce44SJohn Forte } 3245291a2b48SSukumar Swaminathan 3246fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 3247fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 3248fcf3ce44SJohn Forte 3249fcf3ce44SJohn Forte /* Build the fc header */ 325082527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(NAMESERVER_DID); 3251fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL; 325282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 3253fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES; 3254291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 3255291a2b48SSukumar Swaminathan F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 3256fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3257fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3258fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3259fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 3260fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff; 3261fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3262fcf3ce44SJohn Forte 3263fcf3ce44SJohn Forte /* Build the command */ 3264fcf3ce44SJohn Forte ct = (SLI_CT_REQUEST *)pkt->pkt_cmd; 3265fcf3ce44SJohn Forte 3266fcf3ce44SJohn Forte ct->RevisionId.bits.Revision = SLI_CT_REVISION; 3267fcf3ce44SJohn Forte ct->RevisionId.bits.InId = 0; 3268fcf3ce44SJohn Forte 3269fcf3ce44SJohn Forte ct->FsType = SLI_CT_DIRECTORY_SERVICE; 3270fcf3ce44SJohn Forte ct->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER; 3271fcf3ce44SJohn Forte 3272fcf3ce44SJohn Forte ct->CommandResponse.bits.Size = 0; 327382527734SSukumar Swaminathan ct->CommandResponse.bits.CmdRsp = LE_SWAP16(SLI_CTNS_RSNN_NN); 3274fcf3ce44SJohn Forte 3275fcf3ce44SJohn Forte bcopy((uint8_t *)&hba->wwnn, (char *)ct->un.rsnn.wwnn, 8); 3276fcf3ce44SJohn Forte 3277fcf3ce44SJohn Forte ct->un.rsnn.snn_len = strlen(port->snn); 3278fcf3ce44SJohn Forte bcopy(port->snn, (char *)ct->un.rsnn.snn, ct->un.rsnn.snn_len); 3279fcf3ce44SJohn Forte 3280291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_send_msg, "Sending RSNN_NN. [%s]", 3281fcf3ce44SJohn Forte port->snn); 3282fcf3ce44SJohn Forte 3283fcf3ce44SJohn Forte /* Send the pkt later in another thread */ 3284fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 0) != FC_SUCCESS) { 3285fcf3ce44SJohn Forte /* Free the pkt */ 3286fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3287fcf3ce44SJohn Forte } 3288291a2b48SSukumar Swaminathan 3289fcf3ce44SJohn Forte return; 3290fcf3ce44SJohn Forte 329182527734SSukumar Swaminathan } /* emlxs_send_rsnn() */ 3292*a9800bebSGarrett D'Amore #endif /* < EMLXS_MODREV4 */ 3293*a9800bebSGarrett D'Amore 3294fcf3ce44SJohn Forte 3295fcf3ce44SJohn Forte 3296fcf3ce44SJohn Forte extern uint32_t 3297fcf3ce44SJohn Forte emlxs_ub_send_login_acc(emlxs_port_t *port, fc_unsol_buf_t *ubp) 3298fcf3ce44SJohn Forte { 3299fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3300fcf3ce44SJohn Forte fc_packet_t *pkt; 3301fcf3ce44SJohn Forte ELS_PKT *els; 3302fcf3ce44SJohn Forte uint32_t rval; 3303fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 3304fcf3ce44SJohn Forte 3305fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 3306fcf3ce44SJohn Forte 3307fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 3308fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (SERV_PARM), 0, 0, KM_NOSLEEP))) { 3309fcf3ce44SJohn Forte return (1); 3310fcf3ce44SJohn Forte } 3311291a2b48SSukumar Swaminathan 3312fcf3ce44SJohn Forte /* Common initialization */ 3313fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 3314fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 3315fcf3ce44SJohn Forte 3316fcf3ce44SJohn Forte if ((uint32_t)ubp->ub_class == FC_TRAN_CLASS2) { 3317fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 3318fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 3319fcf3ce44SJohn Forte } 3320291a2b48SSukumar Swaminathan 3321fcf3ce44SJohn Forte /* Build the fc header */ 3322fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = ubp->ub_frame.s_id; 3323291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 3324291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 3325fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = ubp->ub_frame.d_id; 3326fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 3327291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 3328291a2b48SSukumar Swaminathan F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 3329fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3330fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3331fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3332fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = (ub_priv->cmd >> ELS_CMD_SHIFT) & 0xff; 3333fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = ubp->ub_frame.rx_id; 3334fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3335fcf3ce44SJohn Forte 3336fcf3ce44SJohn Forte /* Build the command */ 3337291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_cmd; 3338fcf3ce44SJohn Forte els->elsCode = 0x02; 3339291a2b48SSukumar Swaminathan bcopy((void *)&port->sparam, (void *)&els->un.logi, 3340291a2b48SSukumar Swaminathan sizeof (SERV_PARM)); 3341fcf3ce44SJohn Forte 3342fcf3ce44SJohn Forte if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) { 3343fcf3ce44SJohn Forte /* Free the pkt */ 3344fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3345fcf3ce44SJohn Forte } else { 3346fcf3ce44SJohn Forte ub_priv->flags |= EMLXS_UB_INTERCEPT; 3347fcf3ce44SJohn Forte } 3348fcf3ce44SJohn Forte 3349fcf3ce44SJohn Forte return (rval); 3350fcf3ce44SJohn Forte 335182527734SSukumar Swaminathan } /* emlxs_ub_send_login_acc */ 3352fcf3ce44SJohn Forte 3353fcf3ce44SJohn Forte 3354fcf3ce44SJohn Forte extern void 3355fcf3ce44SJohn Forte emlxs_send_logo(emlxs_port_t *port, uint32_t d_id) 3356fcf3ce44SJohn Forte { 3357fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3358fcf3ce44SJohn Forte fc_packet_t *pkt; 3359fcf3ce44SJohn Forte ELS_PKT *els; 3360fcf3ce44SJohn Forte 3361fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 3362fcf3ce44SJohn Forte return; 3363fcf3ce44SJohn Forte } 3364291a2b48SSukumar Swaminathan 3365291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, 3366291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (LOGO), 3367fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (LOGO), 0, KM_NOSLEEP))) { 3368fcf3ce44SJohn Forte return; 3369fcf3ce44SJohn Forte } 3370291a2b48SSukumar Swaminathan 3371fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 3372fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 3373fcf3ce44SJohn Forte 3374fcf3ce44SJohn Forte /* Build the fc header */ 337582527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(d_id); 3376291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 3377291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 337882527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 3379fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 3380291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 3381291a2b48SSukumar Swaminathan F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 3382fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3383fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3384fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3385fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 3386fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff; 3387fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3388fcf3ce44SJohn Forte 3389fcf3ce44SJohn Forte /* Build the command */ 3390fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_cmd; 3391fcf3ce44SJohn Forte els->elsCode = 0x05; 3392fcf3ce44SJohn Forte els->un.logo.un.nPortId32 = pkt->pkt_cmd_fhdr.s_id; 3393291a2b48SSukumar Swaminathan bcopy((uint8_t *)&port->wwpn, (uint8_t *)&els->un.logo.portName, 3394291a2b48SSukumar Swaminathan 8); 3395fcf3ce44SJohn Forte 3396fcf3ce44SJohn Forte /* Send the pkt now */ 3397fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 3398fcf3ce44SJohn Forte /* Free the pkt */ 3399fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3400fcf3ce44SJohn Forte } 3401291a2b48SSukumar Swaminathan 3402fcf3ce44SJohn Forte return; 3403fcf3ce44SJohn Forte 3404fcf3ce44SJohn Forte } /* emlxs_send_logo() */ 3405