1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte 22fcf3ce44SJohn Forte /* 23291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24*82527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27*82527734SSukumar Swaminathan 28291a2b48SSukumar Swaminathan #include <emlxs.h> 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 31fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_ELS_C); 32fcf3ce44SJohn Forte 33291a2b48SSukumar Swaminathan static void emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp); 34291a2b48SSukumar Swaminathan static void emlxs_handle_sol_fdisk(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 40*82527734SSukumar Swaminathan static void emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp, 41291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 42*82527734SSukumar Swaminathan static void emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, 43291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 44*82527734SSukumar Swaminathan static void emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, 45291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 46*82527734SSukumar Swaminathan static void emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp, 47291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 48*82527734SSukumar Swaminathan static void emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp, 49291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 50*82527734SSukumar Swaminathan static void emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp, 51291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 52*82527734SSukumar Swaminathan static void emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp, 53291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 54*82527734SSukumar Swaminathan static void emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp, 55291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 56*82527734SSukumar Swaminathan static void emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp, 57291a2b48SSukumar Swaminathan IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 58291a2b48SSukumar Swaminathan static void emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, 59291a2b48SSukumar Swaminathan IOCBQ *iocbq, uint32_t flag); 60291a2b48SSukumar Swaminathan static void emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, 61291a2b48SSukumar Swaminathan IOCBQ *iocbq, uint32_t flag); 62291a2b48SSukumar Swaminathan static void emlxs_send_rsnn(emlxs_port_t *port); 63fcf3ce44SJohn Forte 64fcf3ce44SJohn Forte 65fcf3ce44SJohn Forte 66fcf3ce44SJohn Forte 67fcf3ce44SJohn Forte /* Routine Declaration - Local */ 68fcf3ce44SJohn Forte /* End Routine Declaration - Local */ 69fcf3ce44SJohn Forte 70fcf3ce44SJohn Forte /* 71fcf3ce44SJohn Forte * emlxs_els_handle_event 72fcf3ce44SJohn Forte * 73291a2b48SSukumar Swaminathan * Description: Process an ELS Response Ring cmpl 74fcf3ce44SJohn Forte * 75fcf3ce44SJohn Forte */ 76fcf3ce44SJohn Forte extern int 77*82527734SSukumar Swaminathan emlxs_els_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 78fcf3ce44SJohn Forte { 79fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 80fcf3ce44SJohn Forte IOCB *iocb; 81fcf3ce44SJohn Forte emlxs_buf_t *sbp; 82fcf3ce44SJohn Forte fc_packet_t *pkt; 83fcf3ce44SJohn Forte uint32_t *lp0; 84fcf3ce44SJohn Forte uint32_t command; 85fcf3ce44SJohn Forte NODELIST *ndlp; 86fcf3ce44SJohn Forte uint32_t did; 87fcf3ce44SJohn Forte ELS_PKT *els; 88fcf3ce44SJohn Forte 89fcf3ce44SJohn Forte iocb = &iocbq->iocb; 90fcf3ce44SJohn Forte 91fcf3ce44SJohn Forte HBASTATS.ElsEvent++; 92fcf3ce44SJohn Forte 93fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 94fcf3ce44SJohn Forte 95fcf3ce44SJohn Forte if (!sbp) { 96fcf3ce44SJohn Forte /* 97fcf3ce44SJohn Forte * completion with missing xmit command 98fcf3ce44SJohn Forte */ 99fcf3ce44SJohn Forte HBASTATS.ElsStray++; 100fcf3ce44SJohn Forte 101fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg, 102fcf3ce44SJohn Forte "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x", 103*82527734SSukumar Swaminathan iocbq, (uint32_t)iocb->ULPCOMMAND, 104*82527734SSukumar Swaminathan (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS, 105291a2b48SSukumar Swaminathan iocb->un.ulpWord[4]); 106fcf3ce44SJohn Forte 107fcf3ce44SJohn Forte return (1); 108fcf3ce44SJohn Forte } 109291a2b48SSukumar Swaminathan 110*82527734SSukumar Swaminathan if (cp->channelno != hba->channel_els) { 111fcf3ce44SJohn Forte HBASTATS.ElsStray++; 112fcf3ce44SJohn Forte 113fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg, 114*82527734SSukumar Swaminathan "Not ELS channel: channel=%d iocbq=%p cmd=0x%x iotag=0x%x " 115*82527734SSukumar Swaminathan "status=0x%x perr=0x%x", cp->channelno, iocbq, 116*82527734SSukumar Swaminathan (uint32_t)iocb->ULPCOMMAND, (uint32_t)iocb->ULPIOTAG, 117*82527734SSukumar Swaminathan iocb->ULPSTATUS, iocb->un.ulpWord[4]); 118fcf3ce44SJohn Forte 119fcf3ce44SJohn Forte return (1); 120fcf3ce44SJohn Forte } 121291a2b48SSukumar Swaminathan 122fcf3ce44SJohn Forte port = sbp->iocbq.port; 123fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 124fcf3ce44SJohn Forte lp0 = (uint32_t *)pkt->pkt_cmd; 125fcf3ce44SJohn Forte command = *lp0 & ELS_CMD_MASK; 126*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 127fcf3ce44SJohn Forte 128fcf3ce44SJohn Forte /* Check if a response buffer was provided */ 129fcf3ce44SJohn Forte if (pkt->pkt_rsplen) { 130*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen, 131fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 132fcf3ce44SJohn Forte } 133291a2b48SSukumar Swaminathan 134*82527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) { 135291a2b48SSukumar Swaminathan /* 136291a2b48SSukumar Swaminathan * ELS Reply completion 137291a2b48SSukumar Swaminathan */ 138fcf3ce44SJohn Forte case CMD_XMIT_ELS_RSP_CX: 139fcf3ce44SJohn Forte case CMD_XMIT_ELS_RSP64_CX: 140fcf3ce44SJohn Forte 141fcf3ce44SJohn Forte HBASTATS.ElsRspCompleted++; 142fcf3ce44SJohn Forte 143fcf3ce44SJohn Forte if (command == ELS_CMD_ACC) { 144fcf3ce44SJohn Forte emlxs_handle_acc(port, sbp, iocbq, 1); 145fcf3ce44SJohn Forte } else { 146fcf3ce44SJohn Forte emlxs_handle_reject(port, sbp, iocbq, 1); 147fcf3ce44SJohn Forte } 148fcf3ce44SJohn Forte 149fcf3ce44SJohn Forte break; 150fcf3ce44SJohn Forte 151291a2b48SSukumar Swaminathan /* 152291a2b48SSukumar Swaminathan * ELS command completion 153291a2b48SSukumar Swaminathan */ 154fcf3ce44SJohn Forte case CMD_ELS_REQUEST_CR: 155fcf3ce44SJohn Forte case CMD_ELS_REQUEST64_CR: 156fcf3ce44SJohn Forte case CMD_ELS_REQUEST_CX: 157fcf3ce44SJohn Forte case CMD_ELS_REQUEST64_CX: 158fcf3ce44SJohn Forte 159fcf3ce44SJohn Forte HBASTATS.ElsCmdCompleted++; 160fcf3ce44SJohn Forte 161fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_ELS_RSP_VALID; 162fcf3ce44SJohn Forte 163fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_resp; 164fcf3ce44SJohn Forte 165fcf3ce44SJohn Forte pkt->pkt_resp_resid = 166fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->un.elsreq64.bdl.bdeSize; 167fcf3ce44SJohn Forte pkt->pkt_data_resid = pkt->pkt_datalen; 168fcf3ce44SJohn Forte 169fcf3ce44SJohn Forte pkt->pkt_resp_fhdr.d_id = pkt->pkt_cmd_fhdr.s_id; 170fcf3ce44SJohn Forte pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id; 171fcf3ce44SJohn Forte 172*82527734SSukumar Swaminathan if ((iocb->ULPSTATUS == 0) && (els->elsCode == 0x02)) { 173fcf3ce44SJohn Forte HBASTATS.ElsCmdGood++; 174fcf3ce44SJohn Forte 175fcf3ce44SJohn Forte if (!(sbp->pkt_flags & PACKET_ALLOCATED)) { 176fcf3ce44SJohn Forte /* 177291a2b48SSukumar Swaminathan * ULP patch - ULP expects 178291a2b48SSukumar Swaminathan * resp_resid = 0 on success 179fcf3ce44SJohn Forte */ 180fcf3ce44SJohn Forte pkt->pkt_resp_resid = 0; 181fcf3ce44SJohn Forte } 182291a2b48SSukumar Swaminathan 183fcf3ce44SJohn Forte switch (command) { 184fcf3ce44SJohn Forte case ELS_CMD_FDISC: /* Fabric login */ 185fcf3ce44SJohn Forte emlxs_handle_sol_fdisk(port, sbp); 186fcf3ce44SJohn Forte 187fcf3ce44SJohn Forte break; 188fcf3ce44SJohn Forte 189fcf3ce44SJohn Forte case ELS_CMD_FLOGI: /* Fabric login */ 190fcf3ce44SJohn Forte emlxs_handle_sol_flogi(port, sbp); 191fcf3ce44SJohn Forte 192fcf3ce44SJohn Forte break; 193fcf3ce44SJohn Forte 194fcf3ce44SJohn Forte case ELS_CMD_PLOGI: /* NPort login */ 195fcf3ce44SJohn Forte emlxs_handle_sol_plogi(port, sbp); 196fcf3ce44SJohn Forte 197fcf3ce44SJohn Forte break; 198fcf3ce44SJohn Forte 199fcf3ce44SJohn Forte case ELS_CMD_ADISC: /* Adisc */ 200fcf3ce44SJohn Forte emlxs_handle_sol_adisc(port, sbp); 201fcf3ce44SJohn Forte 202fcf3ce44SJohn Forte break; 203fcf3ce44SJohn Forte 204fcf3ce44SJohn Forte case ELS_CMD_LOGO: /* Logout */ 205fcf3ce44SJohn Forte emlxs_handle_sol_logo(port, sbp); 206fcf3ce44SJohn Forte 207fcf3ce44SJohn Forte break; 208fcf3ce44SJohn Forte 209fcf3ce44SJohn Forte case ELS_CMD_PRLI: /* Process Log In */ 210fcf3ce44SJohn Forte emlxs_handle_sol_prli(port, sbp); 211fcf3ce44SJohn Forte 212fcf3ce44SJohn Forte break; 213fcf3ce44SJohn Forte 214fcf3ce44SJohn Forte default: 215fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 216291a2b48SSukumar Swaminathan &emlxs_els_completion_msg, "%s: did=%x", 217fcf3ce44SJohn Forte emlxs_elscmd_xlate(command), did); 218fcf3ce44SJohn Forte 219fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 220fcf3ce44SJohn Forte 221fcf3ce44SJohn Forte break; 222fcf3ce44SJohn Forte } 223fcf3ce44SJohn Forte 224fcf3ce44SJohn Forte } else { 225fcf3ce44SJohn Forte HBASTATS.ElsCmdError++; 226fcf3ce44SJohn Forte 227fcf3ce44SJohn Forte /* Look for LS_REJECT */ 228*82527734SSukumar Swaminathan if (iocb->ULPSTATUS == IOSTAT_LS_RJT) { 229fcf3ce44SJohn Forte pkt->pkt_state = FC_PKT_LS_RJT; 230fcf3ce44SJohn Forte pkt->pkt_action = FC_ACTION_RETRYABLE; 231fcf3ce44SJohn Forte pkt->pkt_reason = iocb->un.grsp.perr.statRsn; 232fcf3ce44SJohn Forte pkt->pkt_expln = iocb->un.grsp.perr.statBaExp; 233fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_STATE_VALID; 234fcf3ce44SJohn Forte 235291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 236291a2b48SSukumar Swaminathan ndlp = emlxs_node_find_did(port, did); 237291a2b48SSukumar Swaminathan if (ndlp) { 238291a2b48SSukumar Swaminathan emlxs_log_sd_lsrjt_event(port, 239291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_portname, 240291a2b48SSukumar Swaminathan command, pkt->pkt_reason, 241291a2b48SSukumar Swaminathan pkt->pkt_expln); 242291a2b48SSukumar Swaminathan } 243291a2b48SSukumar Swaminathan #endif 244291a2b48SSukumar Swaminathan 245fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 246fcf3ce44SJohn Forte &emlxs_els_completion_msg, 247fcf3ce44SJohn Forte "%s Rejected: did=%x rsn=%x exp=%x", 248fcf3ce44SJohn Forte emlxs_elscmd_xlate(command), did, 249fcf3ce44SJohn Forte pkt->pkt_reason, pkt->pkt_expln); 250*82527734SSukumar Swaminathan } else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) { 251fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 252fcf3ce44SJohn Forte &emlxs_bad_els_completion_msg, 253fcf3ce44SJohn Forte "%s: did=%x Local Reject. %s", 254fcf3ce44SJohn Forte emlxs_elscmd_xlate(command), did, 255291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 256291a2b48SSukumar Swaminathan statLocalError)); 257fcf3ce44SJohn Forte } else { 258fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 259fcf3ce44SJohn Forte &emlxs_bad_els_completion_msg, 260fcf3ce44SJohn Forte "%s: did=%x %s (%02x%02x%02x%02x)", 261fcf3ce44SJohn Forte emlxs_elscmd_xlate(command), did, 262*82527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 263fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 264fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 265fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 266fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError); 267fcf3ce44SJohn Forte } 268fcf3ce44SJohn Forte 269fcf3ce44SJohn Forte switch (command) { 270fcf3ce44SJohn Forte case ELS_CMD_PLOGI: /* NPort login failed */ 271fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 272fcf3ce44SJohn Forte 273fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 274fcf3ce44SJohn Forte /* Open the node again */ 275fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, 276*82527734SSukumar Swaminathan hba->channel_fcp); 277fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, 278*82527734SSukumar Swaminathan hba->channel_ip); 279fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 280fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_LS_RJT) { 281fcf3ce44SJohn Forte emlxs_dhc_state(port, ndlp, 282fcf3ce44SJohn Forte NODE_STATE_NOCHANGE, 283fcf3ce44SJohn Forte pkt->pkt_reason, 284fcf3ce44SJohn Forte pkt->pkt_expln); 285fcf3ce44SJohn Forte } 286291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 287fcf3ce44SJohn Forte } 288291a2b48SSukumar Swaminathan 289fcf3ce44SJohn Forte break; 290fcf3ce44SJohn Forte 291fcf3ce44SJohn Forte 292fcf3ce44SJohn Forte case ELS_CMD_PRLI: /* Process Log In failed */ 293fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 294fcf3ce44SJohn Forte 295fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 296fcf3ce44SJohn Forte /* Open the node again */ 297fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, 298*82527734SSukumar Swaminathan hba->channel_fcp); 299fcf3ce44SJohn Forte } 300291a2b48SSukumar Swaminathan 301fcf3ce44SJohn Forte break; 302fcf3ce44SJohn Forte 303fcf3ce44SJohn Forte case ELS_CMD_FDISC: /* Fabric login */ 304fcf3ce44SJohn Forte case ELS_CMD_FLOGI: /* Fabric login */ 305fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_LS_RJT) { 306291a2b48SSukumar Swaminathan /* This will cause ULP to retry */ 307291a2b48SSukumar Swaminathan /* FLOGI requests */ 308fcf3ce44SJohn Forte pkt->pkt_reason = FC_REASON_QFULL; 309fcf3ce44SJohn Forte pkt->pkt_expln = 0; 310fcf3ce44SJohn Forte 311fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 312fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 313fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 314fcf3ce44SJohn Forte emlxs_dhc_state(port, ndlp, 315fcf3ce44SJohn Forte NODE_STATE_NOCHANGE, 316fcf3ce44SJohn Forte pkt->pkt_reason, 317fcf3ce44SJohn Forte pkt->pkt_expln); 318fcf3ce44SJohn Forte } 319291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 320fcf3ce44SJohn Forte } 321291a2b48SSukumar Swaminathan 322fcf3ce44SJohn Forte break; 323fcf3ce44SJohn Forte 324fcf3ce44SJohn Forte default: 325fcf3ce44SJohn Forte break; 326fcf3ce44SJohn Forte } 327fcf3ce44SJohn Forte 328*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 329fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 330fcf3ce44SJohn Forte 331fcf3ce44SJohn Forte } 332fcf3ce44SJohn Forte 333fcf3ce44SJohn Forte 334fcf3ce44SJohn Forte break; 335fcf3ce44SJohn Forte 336fcf3ce44SJohn Forte default: 337fcf3ce44SJohn Forte 338fcf3ce44SJohn Forte HBASTATS.ElsStray++; 339fcf3ce44SJohn Forte 340fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_els_msg, 341*82527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND); 342fcf3ce44SJohn Forte 343*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 344fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 345fcf3ce44SJohn Forte 346fcf3ce44SJohn Forte break; 347*82527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */ 348fcf3ce44SJohn Forte 349fcf3ce44SJohn Forte return (0); 350fcf3ce44SJohn Forte 351*82527734SSukumar Swaminathan } /* emlxs_els_handle_event() */ 352fcf3ce44SJohn Forte 353fcf3ce44SJohn Forte 354fcf3ce44SJohn Forte extern int 355*82527734SSukumar Swaminathan emlxs_els_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 356fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 357fcf3ce44SJohn Forte { 358fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 359fcf3ce44SJohn Forte uint32_t cmd_code; 360fcf3ce44SJohn Forte 361fcf3ce44SJohn Forte HBASTATS.ElsCmdReceived++; 362fcf3ce44SJohn Forte 363fcf3ce44SJohn Forte cmd_code = *((uint32_t *)mp->virt) & ELS_CMD_MASK; 364fcf3ce44SJohn Forte 365*82527734SSukumar Swaminathan if (!(port->flag & EMLXS_PORT_BOUND)) { 366*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_els_msg, 367*82527734SSukumar Swaminathan "ELS rcvd (0x%x): sid=%x Port not bound: Rejecting.", 368*82527734SSukumar Swaminathan cmd_code, iocbq->iocb.un.elsreq.remoteID); 369*82527734SSukumar Swaminathan 370*82527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 371*82527734SSukumar Swaminathan ELS_CMD_RSCN, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 372*82527734SSukumar Swaminathan 373*82527734SSukumar Swaminathan return (0); 374*82527734SSukumar Swaminathan } 375*82527734SSukumar Swaminathan 376fcf3ce44SJohn Forte switch (cmd_code) { 377fcf3ce44SJohn Forte case ELS_CMD_RSCN: 378fcf3ce44SJohn Forte HBASTATS.ElsRscnReceived++; 379*82527734SSukumar Swaminathan emlxs_handle_unsol_rscn(port, cp, iocbq, mp, size); 380fcf3ce44SJohn Forte break; 381fcf3ce44SJohn Forte 382fcf3ce44SJohn Forte case ELS_CMD_FLOGI: 383fcf3ce44SJohn Forte HBASTATS.ElsFlogiReceived++; 384*82527734SSukumar Swaminathan emlxs_handle_unsol_flogi(port, cp, iocbq, mp, size); 385fcf3ce44SJohn Forte break; 386fcf3ce44SJohn Forte 387fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 388fcf3ce44SJohn Forte HBASTATS.ElsPlogiReceived++; 389*82527734SSukumar Swaminathan emlxs_handle_unsol_plogi(port, cp, iocbq, mp, size); 390fcf3ce44SJohn Forte break; 391fcf3ce44SJohn Forte 392fcf3ce44SJohn Forte case ELS_CMD_PRLI: 393fcf3ce44SJohn Forte HBASTATS.ElsPrliReceived++; 394*82527734SSukumar Swaminathan emlxs_handle_unsol_prli(port, cp, iocbq, mp, size); 395fcf3ce44SJohn Forte break; 396fcf3ce44SJohn Forte 397fcf3ce44SJohn Forte case ELS_CMD_PRLO: 398fcf3ce44SJohn Forte HBASTATS.ElsPrloReceived++; 399*82527734SSukumar Swaminathan emlxs_handle_unsol_prlo(port, cp, iocbq, mp, size); 400fcf3ce44SJohn Forte break; 401fcf3ce44SJohn Forte 402fcf3ce44SJohn Forte case ELS_CMD_LOGO: 403fcf3ce44SJohn Forte HBASTATS.ElsLogoReceived++; 404*82527734SSukumar Swaminathan emlxs_handle_unsol_logo(port, cp, iocbq, mp, size); 405fcf3ce44SJohn Forte break; 406fcf3ce44SJohn Forte 407fcf3ce44SJohn Forte case ELS_CMD_ADISC: 408fcf3ce44SJohn Forte HBASTATS.ElsAdiscReceived++; 409*82527734SSukumar Swaminathan emlxs_handle_unsol_adisc(port, cp, iocbq, mp, size); 410fcf3ce44SJohn Forte break; 411fcf3ce44SJohn Forte 412fcf3ce44SJohn Forte case ELS_CMD_AUTH: 413fcf3ce44SJohn Forte HBASTATS.ElsAuthReceived++; 414*82527734SSukumar Swaminathan emlxs_handle_unsol_auth(port, cp, iocbq, mp, size); 415fcf3ce44SJohn Forte break; 416fcf3ce44SJohn Forte 417fcf3ce44SJohn Forte default: 418fcf3ce44SJohn Forte HBASTATS.ElsGenReceived++; 419*82527734SSukumar Swaminathan emlxs_handle_unsol_gen_cmd(port, cp, iocbq, mp, size); 420fcf3ce44SJohn Forte break; 421fcf3ce44SJohn Forte } 422fcf3ce44SJohn Forte 423fcf3ce44SJohn Forte return (0); 424fcf3ce44SJohn Forte 425*82527734SSukumar Swaminathan } /* emlxs_els_handle_unsol_req() */ 426fcf3ce44SJohn Forte 427fcf3ce44SJohn Forte 428fcf3ce44SJohn Forte static void 429fcf3ce44SJohn Forte emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp) 430fcf3ce44SJohn Forte { 431fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 432fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 433fcf3ce44SJohn Forte emlxs_port_t *vport; 434fcf3ce44SJohn Forte SERV_PARM *sp; 435fcf3ce44SJohn Forte fc_packet_t *pkt; 436fcf3ce44SJohn Forte MAILBOXQ *mbox; 437fcf3ce44SJohn Forte uint32_t did; 438fcf3ce44SJohn Forte IOCBQ *iocbq; 439fcf3ce44SJohn Forte IOCB *iocb; 440fcf3ce44SJohn Forte char buffer[64]; 441fcf3ce44SJohn Forte uint32_t i; 442*82527734SSukumar Swaminathan int rc; 443fcf3ce44SJohn Forte 444fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 445fcf3ce44SJohn Forte sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t)); 446*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 447fcf3ce44SJohn Forte iocbq = &sbp->iocbq; 448fcf3ce44SJohn Forte iocb = &iocbq->iocb; 449fcf3ce44SJohn Forte 450fcf3ce44SJohn Forte if (sp->cmn.fPort) { 451fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 452fcf3ce44SJohn Forte 453fcf3ce44SJohn Forte hba->flag |= FC_FABRIC_ATTACHED; 454fcf3ce44SJohn Forte hba->flag &= ~FC_PT_TO_PT; 455fcf3ce44SJohn Forte 456fcf3ce44SJohn Forte /* Save our new port ID */ 457fcf3ce44SJohn Forte port->did = iocb->un.elsreq.myID; 458*82527734SSukumar Swaminathan pkt->pkt_resp_fhdr.s_id = LE_SWAP24_LO(FABRIC_DID); 459*82527734SSukumar Swaminathan pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did); 460fcf3ce44SJohn Forte 461fcf3ce44SJohn Forte /* Save E_D_TOV ticks in nanoseconds */ 462fcf3ce44SJohn Forte if (sp->cmn.edtovResolution) { 463fcf3ce44SJohn Forte hba->fc_edtov = 464*82527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000; 465fcf3ce44SJohn Forte } else { 466*82527734SSukumar Swaminathan hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov); 467fcf3ce44SJohn Forte } 468fcf3ce44SJohn Forte 469fcf3ce44SJohn Forte /* Save R_A_TOV ticks */ 470291a2b48SSukumar Swaminathan hba->fc_ratov = 471*82527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000; 472fcf3ce44SJohn Forte 473fcf3ce44SJohn Forte if (hba->topology != TOPOLOGY_LOOP) { 474fcf3ce44SJohn Forte /* 475291a2b48SSukumar Swaminathan * If we are a N-port connected to a Fabric, 476291a2b48SSukumar Swaminathan * fixup sparam's so logins to devices on remote 477291a2b48SSukumar Swaminathan * loops work. 478fcf3ce44SJohn Forte */ 479fcf3ce44SJohn Forte hba->sparam.cmn.altBbCredit = 1; 480fcf3ce44SJohn Forte 481fcf3ce44SJohn Forte /* Set this bit in all the port sparam copies */ 482fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 483fcf3ce44SJohn Forte vport = &VPORT(i); 484fcf3ce44SJohn Forte 485fcf3ce44SJohn Forte if (!(vport->flag & EMLXS_PORT_BOUND)) { 486fcf3ce44SJohn Forte continue; 487fcf3ce44SJohn Forte } 488291a2b48SSukumar Swaminathan 489fcf3ce44SJohn Forte vport->sparam.cmn.altBbCredit = 1; 490fcf3ce44SJohn Forte } 491fcf3ce44SJohn Forte } 492*82527734SSukumar Swaminathan 493fcf3ce44SJohn Forte if (sp->cmn.rspMultipleNPort) { 494fcf3ce44SJohn Forte hba->flag |= FC_NPIV_SUPPORTED; 495fcf3ce44SJohn Forte 496fcf3ce44SJohn Forte if (cfg[CFG_NPIV_DELAY].current) { 497fcf3ce44SJohn Forte /* 498291a2b48SSukumar Swaminathan * PATCH: for NPIV support on 499291a2b48SSukumar Swaminathan * Brocade switch firmware 5.10b 500fcf3ce44SJohn Forte */ 501fcf3ce44SJohn Forte if ((hba->flag & FC_NPIV_ENABLED) && 502fcf3ce44SJohn Forte ((sp->nodeName.IEEE[0] == 0x00) && 503fcf3ce44SJohn Forte (sp->nodeName.IEEE[1] == 0x05) && 504fcf3ce44SJohn Forte (sp->nodeName.IEEE[2] == 0x1e))) { 505fcf3ce44SJohn Forte hba->flag |= FC_NPIV_DELAY_REQUIRED; 506fcf3ce44SJohn Forte } 507fcf3ce44SJohn Forte } 508fcf3ce44SJohn Forte } else { 509fcf3ce44SJohn Forte hba->flag |= FC_NPIV_UNSUPPORTED; 510fcf3ce44SJohn Forte } 511fcf3ce44SJohn Forte 512fcf3ce44SJohn Forte if (!(hba->flag & FC_NPIV_ENABLED)) { 513fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Disabled "); 514fcf3ce44SJohn Forte } else if (hba->flag & FC_NPIV_SUPPORTED) { 515fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Supported "); 516fcf3ce44SJohn Forte } else { 517fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Unsupported "); 518fcf3ce44SJohn Forte } 519fcf3ce44SJohn Forte 520fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 521fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 522fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 523fcf3ce44SJohn Forte } else if (cfg[CFG_AUTH_ENABLE].current && 524fcf3ce44SJohn Forte (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) { 525fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 526fcf3ce44SJohn Forte } else { 527fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 528fcf3ce44SJohn Forte } 529291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 530fcf3ce44SJohn Forte 531fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 532fcf3ce44SJohn Forte 533fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 534291a2b48SSukumar Swaminathan "FLOGI: did=%x sid=%x %s", did, port->did, buffer); 535fcf3ce44SJohn Forte 536fcf3ce44SJohn Forte /* Update our service parms */ 537*82527734SSukumar Swaminathan if (!(mbox = (MAILBOXQ *)emlxs_mem_get(hba, 538*82527734SSukumar Swaminathan MEM_MBOX, 1))) { 539*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 540*82527734SSukumar Swaminathan IOERR_NO_RESOURCES, 1); 541*82527734SSukumar Swaminathan return; 542*82527734SSukumar Swaminathan 543*82527734SSukumar Swaminathan } 544*82527734SSukumar Swaminathan 545*82527734SSukumar Swaminathan /* For SLI4 we replace CONFIG_LINK and REG_LOGIN of */ 546*82527734SSukumar Swaminathan /* Fabric with a REG_VFI mailbox command. */ 547*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 548*82527734SSukumar Swaminathan emlxs_port_t *vpip = sbp->port; 549*82527734SSukumar Swaminathan VFIobj_t *vfip; 550*82527734SSukumar Swaminathan FCFIobj_t *fcfp; 551*82527734SSukumar Swaminathan uint32_t regvfi; 552*82527734SSukumar Swaminathan 553*82527734SSukumar Swaminathan vfip = vpip->VFIp; 554*82527734SSukumar Swaminathan fcfp = vfip->FCFIp; 555*82527734SSukumar Swaminathan regvfi = vfip->state & RESOURCE_VFI_REG; 556fcf3ce44SJohn Forte 557*82527734SSukumar Swaminathan /* Save the FCF service parameters */ 558*82527734SSukumar Swaminathan bcopy((void *)sp, (void *)&fcfp->fcf_sparam, 559*82527734SSukumar Swaminathan sizeof (SERV_PARM)); 560*82527734SSukumar Swaminathan 561*82527734SSukumar Swaminathan if (emlxs_mb_check_sparm(hba, sp)) { 562*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 563*82527734SSukumar Swaminathan &emlxs_node_create_failed_msg, 564*82527734SSukumar Swaminathan "Invalid Fabric parameters. did=%06x", 565*82527734SSukumar Swaminathan port->did); 566fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, 567fcf3ce44SJohn Forte (uint8_t *)mbox); 568*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 569*82527734SSukumar Swaminathan IOERR_NO_RESOURCES, 1); 570*82527734SSukumar Swaminathan return; 571*82527734SSukumar Swaminathan } 572*82527734SSukumar Swaminathan 573*82527734SSukumar Swaminathan if (!regvfi) { 574*82527734SSukumar Swaminathan if (emlxs_mb_reg_vfi(hba, mbox, vfip, vpip) == 575*82527734SSukumar Swaminathan 0) { 576*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 577*82527734SSukumar Swaminathan &emlxs_sli_detail_msg, 578*82527734SSukumar Swaminathan "Cannot REG_VFI for FCF: sid=%x", 579*82527734SSukumar Swaminathan port->did); 580*82527734SSukumar Swaminathan 581*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, 582*82527734SSukumar Swaminathan (uint8_t *)mbox); 583*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, 584*82527734SSukumar Swaminathan IOSTAT_LOCAL_REJECT, 585*82527734SSukumar Swaminathan IOERR_NO_RESOURCES, 1); 586*82527734SSukumar Swaminathan return; 587*82527734SSukumar Swaminathan } 588*82527734SSukumar Swaminathan mbox->sbp = (uint8_t *)sbp; 589*82527734SSukumar Swaminathan 590*82527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, 591*82527734SSukumar Swaminathan MBX_NOWAIT, 0); 592*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 593*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 594*82527734SSukumar Swaminathan &emlxs_sli_detail_msg, 595*82527734SSukumar Swaminathan "Cannot REG_VFI for FCF: sid=%x", 596*82527734SSukumar Swaminathan port->did); 597*82527734SSukumar Swaminathan 598*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, 599*82527734SSukumar Swaminathan (uint8_t *)mbox); 600*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, 601*82527734SSukumar Swaminathan IOSTAT_LOCAL_REJECT, 602*82527734SSukumar Swaminathan IOERR_NO_RESOURCES, 1); 603*82527734SSukumar Swaminathan return; 604*82527734SSukumar Swaminathan } 605*82527734SSukumar Swaminathan /* Preset the state for the REG_VFI cmpl */ 606*82527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 607*82527734SSukumar Swaminathan 608*82527734SSukumar Swaminathan /* Deferred completion of this pkt until */ 609*82527734SSukumar Swaminathan /* REG_VFI is complete */ 610*82527734SSukumar Swaminathan return; 611fcf3ce44SJohn Forte } 612*82527734SSukumar Swaminathan /* VFI is already Registered */ 613291a2b48SSukumar Swaminathan 614*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox); 615*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 616*82527734SSukumar Swaminathan 617*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_READY); 618*82527734SSukumar Swaminathan if (regvfi) { 619*82527734SSukumar Swaminathan /* 620*82527734SSukumar Swaminathan * If NPIV Fabric support has just been 621*82527734SSukumar Swaminathan * established on the physical port, then 622*82527734SSukumar Swaminathan * notify the vports of the link up. 623*82527734SSukumar Swaminathan */ 624*82527734SSukumar Swaminathan if ((hba->flag & FC_NPIV_ENABLED) && 625*82527734SSukumar Swaminathan (hba->flag & FC_NPIV_SUPPORTED)) { 626*82527734SSukumar Swaminathan /* Skip the physical port */ 627*82527734SSukumar Swaminathan for (i = 1; i < MAX_VPORTS; i++) { 628*82527734SSukumar Swaminathan vport = &VPORT(i); 629*82527734SSukumar Swaminathan 630*82527734SSukumar Swaminathan if (!(vport->flag & 631*82527734SSukumar Swaminathan EMLXS_PORT_BOUND) || 632*82527734SSukumar Swaminathan !(vport->flag & 633*82527734SSukumar Swaminathan EMLXS_PORT_ENABLE)) { 634*82527734SSukumar Swaminathan continue; 635*82527734SSukumar Swaminathan } 636*82527734SSukumar Swaminathan 637*82527734SSukumar Swaminathan emlxs_port_online(vport); 638*82527734SSukumar Swaminathan } 639*82527734SSukumar Swaminathan } 640*82527734SSukumar Swaminathan } 641*82527734SSukumar Swaminathan return; 642*82527734SSukumar Swaminathan } 643*82527734SSukumar Swaminathan 644*82527734SSukumar Swaminathan /* Save the fabric service parameters */ 645*82527734SSukumar Swaminathan bcopy((void *)sp, (void *)&port->fabric_sparam, 646*82527734SSukumar Swaminathan sizeof (SERV_PARM)); 647*82527734SSukumar Swaminathan 648*82527734SSukumar Swaminathan emlxs_mb_config_link(hba, mbox); 649*82527734SSukumar Swaminathan 650*82527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0); 651*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 652*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox); 653fcf3ce44SJohn Forte } 654291a2b48SSukumar Swaminathan 655fcf3ce44SJohn Forte /* Preset the state for the reg_did */ 656fcf3ce44SJohn Forte emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 657fcf3ce44SJohn Forte 658*82527734SSukumar Swaminathan if (emlxs_mb_reg_did(port, FABRIC_DID, &port->fabric_sparam, 659fcf3ce44SJohn Forte sbp, NULL, NULL) == 0) { 660291a2b48SSukumar Swaminathan /* Deferred completion of this pkt until */ 661291a2b48SSukumar Swaminathan /* login is complete */ 662fcf3ce44SJohn Forte return; 663fcf3ce44SJohn Forte } 664291a2b48SSukumar Swaminathan 665fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 666fcf3ce44SJohn Forte IOERR_NO_RESOURCES, 1); 667fcf3ce44SJohn Forte 668fcf3ce44SJohn Forte } else { /* No switch */ 669291a2b48SSukumar Swaminathan 670fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 671fcf3ce44SJohn Forte 672fcf3ce44SJohn Forte hba->flag &= ~FC_FABRIC_ATTACHED; 673fcf3ce44SJohn Forte hba->flag |= FC_PT_TO_PT; 674fcf3ce44SJohn Forte 675fcf3ce44SJohn Forte /* Save E_D_TOV ticks in nanoseconds */ 676fcf3ce44SJohn Forte if (sp->cmn.edtovResolution) { 677fcf3ce44SJohn Forte hba->fc_edtov = 678*82527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000; 679fcf3ce44SJohn Forte } else { 680*82527734SSukumar Swaminathan hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov); 681fcf3ce44SJohn Forte } 682fcf3ce44SJohn Forte 683fcf3ce44SJohn Forte /* Save R_A_TOV ticks */ 684291a2b48SSukumar Swaminathan hba->fc_ratov = 685*82527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000; 686fcf3ce44SJohn Forte 687fcf3ce44SJohn Forte hba->flag &= ~FC_NPIV_SUPPORTED; 688fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Disabled. P2P"); 689*82527734SSukumar Swaminathan 690*82527734SSukumar Swaminathan port->rdid = did; 691fcf3ce44SJohn Forte 692fcf3ce44SJohn Forte /* Clear the fabric service parameters */ 693fcf3ce44SJohn Forte bzero((void *)&port->fabric_sparam, sizeof (SERV_PARM)); 694fcf3ce44SJohn Forte 695fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 696fcf3ce44SJohn Forte 697fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 698291a2b48SSukumar Swaminathan "FLOGI: did=%x sid=%x %s", did, port->did, buffer); 699fcf3ce44SJohn Forte 700fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 701fcf3ce44SJohn Forte } 702fcf3ce44SJohn Forte 703fcf3ce44SJohn Forte return; 704fcf3ce44SJohn Forte 705*82527734SSukumar Swaminathan } /* emlxs_handle_sol_flogi() */ 706fcf3ce44SJohn Forte 707fcf3ce44SJohn Forte 708fcf3ce44SJohn Forte static void 709fcf3ce44SJohn Forte emlxs_handle_sol_fdisk(emlxs_port_t *port, emlxs_buf_t *sbp) 710fcf3ce44SJohn Forte { 711fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 712fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 713fcf3ce44SJohn Forte SERV_PARM *sp; 714fcf3ce44SJohn Forte fc_packet_t *pkt; 715fcf3ce44SJohn Forte MAILBOXQ *mbox; 716fcf3ce44SJohn Forte uint32_t did; 717fcf3ce44SJohn Forte IOCBQ *iocbq; 718fcf3ce44SJohn Forte IOCB *iocb; 719fcf3ce44SJohn Forte char buffer[64]; 720*82527734SSukumar Swaminathan int rc; 721fcf3ce44SJohn Forte 722fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 723fcf3ce44SJohn Forte sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t)); 724*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 725fcf3ce44SJohn Forte iocbq = &sbp->iocbq; 726fcf3ce44SJohn Forte iocb = &iocbq->iocb; 727fcf3ce44SJohn Forte 728fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 729fcf3ce44SJohn Forte 730fcf3ce44SJohn Forte /* Save our new port ID */ 731fcf3ce44SJohn Forte port->did = iocb->un.elsreq.myID; 732*82527734SSukumar Swaminathan pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did); 733fcf3ce44SJohn Forte 734fcf3ce44SJohn Forte /* Save the fabric service parameters */ 735fcf3ce44SJohn Forte bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM)); 736fcf3ce44SJohn Forte 737fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 738fcf3ce44SJohn Forte 739fcf3ce44SJohn Forte buffer[0] = 0; 740fcf3ce44SJohn Forte 741fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 742fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 743fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 744291a2b48SSukumar Swaminathan } else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_NPIV].current) { 745fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 746fcf3ce44SJohn Forte } else { 747fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 748fcf3ce44SJohn Forte } 749291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 750fcf3ce44SJohn Forte 751fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 752291a2b48SSukumar Swaminathan "FDISK: did=%x sid=%x %s", did, port->did, buffer); 753fcf3ce44SJohn Forte 754*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 755*82527734SSukumar Swaminathan emlxs_port_t *pport = &PPORT; 756*82527734SSukumar Swaminathan 757*82527734SSukumar Swaminathan port->VFIp = pport->VFIp; 758*82527734SSukumar Swaminathan 759*82527734SSukumar Swaminathan if (emlxs_mb_check_sparm(hba, sp)) { 760*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 761*82527734SSukumar Swaminathan &emlxs_node_create_failed_msg, 762*82527734SSukumar Swaminathan "Invalid Fabric parameters. did=%06x", 763*82527734SSukumar Swaminathan port->did); 764*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 765*82527734SSukumar Swaminathan IOERR_NO_RESOURCES, 1); 766*82527734SSukumar Swaminathan return; 767*82527734SSukumar Swaminathan } 768*82527734SSukumar Swaminathan 769*82527734SSukumar Swaminathan /* Preset the state for the REG_VFI cmpl */ 770*82527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 771*82527734SSukumar Swaminathan 772*82527734SSukumar Swaminathan if (port->flag & EMLXS_PORT_REG_VPI_CMPL) { 773*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, -1, 0, 1); 774*82527734SSukumar Swaminathan } else { 775*82527734SSukumar Swaminathan /* Deferred completion of this pkt until */ 776*82527734SSukumar Swaminathan /* REG_VPI is complete */ 777*82527734SSukumar Swaminathan (void) emlxs_mb_reg_vpi(port, sbp); 778*82527734SSukumar Swaminathan } 779*82527734SSukumar Swaminathan 780*82527734SSukumar Swaminathan return; 781*82527734SSukumar Swaminathan } 782*82527734SSukumar Swaminathan 783fcf3ce44SJohn Forte /* Update our service parms */ 784*82527734SSukumar Swaminathan if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) { 785*82527734SSukumar Swaminathan emlxs_mb_config_link(hba, mbox); 786fcf3ce44SJohn Forte 787*82527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, 788*82527734SSukumar Swaminathan MBX_NOWAIT, 0); 789*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 790fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox); 791fcf3ce44SJohn Forte } 792fcf3ce44SJohn Forte } 793291a2b48SSukumar Swaminathan 794fcf3ce44SJohn Forte /* Preset the state for the reg_did */ 795fcf3ce44SJohn Forte emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 796fcf3ce44SJohn Forte 797*82527734SSukumar Swaminathan if (emlxs_mb_reg_did(port, FABRIC_DID, &port->fabric_sparam, sbp, 798fcf3ce44SJohn Forte NULL, NULL) == 0) { 799fcf3ce44SJohn Forte /* 800fcf3ce44SJohn Forte * Deferred completion of this pkt until login is complete 801fcf3ce44SJohn Forte */ 802fcf3ce44SJohn Forte 803fcf3ce44SJohn Forte return; 804fcf3ce44SJohn Forte } 805291a2b48SSukumar Swaminathan 806fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1); 807fcf3ce44SJohn Forte 808fcf3ce44SJohn Forte return; 809fcf3ce44SJohn Forte 810*82527734SSukumar Swaminathan } /* emlxs_handle_sol_fdisk() */ 811fcf3ce44SJohn Forte 812fcf3ce44SJohn Forte 813fcf3ce44SJohn Forte static void 814fcf3ce44SJohn Forte emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp) 815fcf3ce44SJohn Forte { 816fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 817fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 818fcf3ce44SJohn Forte SERV_PARM *sp; 819fcf3ce44SJohn Forte fc_packet_t *pkt; 820fcf3ce44SJohn Forte uint32_t did; 821fcf3ce44SJohn Forte uint32_t sid; 822fcf3ce44SJohn Forte NODELIST *ndlp; 823fcf3ce44SJohn Forte char buffer[64]; 824fcf3ce44SJohn Forte 825fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 826fcf3ce44SJohn Forte sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t)); 827*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 828*82527734SSukumar Swaminathan sid = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.s_id); 829fcf3ce44SJohn Forte 830fcf3ce44SJohn Forte buffer[0] = 0; 831fcf3ce44SJohn Forte 832fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 833fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 834fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 835fcf3ce44SJohn Forte } else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current && 836fcf3ce44SJohn Forte (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) { 837fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 838fcf3ce44SJohn Forte } else { 839fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 840fcf3ce44SJohn Forte } 841291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 842fcf3ce44SJohn Forte 843fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 844291a2b48SSukumar Swaminathan "PLOGI: sid=%x did=%x %s", sid, did, buffer); 845fcf3ce44SJohn Forte 846fcf3ce44SJohn Forte /* Preset the pkt state for reg_did */ 847fcf3ce44SJohn Forte emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1); 848fcf3ce44SJohn Forte 849fcf3ce44SJohn Forte /* 850fcf3ce44SJohn Forte * Do register login to Firmware before calling packet completion 851fcf3ce44SJohn Forte */ 852fcf3ce44SJohn Forte if (emlxs_mb_reg_did(port, did, sp, sbp, NULL, NULL) == 0) { 853fcf3ce44SJohn Forte /* 854fcf3ce44SJohn Forte * Deferred completion of this pkt until login is complete 855fcf3ce44SJohn Forte */ 856fcf3ce44SJohn Forte return; 857fcf3ce44SJohn Forte } 858291a2b48SSukumar Swaminathan 859fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 860fcf3ce44SJohn Forte 861fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 862fcf3ce44SJohn Forte /* Open the node again */ 863*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 864*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_ip); 865fcf3ce44SJohn Forte } 866291a2b48SSukumar Swaminathan 867fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1); 868fcf3ce44SJohn Forte 869fcf3ce44SJohn Forte return; 870fcf3ce44SJohn Forte 871*82527734SSukumar Swaminathan } /* emlxs_handle_sol_plogi() */ 872fcf3ce44SJohn Forte 873fcf3ce44SJohn Forte 874fcf3ce44SJohn Forte static void 875fcf3ce44SJohn Forte emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp) 876fcf3ce44SJohn Forte { 877*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 878fcf3ce44SJohn Forte fc_packet_t *pkt; 879fcf3ce44SJohn Forte uint32_t did; 880fcf3ce44SJohn Forte NODELIST *ndlp; 881*82527734SSukumar Swaminathan RPIobj_t *rp; 882fcf3ce44SJohn Forte 883fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 884*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 885fcf3ce44SJohn Forte 886291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "ADISC: did=%x", 887fcf3ce44SJohn Forte did); 888fcf3ce44SJohn Forte 889fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 890fcf3ce44SJohn Forte 891fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 892fcf3ce44SJohn Forte /* Open the node again */ 893*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 894*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_ip); 895*82527734SSukumar Swaminathan 896*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 897*82527734SSukumar Swaminathan rp = emlxs_sli4_find_rpi(hba, ndlp->nlp_Rpi); 898*82527734SSukumar Swaminathan if (rp && (rp->state & RESOURCE_RPI_PAUSED)) { 899*82527734SSukumar Swaminathan (void) emlxs_mb_resume_rpi(hba, sbp, 900*82527734SSukumar Swaminathan ndlp->nlp_Rpi); 901*82527734SSukumar Swaminathan rp->state &= ~RESOURCE_RPI_PAUSED; 902*82527734SSukumar Swaminathan /* 903*82527734SSukumar Swaminathan * Delay ADISC cmpl to ULP till 904*82527734SSukumar Swaminathan * after RESUME_RPI 905*82527734SSukumar Swaminathan */ 906*82527734SSukumar Swaminathan return; 907*82527734SSukumar Swaminathan } 908*82527734SSukumar Swaminathan } 909fcf3ce44SJohn Forte } 910291a2b48SSukumar Swaminathan 911fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 912fcf3ce44SJohn Forte 913fcf3ce44SJohn Forte return; 914fcf3ce44SJohn Forte 915*82527734SSukumar Swaminathan } /* emlxs_handle_sol_adisc() */ 916fcf3ce44SJohn Forte 917fcf3ce44SJohn Forte 918fcf3ce44SJohn Forte static void 919fcf3ce44SJohn Forte emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp) 920fcf3ce44SJohn Forte { 921fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 922fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 923fcf3ce44SJohn Forte fc_packet_t *pkt; 924fcf3ce44SJohn Forte NODELIST *ndlp; 925fcf3ce44SJohn Forte uint32_t did; 926fcf3ce44SJohn Forte PRLI *npr; 927fcf3ce44SJohn Forte uint32_t task_retry_id; 928fcf3ce44SJohn Forte 929fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 930fcf3ce44SJohn Forte npr = (PRLI *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t)); 931*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 932fcf3ce44SJohn Forte 933fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 934fcf3ce44SJohn Forte 935fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 936fcf3ce44SJohn Forte /* Check for FCP support */ 937fcf3ce44SJohn Forte if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) && 938fcf3ce44SJohn Forte (npr->prliType == PRLI_FCP_TYPE)) { 939fcf3ce44SJohn Forte /* Check for target */ 940fcf3ce44SJohn Forte if (npr->targetFunc) { 941fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE; 942fcf3ce44SJohn Forte } else { 943fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE; 944fcf3ce44SJohn Forte } 945fcf3ce44SJohn Forte 946fcf3ce44SJohn Forte /* Check for initiator */ 947fcf3ce44SJohn Forte if (npr->initiatorFunc) { 948fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE; 949fcf3ce44SJohn Forte } else { 950fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE; 951fcf3ce44SJohn Forte } 952fcf3ce44SJohn Forte 953291a2b48SSukumar Swaminathan /* If TRI support is not required then force */ 954291a2b48SSukumar Swaminathan /* the task_retry_id value to one */ 955fcf3ce44SJohn Forte if (cfg[CFG_TRI_REQUIRED].current == 0) { 956fcf3ce44SJohn Forte task_retry_id = 1; 957fcf3ce44SJohn Forte } else { 958fcf3ce44SJohn Forte task_retry_id = npr->TaskRetryIdReq; 959fcf3ce44SJohn Forte } 960fcf3ce44SJohn Forte 961fcf3ce44SJohn Forte /* Check for FCP2 target support */ 962fcf3ce44SJohn Forte /* Retry and TaskRetryId bits are both required here */ 963fcf3ce44SJohn Forte if (npr->targetFunc && npr->Retry && task_retry_id) { 964fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; 965fcf3ce44SJohn Forte } else { 966fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; 967fcf3ce44SJohn Forte } 968fcf3ce44SJohn Forte } 969291a2b48SSukumar Swaminathan 970fcf3ce44SJohn Forte /* Open the node again */ 971*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 972fcf3ce44SJohn Forte 973fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 974291a2b48SSukumar Swaminathan "PRLI: did=%x info=%02x", did, ndlp->nlp_fcp_info); 975fcf3ce44SJohn Forte 976fcf3ce44SJohn Forte /* 977fcf3ce44SJohn Forte * Report PRLI completion 978fcf3ce44SJohn Forte */ 979fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 980fcf3ce44SJohn Forte 981fcf3ce44SJohn Forte } else { 982fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 983291a2b48SSukumar Swaminathan "PRLI: did=%x: Node not found. Failing.", did); 984fcf3ce44SJohn Forte 985fcf3ce44SJohn Forte /* 986fcf3ce44SJohn Forte * Report PRLI failed 987fcf3ce44SJohn Forte */ 988fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 989fcf3ce44SJohn Forte IOERR_INVALID_RPI, 1); 990fcf3ce44SJohn Forte } 991fcf3ce44SJohn Forte return; 992fcf3ce44SJohn Forte 993*82527734SSukumar Swaminathan } /* emlxs_handle_sol_prli() */ 994fcf3ce44SJohn Forte 995fcf3ce44SJohn Forte 996fcf3ce44SJohn Forte static void 997fcf3ce44SJohn Forte emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp) 998fcf3ce44SJohn Forte { 999*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 1000fcf3ce44SJohn Forte fc_packet_t *pkt; 1001fcf3ce44SJohn Forte uint32_t did; 1002fcf3ce44SJohn Forte NODELIST *ndlp; 1003fcf3ce44SJohn Forte 1004fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 1005*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 1006fcf3ce44SJohn Forte 1007291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "LOGO: did=%x", 1008fcf3ce44SJohn Forte did); 1009fcf3ce44SJohn Forte 1010fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 1011fcf3ce44SJohn Forte 1012fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 1013fcf3ce44SJohn Forte /* Close the node for any further normal IO */ 1014*82527734SSukumar Swaminathan emlxs_node_close(port, ndlp, hba->channel_fcp, 60); 1015*82527734SSukumar Swaminathan emlxs_node_close(port, ndlp, hba->channel_ip, 60); 1016fcf3ce44SJohn Forte 1017fcf3ce44SJohn Forte /* Flush tx queues */ 1018fcf3ce44SJohn Forte (void) emlxs_tx_node_flush(port, ndlp, 0, 0, 0); 1019fcf3ce44SJohn Forte 1020fcf3ce44SJohn Forte /* Flush chip queues */ 1021fcf3ce44SJohn Forte (void) emlxs_chipq_node_flush(port, 0, ndlp, 0); 1022fcf3ce44SJohn Forte } 1023291a2b48SSukumar Swaminathan 1024fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1); 1025fcf3ce44SJohn Forte 1026fcf3ce44SJohn Forte return; 1027fcf3ce44SJohn Forte 1028*82527734SSukumar Swaminathan } /* emlxs_handle_sol_logo() */ 1029fcf3ce44SJohn Forte 1030fcf3ce44SJohn Forte 1031fcf3ce44SJohn Forte /* ARGSUSED */ 1032fcf3ce44SJohn Forte static void 1033*82527734SSukumar Swaminathan emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1034fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1035fcf3ce44SJohn Forte { 1036fcf3ce44SJohn Forte uint32_t *lp; 1037fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1038fcf3ce44SJohn Forte uint8_t *bp; 1039fcf3ce44SJohn Forte IOCB *iocb; 1040fcf3ce44SJohn Forte uint32_t count; 1041fcf3ce44SJohn Forte uint32_t sid; 1042fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1043fcf3ce44SJohn Forte 1044fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1045fcf3ce44SJohn Forte bp = mp->virt; 1046291a2b48SSukumar Swaminathan lp = (uint32_t *)bp + 1; 1047fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1048fcf3ce44SJohn Forte 1049291a2b48SSukumar Swaminathan /* Log the legacy rscn event for physical port only */ 1050291a2b48SSukumar Swaminathan if (port->vpi == 0) { 1051291a2b48SSukumar Swaminathan emlxs_log_rscn_event(port, bp, size); 1052291a2b48SSukumar Swaminathan } 1053291a2b48SSukumar Swaminathan 1054291a2b48SSukumar Swaminathan /* Log the vport rscn event for all ports */ 1055291a2b48SSukumar Swaminathan emlxs_log_vportrscn_event(port, bp, size); 1056fcf3ce44SJohn Forte 1057fcf3ce44SJohn Forte count = ((size - 4) / 4); 1058fcf3ce44SJohn Forte 1059fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 1); 1060fcf3ce44SJohn Forte 1061fcf3ce44SJohn Forte if (ubp == NULL) { 1062fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1063fcf3ce44SJohn Forte "RSCN rcvd: sid=%x %d page(s): %08X, %08X. Rejecting.", 1064*82527734SSukumar Swaminathan sid, count, LE_SWAP32(*lp), 1065*82527734SSukumar Swaminathan ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0)); 1066fcf3ce44SJohn Forte 1067fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1068291a2b48SSukumar Swaminathan ELS_CMD_RSCN, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1069fcf3ce44SJohn Forte 1070fcf3ce44SJohn Forte goto drop_it; 1071fcf3ce44SJohn Forte } 1072291a2b48SSukumar Swaminathan 1073fcf3ce44SJohn Forte bcopy(bp, ubp->ub_buffer, size); 1074fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1075fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_RSCN; 1076fcf3ce44SJohn Forte 1077fcf3ce44SJohn Forte /* 1078fcf3ce44SJohn Forte * Setup frame header 1079fcf3ce44SJohn Forte */ 1080fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1081fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 1082*82527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 1083*82527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1084fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 1085*82527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1086fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1087fcf3ce44SJohn Forte 1088fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1089291a2b48SSukumar Swaminathan "RSCN: sid=%x %d page(s): %08X, %08X buffer=%p token=%x.", sid, 1090*82527734SSukumar Swaminathan count, LE_SWAP32(*lp), 1091*82527734SSukumar Swaminathan ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0), ubp, ub_priv->token); 1092fcf3ce44SJohn Forte 1093fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1094fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1095291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1096fcf3ce44SJohn Forte 1097fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1098fcf3ce44SJohn Forte 1099fcf3ce44SJohn Forte drop_it: 1100fcf3ce44SJohn Forte 1101fcf3ce44SJohn Forte return; 1102fcf3ce44SJohn Forte 1103*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_rscn() */ 1104fcf3ce44SJohn Forte 1105fcf3ce44SJohn Forte 1106fcf3ce44SJohn Forte /* This is shared by FCT driver */ 1107fcf3ce44SJohn Forte extern uint32_t 1108291a2b48SSukumar Swaminathan emlxs_process_unsol_flogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp, 1109291a2b48SSukumar Swaminathan uint32_t size, char *buffer) 1110fcf3ce44SJohn Forte { 1111fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1112fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1113fcf3ce44SJohn Forte uint8_t *bp; 1114fcf3ce44SJohn Forte IOCB *iocb; 1115fcf3ce44SJohn Forte uint32_t sid; 1116fcf3ce44SJohn Forte SERV_PARM *sp; 1117fcf3ce44SJohn Forte 1118fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1119fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1120fcf3ce44SJohn Forte 1121fcf3ce44SJohn Forte /* Check payload size */ 1122fcf3ce44SJohn Forte if (size < (sizeof (SERV_PARM) + 4)) { 1123fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1124291a2b48SSukumar Swaminathan "FLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid, 1125291a2b48SSukumar Swaminathan size, (sizeof (SERV_PARM) + 4)); 1126fcf3ce44SJohn Forte 1127fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1128fcf3ce44SJohn Forte ELS_CMD_FLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE); 1129fcf3ce44SJohn Forte 1130fcf3ce44SJohn Forte return (1); 1131fcf3ce44SJohn Forte } 1132291a2b48SSukumar Swaminathan 1133fcf3ce44SJohn Forte bp = mp->virt; 1134fcf3ce44SJohn Forte sp = (SERV_PARM *)(bp + sizeof (uint32_t)); 1135fcf3ce44SJohn Forte 1136fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1137fcf3ce44SJohn Forte 1138fcf3ce44SJohn Forte hba->flag &= ~FC_FABRIC_ATTACHED; 1139fcf3ce44SJohn Forte hba->flag |= FC_PT_TO_PT; 1140fcf3ce44SJohn Forte 1141fcf3ce44SJohn Forte /* Save E_D_TOV ticks in nanoseconds */ 1142fcf3ce44SJohn Forte if (sp->cmn.edtovResolution) { 1143fcf3ce44SJohn Forte hba->fc_edtov = 1144*82527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000; 1145fcf3ce44SJohn Forte } else { 1146*82527734SSukumar Swaminathan hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov); 1147fcf3ce44SJohn Forte } 1148fcf3ce44SJohn Forte 1149fcf3ce44SJohn Forte /* Save R_A_TOV ticks */ 1150*82527734SSukumar Swaminathan hba->fc_ratov = (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000; 1151fcf3ce44SJohn Forte 1152fcf3ce44SJohn Forte buffer[0] = 0; 1153fcf3ce44SJohn Forte 1154fcf3ce44SJohn Forte hba->flag &= ~FC_NPIV_SUPPORTED; 1155fcf3ce44SJohn Forte (void) strcpy(buffer, "npiv:Disabled. P2P "); 1156*82527734SSukumar Swaminathan 1157*82527734SSukumar Swaminathan port->rdid = sid; 1158fcf3ce44SJohn Forte 1159fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1160fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 1161fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 1162fcf3ce44SJohn Forte } else if (cfg[CFG_AUTH_ENABLE].current && 1163fcf3ce44SJohn Forte (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) { 1164fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 1165fcf3ce44SJohn Forte } else { 1166fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 1167fcf3ce44SJohn Forte } 1168291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 1169fcf3ce44SJohn Forte 1170fcf3ce44SJohn Forte /* Clear the fabric service parameters */ 1171291a2b48SSukumar Swaminathan bzero((void *)&port->fabric_sparam, sizeof (SERV_PARM)); 1172fcf3ce44SJohn Forte 1173fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1174fcf3ce44SJohn Forte 1175fcf3ce44SJohn Forte return (0); 1176fcf3ce44SJohn Forte 1177*82527734SSukumar Swaminathan } /* emlxs_process_unsol_flogi() */ 1178fcf3ce44SJohn Forte 1179fcf3ce44SJohn Forte 1180fcf3ce44SJohn Forte /* ARGSUSED */ 1181fcf3ce44SJohn Forte static void 1182*82527734SSukumar Swaminathan emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1183fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1184fcf3ce44SJohn Forte { 1185fcf3ce44SJohn Forte uint8_t *bp; 1186fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1187fcf3ce44SJohn Forte IOCB *iocb; 1188fcf3ce44SJohn Forte uint32_t sid; 1189fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1190fcf3ce44SJohn Forte char buffer[64]; 1191fcf3ce44SJohn Forte 1192fcf3ce44SJohn Forte buffer[0] = 0; 1193fcf3ce44SJohn Forte 1194fcf3ce44SJohn Forte /* Perform processing of FLOGI payload */ 1195fcf3ce44SJohn Forte if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) { 1196fcf3ce44SJohn Forte return; 1197fcf3ce44SJohn Forte } 1198291a2b48SSukumar Swaminathan 1199fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1200fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1201fcf3ce44SJohn Forte bp = mp->virt; 1202fcf3ce44SJohn Forte size = sizeof (SERV_PARM) + 4; 1203fcf3ce44SJohn Forte 1204fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1205fcf3ce44SJohn Forte 1206fcf3ce44SJohn Forte if (ubp == NULL) { 1207fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1208291a2b48SSukumar Swaminathan "FLOGI rcvd: sid=%x. Rejecting.", sid); 1209fcf3ce44SJohn Forte 1210fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1211fcf3ce44SJohn Forte ELS_CMD_FLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1212fcf3ce44SJohn Forte 1213fcf3ce44SJohn Forte goto drop_it; 1214fcf3ce44SJohn Forte } 1215291a2b48SSukumar Swaminathan 1216fcf3ce44SJohn Forte /* 1217fcf3ce44SJohn Forte * Setup unsolicited buffer and pass it up 1218fcf3ce44SJohn Forte */ 1219fcf3ce44SJohn Forte bcopy(bp, ubp->ub_buffer, size); 1220fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1221fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_FLOGI; 1222fcf3ce44SJohn Forte 1223fcf3ce44SJohn Forte /* 1224fcf3ce44SJohn Forte * Setup frame header 1225fcf3ce44SJohn Forte */ 1226fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1227fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 1228*82527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 1229*82527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1230fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 1231*82527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1232fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1233fcf3ce44SJohn Forte 1234fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1235291a2b48SSukumar Swaminathan "FLOGI: sid=%x buffer=%p token=%x %s", sid, ubp, ub_priv->token, 1236291a2b48SSukumar Swaminathan buffer); 1237fcf3ce44SJohn Forte 1238fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1239fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1240291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1241fcf3ce44SJohn Forte 1242fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1243fcf3ce44SJohn Forte 1244fcf3ce44SJohn Forte drop_it: 1245fcf3ce44SJohn Forte 1246fcf3ce44SJohn Forte return; 1247fcf3ce44SJohn Forte 1248*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_flogi() */ 1249fcf3ce44SJohn Forte 1250fcf3ce44SJohn Forte 1251fcf3ce44SJohn Forte 1252fcf3ce44SJohn Forte /* This is shared by FCT driver */ 1253fcf3ce44SJohn Forte extern uint32_t 1254291a2b48SSukumar Swaminathan emlxs_process_unsol_plogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp, 1255291a2b48SSukumar Swaminathan uint32_t size, char *buffer) 1256fcf3ce44SJohn Forte { 1257fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1258fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1259fcf3ce44SJohn Forte uint8_t *bp; 1260fcf3ce44SJohn Forte IOCB *iocb; 1261fcf3ce44SJohn Forte uint32_t sid; 1262fcf3ce44SJohn Forte SERV_PARM *sp; 1263fcf3ce44SJohn Forte MAILBOXQ *mbox; 1264291a2b48SSukumar Swaminathan emlxs_vvl_fmt_t vvl; 1265*82527734SSukumar Swaminathan int rc; 1266fcf3ce44SJohn Forte 1267fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1268fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1269fcf3ce44SJohn Forte 1270fcf3ce44SJohn Forte if (size < (sizeof (SERV_PARM) + 4)) { 1271fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1272291a2b48SSukumar Swaminathan "PLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid, 1273291a2b48SSukumar Swaminathan size, (sizeof (SERV_PARM) + 4)); 1274fcf3ce44SJohn Forte 1275fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1276fcf3ce44SJohn Forte ELS_CMD_PLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE); 1277fcf3ce44SJohn Forte 1278fcf3ce44SJohn Forte return (1); 1279fcf3ce44SJohn Forte } 1280291a2b48SSukumar Swaminathan 1281fcf3ce44SJohn Forte bp = mp->virt; 1282fcf3ce44SJohn Forte sp = (SERV_PARM *)(bp + sizeof (uint32_t)); 1283fcf3ce44SJohn Forte 1284291a2b48SSukumar Swaminathan bzero((char *)&vvl, sizeof (emlxs_vvl_fmt_t)); 1285fcf3ce44SJohn Forte 1286*82527734SSukumar Swaminathan if (sp->VALID_VENDOR_VERSION) { 1287fcf3ce44SJohn Forte 1288291a2b48SSukumar Swaminathan bcopy((caddr_t *)&sp->vendorVersion[0], 1289291a2b48SSukumar Swaminathan (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t)); 1290*82527734SSukumar Swaminathan vvl.un0.word0 = LE_SWAP32(vvl.un0.word0); 1291*82527734SSukumar Swaminathan vvl.un1.word1 = LE_SWAP32(vvl.un1.word1); 1292291a2b48SSukumar Swaminathan } 1293291a2b48SSukumar Swaminathan 1294291a2b48SSukumar Swaminathan if (port->flag & EMLXS_PORT_RESTRICTED) { 1295291a2b48SSukumar Swaminathan uint32_t reject_it = 0; 1296291a2b48SSukumar Swaminathan 1297291a2b48SSukumar Swaminathan /* If remote port is the virtual port, then reject it */ 1298291a2b48SSukumar Swaminathan if ((vvl.un0.w0.oui == 0x0000C9) && (vvl.un1.w1.vport)) { 1299291a2b48SSukumar Swaminathan reject_it = 1; 1300fcf3ce44SJohn Forte } 1301291a2b48SSukumar Swaminathan 1302291a2b48SSukumar Swaminathan /* If we are a virtual port and the remote device */ 1303291a2b48SSukumar Swaminathan /* is not a switch, then reject it */ 1304*82527734SSukumar Swaminathan else if (port->vpi && ((sid & FABRIC_DID_MASK) != 1305*82527734SSukumar Swaminathan FABRIC_DID_MASK)) { 1306fcf3ce44SJohn Forte reject_it = 1; 1307fcf3ce44SJohn Forte } 1308291a2b48SSukumar Swaminathan 1309fcf3ce44SJohn Forte if (reject_it) { 1310fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1311fcf3ce44SJohn Forte "PLOGI rcvd: sid=%x. Restricted. Rejecting.", 1312fcf3ce44SJohn Forte sid); 1313fcf3ce44SJohn Forte 1314fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1315fcf3ce44SJohn Forte ELS_CMD_PLOGI, LSRJT_UNABLE_TPC, 1316fcf3ce44SJohn Forte LSEXP_NOTHING_MORE); 1317fcf3ce44SJohn Forte 1318fcf3ce44SJohn Forte /* 1319291a2b48SSukumar Swaminathan * We still need to do reg_did and unreg_did 1320291a2b48SSukumar Swaminathan * to free up rpi 1321fcf3ce44SJohn Forte */ 1322fcf3ce44SJohn Forte (void) emlxs_mb_reg_did(port, sid, sp, NULL, NULL, 1323fcf3ce44SJohn Forte (IOCBQ *)1); 1324fcf3ce44SJohn Forte 1325fcf3ce44SJohn Forte return (1); 1326fcf3ce44SJohn Forte } 1327fcf3ce44SJohn Forte } 1328fcf3ce44SJohn Forte 1329fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1330fcf3ce44SJohn Forte if (emlxs_dhc_verify_login(port, sid, sp)) { 1331fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1332291a2b48SSukumar Swaminathan "PLOGI: sid=%x. FCSP disabled. Rejecting.", sid); 1333fcf3ce44SJohn Forte 1334fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1335fcf3ce44SJohn Forte ELS_CMD_PLOGI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 1336fcf3ce44SJohn Forte 1337fcf3ce44SJohn Forte return (1); 1338fcf3ce44SJohn Forte } 1339291a2b48SSukumar Swaminathan 1340fcf3ce44SJohn Forte if (!sp->cmn.fcsp_support) { 1341fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Unsupported"); 1342fcf3ce44SJohn Forte } else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current && 1343fcf3ce44SJohn Forte (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) { 1344fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Supported"); 1345fcf3ce44SJohn Forte } else { 1346fcf3ce44SJohn Forte (void) strcat(buffer, "fcsp:Disabled"); 1347fcf3ce44SJohn Forte } 1348291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 1349fcf3ce44SJohn Forte 1350fcf3ce44SJohn Forte /* Check if this was a point to point Plogi */ 1351fcf3ce44SJohn Forte if (hba->flag & FC_PT_TO_PT) { 1352fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1353fcf3ce44SJohn Forte 1354fcf3ce44SJohn Forte /* Save our new port ID */ 1355fcf3ce44SJohn Forte port->did = iocb->un.elsreq.myID; 1356fcf3ce44SJohn Forte 1357fcf3ce44SJohn Forte /* Save E_D_TOV ticks in nanoseconds */ 1358fcf3ce44SJohn Forte if (sp->cmn.edtovResolution) { 1359fcf3ce44SJohn Forte hba->fc_edtov = 1360*82527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000; 1361fcf3ce44SJohn Forte } else { 1362*82527734SSukumar Swaminathan hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov); 1363fcf3ce44SJohn Forte } 1364fcf3ce44SJohn Forte 1365fcf3ce44SJohn Forte /* Save R_A_TOV ticks */ 1366291a2b48SSukumar Swaminathan hba->fc_ratov = 1367*82527734SSukumar Swaminathan (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000; 1368fcf3ce44SJohn Forte 1369fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1370fcf3ce44SJohn Forte 1371fcf3ce44SJohn Forte /* Update our service parms */ 1372291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, 1373*82527734SSukumar Swaminathan MEM_MBOX, 1))) { 1374*82527734SSukumar Swaminathan emlxs_mb_config_link(hba, mbox); 1375fcf3ce44SJohn Forte 1376*82527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, 1377*82527734SSukumar Swaminathan MBX_NOWAIT, 0); 1378*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 1379fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, 1380fcf3ce44SJohn Forte (uint8_t *)mbox); 1381fcf3ce44SJohn Forte } 1382291a2b48SSukumar Swaminathan 1383fcf3ce44SJohn Forte } 1384fcf3ce44SJohn Forte } 1385291a2b48SSukumar Swaminathan 1386fcf3ce44SJohn Forte return (0); 1387fcf3ce44SJohn Forte 1388*82527734SSukumar Swaminathan } /* emlxs_process_unsol_plogi() */ 1389fcf3ce44SJohn Forte 1390fcf3ce44SJohn Forte 1391fcf3ce44SJohn Forte /* ARGSUSED */ 1392fcf3ce44SJohn Forte static void 1393*82527734SSukumar Swaminathan emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1394fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1395fcf3ce44SJohn Forte { 1396fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1397fcf3ce44SJohn Forte uint8_t *bp; 1398fcf3ce44SJohn Forte IOCB *iocb; 1399fcf3ce44SJohn Forte uint32_t sid; 1400fcf3ce44SJohn Forte uint32_t did; 1401fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1402fcf3ce44SJohn Forte SERV_PARM *sp; 1403fcf3ce44SJohn Forte char buffer[64]; 1404fcf3ce44SJohn Forte 1405fcf3ce44SJohn Forte buffer[0] = 0; 1406fcf3ce44SJohn Forte 1407fcf3ce44SJohn Forte /* Perform processing of PLOGI payload */ 1408fcf3ce44SJohn Forte if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) { 1409fcf3ce44SJohn Forte return; 1410fcf3ce44SJohn Forte } 1411291a2b48SSukumar Swaminathan 1412fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1413fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1414fcf3ce44SJohn Forte did = iocb->un.elsreq.myID; 1415fcf3ce44SJohn Forte bp = mp->virt; 1416fcf3ce44SJohn Forte sp = (SERV_PARM *)(bp + sizeof (uint32_t)); 1417fcf3ce44SJohn Forte size = sizeof (SERV_PARM) + 4; 1418fcf3ce44SJohn Forte 1419291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1420291a2b48SSukumar Swaminathan emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_PLOGI_RCV, 1421291a2b48SSukumar Swaminathan (HBA_WWN *)&sp->portName, (HBA_WWN *)&sp->nodeName); 1422291a2b48SSukumar Swaminathan #endif 1423291a2b48SSukumar Swaminathan 1424fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1425fcf3ce44SJohn Forte 1426fcf3ce44SJohn Forte if (ubp == NULL) { 1427fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1428291a2b48SSukumar Swaminathan "PLOGI rcvd: sid=%x. Rejecting.", sid); 1429fcf3ce44SJohn Forte 1430fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1431fcf3ce44SJohn Forte ELS_CMD_PLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1432fcf3ce44SJohn Forte 1433fcf3ce44SJohn Forte goto drop_it; 1434fcf3ce44SJohn Forte } 1435291a2b48SSukumar Swaminathan 1436fcf3ce44SJohn Forte /* 1437fcf3ce44SJohn Forte * Setup unsolicited buffer and pass it up 1438fcf3ce44SJohn Forte */ 1439fcf3ce44SJohn Forte bcopy(bp, ubp->ub_buffer, size); 1440fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1441fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_PLOGI; 1442fcf3ce44SJohn Forte 1443fcf3ce44SJohn Forte /* 1444fcf3ce44SJohn Forte * Setup frame header 1445fcf3ce44SJohn Forte */ 1446fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1447fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 1448*82527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 1449*82527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1450fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 1451*82527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1452fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1453fcf3ce44SJohn Forte 1454fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1455291a2b48SSukumar Swaminathan "PLOGI: sid=%x did=%x buffer=%p token=%x %s", sid, did, ubp, 1456291a2b48SSukumar Swaminathan ub_priv->token, buffer); 1457fcf3ce44SJohn Forte 1458fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1459fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1460291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1461fcf3ce44SJohn Forte 1462fcf3ce44SJohn Forte /* Create a new node and defer callback */ 1463fcf3ce44SJohn Forte if (emlxs_mb_reg_did(port, sid, sp, NULL, ubp, NULL) == 0) { 1464fcf3ce44SJohn Forte /* 1465fcf3ce44SJohn Forte * Defer completion of this pkt until login is complete 1466fcf3ce44SJohn Forte */ 1467fcf3ce44SJohn Forte goto drop_it; 1468fcf3ce44SJohn Forte } 1469291a2b48SSukumar Swaminathan 1470fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1471fcf3ce44SJohn Forte 1472fcf3ce44SJohn Forte drop_it: 1473fcf3ce44SJohn Forte 1474fcf3ce44SJohn Forte return; 1475fcf3ce44SJohn Forte 1476*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_plogi() */ 1477fcf3ce44SJohn Forte 1478fcf3ce44SJohn Forte 1479fcf3ce44SJohn Forte /* ARGSUSED */ 1480fcf3ce44SJohn Forte static void 1481*82527734SSukumar Swaminathan emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1482fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1483fcf3ce44SJohn Forte { 1484*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 1485*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 1486fcf3ce44SJohn Forte IOCB *iocb; 1487fcf3ce44SJohn Forte uint32_t sid; 1488fcf3ce44SJohn Forte NODELIST *ndlp; 1489fcf3ce44SJohn Forte PRLI *npr; 1490fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1491fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1492fcf3ce44SJohn Forte 1493fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1494fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1495fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, sid); 1496fcf3ce44SJohn Forte 1497fcf3ce44SJohn Forte if (!ndlp || !ndlp->nlp_active) { 1498fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1499291a2b48SSukumar Swaminathan "PRLI: sid=%x: Node not found. Rejecting.", sid); 1500fcf3ce44SJohn Forte 1501fcf3ce44SJohn Forte /* Auto reply to PRLI's */ 1502fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1503fcf3ce44SJohn Forte ELS_CMD_PRLI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 1504fcf3ce44SJohn Forte 1505fcf3ce44SJohn Forte goto drop_it; 1506fcf3ce44SJohn Forte } 1507291a2b48SSukumar Swaminathan 1508fcf3ce44SJohn Forte /* If node exists then save FCP2 support */ 1509fcf3ce44SJohn Forte npr = (PRLI *)((caddr_t)mp->virt + sizeof (uint32_t)); 1510fcf3ce44SJohn Forte 1511fcf3ce44SJohn Forte /* Check for FCP2 support */ 1512fcf3ce44SJohn Forte if ((npr->prliType == PRLI_FCP_TYPE) && npr->targetFunc) { 1513fcf3ce44SJohn Forte /* Check for target */ 1514fcf3ce44SJohn Forte if (npr->targetFunc) { 1515fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE; 1516fcf3ce44SJohn Forte } else { 1517fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE; 1518fcf3ce44SJohn Forte } 1519fcf3ce44SJohn Forte 1520fcf3ce44SJohn Forte /* Check for initiator */ 1521fcf3ce44SJohn Forte if (npr->initiatorFunc) { 1522fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE; 1523fcf3ce44SJohn Forte } else { 1524fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE; 1525fcf3ce44SJohn Forte } 1526fcf3ce44SJohn Forte 1527fcf3ce44SJohn Forte /* Check for FCP2 target support */ 1528fcf3ce44SJohn Forte if (npr->targetFunc && npr->Retry) { 1529fcf3ce44SJohn Forte ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; 1530fcf3ce44SJohn Forte } else { 1531fcf3ce44SJohn Forte ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; 1532fcf3ce44SJohn Forte } 1533fcf3ce44SJohn Forte } 1534fcf3ce44SJohn Forte 1535*82527734SSukumar Swaminathan #ifdef ULP_PATCH3 1536*82527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH3) { 1537*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1538*82527734SSukumar Swaminathan "PRLI: sid=%x. Accepting.", sid); 1539fcf3ce44SJohn Forte 1540*82527734SSukumar Swaminathan /* Auto reply to PRLI's */ 1541*82527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, 1542*82527734SSukumar Swaminathan ELS_CMD_PRLI, 0, 0); 1543*82527734SSukumar Swaminathan goto drop_it; 1544*82527734SSukumar Swaminathan } 1545*82527734SSukumar Swaminathan #endif /* ULP_PATCH3 */ 1546fcf3ce44SJohn Forte 1547fcf3ce44SJohn Forte /* Tell ULP about it */ 1548fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1549fcf3ce44SJohn Forte 1550fcf3ce44SJohn Forte if (ubp == NULL) { 1551fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1552291a2b48SSukumar Swaminathan "PRLI rcvd: sid=%x. Rejecting.", sid); 1553fcf3ce44SJohn Forte 1554fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1555fcf3ce44SJohn Forte ELS_CMD_PRLI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1556fcf3ce44SJohn Forte 1557fcf3ce44SJohn Forte goto drop_it; 1558fcf3ce44SJohn Forte } 1559291a2b48SSukumar Swaminathan 1560fcf3ce44SJohn Forte /* 1561fcf3ce44SJohn Forte * Setup unsolicited buffer and pass it up 1562fcf3ce44SJohn Forte */ 1563fcf3ce44SJohn Forte bcopy(mp->virt, ubp->ub_buffer, size); 1564fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1565fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_PRLI; 1566fcf3ce44SJohn Forte 1567fcf3ce44SJohn Forte /* 1568fcf3ce44SJohn Forte * Setup frame header 1569fcf3ce44SJohn Forte */ 1570fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1571fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 1572*82527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 1573*82527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1574fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 1575*82527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1576fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1577fcf3ce44SJohn Forte 1578fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1579291a2b48SSukumar Swaminathan "PRLI: sid=%x buffer=%p token=%x info=%02x", sid, ubp, 1580291a2b48SSukumar Swaminathan ub_priv->token, ndlp->nlp_fcp_info); 1581fcf3ce44SJohn Forte 1582fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1583fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1584291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1585fcf3ce44SJohn Forte 1586fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1587fcf3ce44SJohn Forte 1588fcf3ce44SJohn Forte drop_it: 1589fcf3ce44SJohn Forte 1590fcf3ce44SJohn Forte return; 1591fcf3ce44SJohn Forte 1592*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_prli() */ 1593fcf3ce44SJohn Forte 1594fcf3ce44SJohn Forte 1595fcf3ce44SJohn Forte /* ARGSUSED */ 1596fcf3ce44SJohn Forte static void 1597*82527734SSukumar Swaminathan emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1598fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1599fcf3ce44SJohn Forte { 1600fcf3ce44SJohn Forte IOCB *iocb; 1601fcf3ce44SJohn Forte uint32_t sid; 1602fcf3ce44SJohn Forte NODELIST *ndlp; 1603fcf3ce44SJohn Forte 1604fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1605fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1606fcf3ce44SJohn Forte 1607fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1608fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, sid); 1609fcf3ce44SJohn Forte 1610fcf3ce44SJohn Forte if (!ndlp || !ndlp->nlp_active) { 1611fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1612291a2b48SSukumar Swaminathan "AUTH: sid=%x: Node not found. Rejecting.", sid); 1613fcf3ce44SJohn Forte 1614fcf3ce44SJohn Forte /* Auto reply to AUTH_ELS's */ 1615fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1616fcf3ce44SJohn Forte ELS_CMD_AUTH, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 1617fcf3ce44SJohn Forte 1618fcf3ce44SJohn Forte goto drop_it; 1619fcf3ce44SJohn Forte } 1620291a2b48SSukumar Swaminathan 1621291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "AUTH: sid=%x", sid); 1622fcf3ce44SJohn Forte 1623*82527734SSukumar Swaminathan (void) emlxs_dhchap_state_machine(port, cp, iocbq, mp, ndlp, 1624fcf3ce44SJohn Forte NODE_EVENT_RCV_AUTH_MSG); 1625fcf3ce44SJohn Forte #else 1626fcf3ce44SJohn Forte 1627fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1628291a2b48SSukumar Swaminathan "AUTH: sid=%x: Rejecting.", sid); 1629fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, ELS_CMD_AUTH, 1630fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 1631fcf3ce44SJohn Forte 1632291a2b48SSukumar Swaminathan #endif /* DHCAHP_SUPPORT */ 1633fcf3ce44SJohn Forte 1634fcf3ce44SJohn Forte drop_it: 1635fcf3ce44SJohn Forte 1636fcf3ce44SJohn Forte return; 1637fcf3ce44SJohn Forte 1638*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_auth() */ 1639fcf3ce44SJohn Forte 1640fcf3ce44SJohn Forte 1641fcf3ce44SJohn Forte /* ARGSUSED */ 1642fcf3ce44SJohn Forte static void 1643*82527734SSukumar Swaminathan emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1644fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1645fcf3ce44SJohn Forte { 1646291a2b48SSukumar Swaminathan IOCB *iocb; 1647291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1648291a2b48SSukumar Swaminathan NODELIST *ndlp; 1649291a2b48SSukumar Swaminathan #endif 1650291a2b48SSukumar Swaminathan uint32_t sid; 1651fcf3ce44SJohn Forte 1652fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1653fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1654fcf3ce44SJohn Forte 1655291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1656291a2b48SSukumar Swaminathan ndlp = emlxs_node_find_did(port, sid); 1657291a2b48SSukumar Swaminathan 1658291a2b48SSukumar Swaminathan if (ndlp) { 1659291a2b48SSukumar Swaminathan emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_ADISC_RCV, 1660291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_portname, 1661291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_nodename); 1662291a2b48SSukumar Swaminathan } 1663291a2b48SSukumar Swaminathan #endif 1664291a2b48SSukumar Swaminathan 1665fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1666291a2b48SSukumar Swaminathan "ADISC: sid=%x: Accepting.", sid); 1667fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_ADISC, 0, 0); 1668fcf3ce44SJohn Forte 1669fcf3ce44SJohn Forte return; 1670fcf3ce44SJohn Forte 1671*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_adisc() */ 1672fcf3ce44SJohn Forte 1673fcf3ce44SJohn Forte 1674fcf3ce44SJohn Forte /* ARGSUSED */ 1675fcf3ce44SJohn Forte static void 1676*82527734SSukumar Swaminathan emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1677fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1678fcf3ce44SJohn Forte { 1679*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 1680*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 1681fcf3ce44SJohn Forte IOCB *iocb; 1682fcf3ce44SJohn Forte uint32_t sid; 1683fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1684fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1685fcf3ce44SJohn Forte NODELIST *ndlp; 1686fcf3ce44SJohn Forte 1687fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1688fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1689fcf3ce44SJohn Forte 1690fcf3ce44SJohn Forte /* Get the node */ 1691fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, sid); 1692fcf3ce44SJohn Forte 1693291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1694291a2b48SSukumar Swaminathan if (ndlp) { 1695291a2b48SSukumar Swaminathan emlxs_log_sd_prlo_event(port, (HBA_WWN *)&ndlp->nlp_portname); 1696291a2b48SSukumar Swaminathan } 1697291a2b48SSukumar Swaminathan #endif 1698291a2b48SSukumar Swaminathan 1699291a2b48SSukumar Swaminathan #ifdef ULP_PATCH4 1700*82527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH4) { 1701291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6 1702*82527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) { 1703*82527734SSukumar Swaminathan /* Check if this is a SCSI target */ 1704*82527734SSukumar Swaminathan if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) { 1705*82527734SSukumar Swaminathan /* This is a SCSI target */ 1706*82527734SSukumar Swaminathan 1707*82527734SSukumar Swaminathan /* If only one node is present, then we can */ 1708*82527734SSukumar Swaminathan /* conclude that we are direct attached */ 1709*82527734SSukumar Swaminathan /* to a target */ 1710*82527734SSukumar Swaminathan if (port->node_count == 1) { 1711*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1712*82527734SSukumar Swaminathan &emlxs_unsol_els_msg, 1713*82527734SSukumar Swaminathan "PRLO: sid=%x. Accepting and " \ 1714*82527734SSukumar Swaminathan "reseting link.", 1715*82527734SSukumar Swaminathan sid); 1716291a2b48SSukumar Swaminathan 1717*82527734SSukumar Swaminathan /* Send Acc */ 1718*82527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, 1719*82527734SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0); 1720fcf3ce44SJohn Forte 1721*82527734SSukumar Swaminathan /* Spawn a thread to reset the link */ 1722*82527734SSukumar Swaminathan emlxs_thread_spawn(hba, 1723*82527734SSukumar Swaminathan emlxs_reset_link_thread, 1724*82527734SSukumar Swaminathan NULL, NULL); 1725fcf3ce44SJohn Forte 1726*82527734SSukumar Swaminathan goto drop_it; 1727fcf3ce44SJohn Forte 1728*82527734SSukumar Swaminathan } 1729*82527734SSukumar Swaminathan /* Check if fabric is present */ 1730*82527734SSukumar Swaminathan else if (hba->flag & FC_FABRIC_ATTACHED) { 1731*82527734SSukumar Swaminathan /* Auto reply to PRLO */ 1732*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1733*82527734SSukumar Swaminathan &emlxs_unsol_els_msg, 1734*82527734SSukumar Swaminathan "PRLO: sid=%x. Accepting and " \ 1735*82527734SSukumar Swaminathan "generating RSCN.", 1736*82527734SSukumar Swaminathan sid); 1737fcf3ce44SJohn Forte 1738*82527734SSukumar Swaminathan /* Send Acc */ 1739*82527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, 1740*82527734SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0); 1741fcf3ce44SJohn Forte 1742*82527734SSukumar Swaminathan /* Generate an RSCN to wakeup ULP */ 1743*82527734SSukumar Swaminathan (void) emlxs_generate_rscn(port, sid); 1744fcf3ce44SJohn Forte 1745*82527734SSukumar Swaminathan goto drop_it; 1746*82527734SSukumar Swaminathan } 1747*82527734SSukumar Swaminathan } 1748fcf3ce44SJohn Forte } 1749291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */ 1750fcf3ce44SJohn Forte 1751*82527734SSukumar Swaminathan /* Auto reply to PRLO */ 1752*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1753*82527734SSukumar Swaminathan "PRLO: sid=%x. Accepting.", sid); 1754fcf3ce44SJohn Forte 1755*82527734SSukumar Swaminathan /* Send Acc */ 1756*82527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, 1757*82527734SSukumar Swaminathan ELS_CMD_PRLO, 0, 0); 1758fcf3ce44SJohn Forte 1759*82527734SSukumar Swaminathan goto drop_it; 1760*82527734SSukumar Swaminathan } 1761*82527734SSukumar Swaminathan #endif /* ULP_PATCH4 */ 1762fcf3ce44SJohn Forte 1763fcf3ce44SJohn Forte /* Tell ULP about it */ 1764fcf3ce44SJohn Forte 1765fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1766fcf3ce44SJohn Forte 1767fcf3ce44SJohn Forte if (ubp == NULL) { 1768fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1769291a2b48SSukumar Swaminathan "PRLO recvd: sid=%x. Rejecting.", sid); 1770fcf3ce44SJohn Forte 1771fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1772fcf3ce44SJohn Forte ELS_CMD_PRLO, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1773fcf3ce44SJohn Forte 1774fcf3ce44SJohn Forte goto drop_it; 1775fcf3ce44SJohn Forte } 1776291a2b48SSukumar Swaminathan 1777fcf3ce44SJohn Forte /* 1778fcf3ce44SJohn Forte * Setup unsolicited buffer and pass it up 1779fcf3ce44SJohn Forte */ 1780fcf3ce44SJohn Forte bcopy(mp->virt, ubp->ub_buffer, size); 1781fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1782fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_PRLO; 1783fcf3ce44SJohn Forte 1784fcf3ce44SJohn Forte /* 1785fcf3ce44SJohn Forte * Setup frame header 1786fcf3ce44SJohn Forte */ 1787fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1788fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 1789*82527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 1790*82527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1791fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 1792*82527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1793fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1794fcf3ce44SJohn Forte 1795fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1796291a2b48SSukumar Swaminathan "PRLO: sid=%x buffeiocbr=%p token=%x.", sid, ubp, ub_priv->token); 1797fcf3ce44SJohn Forte 1798fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1799fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1800291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1801fcf3ce44SJohn Forte 1802fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1803fcf3ce44SJohn Forte 1804fcf3ce44SJohn Forte drop_it: 1805fcf3ce44SJohn Forte 1806fcf3ce44SJohn Forte return; 1807fcf3ce44SJohn Forte 1808*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_prlo() */ 1809fcf3ce44SJohn Forte 1810fcf3ce44SJohn Forte 1811fcf3ce44SJohn Forte /* ARGSUSED */ 1812fcf3ce44SJohn Forte static void 1813*82527734SSukumar Swaminathan emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1814fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1815fcf3ce44SJohn Forte { 1816fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1817*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 1818fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1819fcf3ce44SJohn Forte IOCB *iocb; 1820fcf3ce44SJohn Forte uint32_t sid; 1821fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1822fcf3ce44SJohn Forte uint32_t reply_sent = 0; 1823fcf3ce44SJohn Forte NODELIST *ndlp; 1824fcf3ce44SJohn Forte 1825fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1826fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1827fcf3ce44SJohn Forte 1828fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, sid); 1829fcf3ce44SJohn Forte 1830291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1831291a2b48SSukumar Swaminathan if (ndlp) { 1832291a2b48SSukumar Swaminathan emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_LOGO_RCV, 1833291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_portname, 1834291a2b48SSukumar Swaminathan (HBA_WWN *)((uint32_t *)mp->virt + 2)); 1835291a2b48SSukumar Swaminathan } 1836291a2b48SSukumar Swaminathan #endif 1837291a2b48SSukumar Swaminathan 1838291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6 1839*82527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) { 1840*82527734SSukumar Swaminathan /* Check if this is a SCSI target */ 1841*82527734SSukumar Swaminathan if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) { 1842*82527734SSukumar Swaminathan /* This is a SCSI target */ 1843291a2b48SSukumar Swaminathan 1844*82527734SSukumar Swaminathan /* If only one node is present, then we can */ 1845*82527734SSukumar Swaminathan /* conclude that we are direct attached to a target */ 1846*82527734SSukumar Swaminathan if (port->node_count == 1) { 1847*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1848*82527734SSukumar Swaminathan "LOGO: sid=%x. Accepting and "\ 1849*82527734SSukumar Swaminathan "reseting link.", sid); 1850fcf3ce44SJohn Forte 1851*82527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, 1852*82527734SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_LOGO, 0, 0); 1853fcf3ce44SJohn Forte 1854*82527734SSukumar Swaminathan /* Spawn a thread to reset the link */ 1855*82527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_reset_link_thread, 1856*82527734SSukumar Swaminathan NULL, NULL); 1857fcf3ce44SJohn Forte 1858fcf3ce44SJohn Forte goto drop_it; 1859fcf3ce44SJohn Forte } 1860*82527734SSukumar Swaminathan /* Check if fabric node is present */ 1861*82527734SSukumar Swaminathan else if (hba->flag & FC_FABRIC_ATTACHED) { 1862*82527734SSukumar Swaminathan /* Send reply ourselves */ 1863*82527734SSukumar Swaminathan /* We will block all attempts */ 1864*82527734SSukumar Swaminathan /* for ULP to reply to a LOGO */ 1865*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1866*82527734SSukumar Swaminathan "LOGO: sid=%x. Accepting and " \ 1867*82527734SSukumar Swaminathan "generating RSCN.", sid); 1868*82527734SSukumar Swaminathan 1869*82527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, 1870*82527734SSukumar Swaminathan ELS_CMD_LOGO, 0, 0); 1871*82527734SSukumar Swaminathan 1872*82527734SSukumar Swaminathan /* Generate an RSCN to wakeup ULP */ 1873*82527734SSukumar Swaminathan if (emlxs_generate_rscn(port, sid) 1874*82527734SSukumar Swaminathan == FC_SUCCESS) { 1875*82527734SSukumar Swaminathan goto drop_it; 1876*82527734SSukumar Swaminathan } 1877291a2b48SSukumar Swaminathan 1878*82527734SSukumar Swaminathan reply_sent = 1; 1879*82527734SSukumar Swaminathan } 1880fcf3ce44SJohn Forte } 1881291a2b48SSukumar Swaminathan } 1882291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */ 1883fcf3ce44SJohn Forte 1884fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 1); 1885fcf3ce44SJohn Forte 1886fcf3ce44SJohn Forte if (ubp == NULL) { 1887fcf3ce44SJohn Forte if (!reply_sent) { 1888fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1889291a2b48SSukumar Swaminathan "LOGO rcvd: sid=%x. Rejecting.", sid); 1890fcf3ce44SJohn Forte 1891fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, 1892fcf3ce44SJohn Forte ELS_CMD_LOGO, LSRJT_LOGICAL_BSY, 1893fcf3ce44SJohn Forte LSEXP_OUT_OF_RESOURCE); 1894fcf3ce44SJohn Forte } 1895291a2b48SSukumar Swaminathan 1896fcf3ce44SJohn Forte goto drop_it; 1897fcf3ce44SJohn Forte 1898fcf3ce44SJohn Forte } 1899291a2b48SSukumar Swaminathan 1900fcf3ce44SJohn Forte /* Setup unsolicited buffer and pass it up */ 1901fcf3ce44SJohn Forte bcopy(mp->virt, ubp->ub_buffer, size); 1902fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 1903fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_LOGO; 1904fcf3ce44SJohn Forte 1905fcf3ce44SJohn Forte /* Setup frame header */ 1906fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 1907fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 1908*82527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 1909*82527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 1910fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 1911*82527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 1912fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 1913fcf3ce44SJohn Forte 1914fcf3ce44SJohn Forte #ifdef ULP_PATCH2 1915*82527734SSukumar Swaminathan if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH2) { 1916*82527734SSukumar Swaminathan if (!reply_sent) { 1917*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1918*82527734SSukumar Swaminathan "LOGO: sid=%x buffer=%p token=%x. Accepting.", 1919*82527734SSukumar Swaminathan sid, ubp, ub_priv->token); 1920fcf3ce44SJohn Forte 1921*82527734SSukumar Swaminathan ub_priv->flags |= EMLXS_UB_REPLY; 1922fcf3ce44SJohn Forte 1923*82527734SSukumar Swaminathan /* Send Acc */ 1924*82527734SSukumar Swaminathan /* Send reply ourselves because ULP */ 1925*82527734SSukumar Swaminathan /* doesn't always reply to these */ 1926*82527734SSukumar Swaminathan /* We ll block attempts for ULP to reply to a LOGO */ 1927*82527734SSukumar Swaminathan (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, 1928*82527734SSukumar Swaminathan ELS_CMD_LOGO, 0, 0); 1929*82527734SSukumar Swaminathan reply_sent = 1; 1930*82527734SSukumar Swaminathan } 1931fcf3ce44SJohn Forte } 1932*82527734SSukumar Swaminathan #endif /* ULP_PATCH2 */ 1933fcf3ce44SJohn Forte 1934fcf3ce44SJohn Forte if (!reply_sent) { 1935fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 1936291a2b48SSukumar Swaminathan "LOGO: sid=%x buffer=%p token=%x.", sid, ubp, 1937291a2b48SSukumar Swaminathan ub_priv->token); 1938fcf3ce44SJohn Forte } 1939fcf3ce44SJohn Forte 1940fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 1941fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 1942291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 1943fcf3ce44SJohn Forte 1944fcf3ce44SJohn Forte /* Clear the RPI */ 1945*82527734SSukumar Swaminathan if ((sid & FABRIC_DID_MASK) == FABRIC_DID_MASK) { 1946fcf3ce44SJohn Forte if (emlxs_mb_unreg_did(port, sid, NULL, ubp, NULL) == 0) { 1947fcf3ce44SJohn Forte /* 1948291a2b48SSukumar Swaminathan * Deferred completion of this ubp 1949291a2b48SSukumar Swaminathan * until unreg login is complete 1950fcf3ce44SJohn Forte */ 1951fcf3ce44SJohn Forte 1952fcf3ce44SJohn Forte return; 1953fcf3ce44SJohn Forte } 1954fcf3ce44SJohn Forte } 1955291a2b48SSukumar Swaminathan 1956fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 1957fcf3ce44SJohn Forte 1958fcf3ce44SJohn Forte drop_it: 1959fcf3ce44SJohn Forte 1960fcf3ce44SJohn Forte return; 1961fcf3ce44SJohn Forte 1962*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_logo() */ 1963291a2b48SSukumar Swaminathan 1964fcf3ce44SJohn Forte 1965fcf3ce44SJohn Forte 1966fcf3ce44SJohn Forte /* ARGSUSED */ 1967fcf3ce44SJohn Forte static void 1968*82527734SSukumar Swaminathan emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 1969fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 1970fcf3ce44SJohn Forte { 1971fcf3ce44SJohn Forte uint8_t *bp; 1972fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 1973fcf3ce44SJohn Forte IOCB *iocb; 1974fcf3ce44SJohn Forte uint32_t *lp; 1975fcf3ce44SJohn Forte uint32_t cmd; 1976fcf3ce44SJohn Forte uint32_t sid; 1977fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1978fcf3ce44SJohn Forte 1979fcf3ce44SJohn Forte iocb = &iocbq->iocb; 1980fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 1981fcf3ce44SJohn Forte 1982fcf3ce44SJohn Forte bp = mp->virt; 1983fcf3ce44SJohn Forte lp = (uint32_t *)bp; 1984fcf3ce44SJohn Forte cmd = *lp & ELS_CMD_MASK; 1985fcf3ce44SJohn Forte 1986fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0); 1987fcf3ce44SJohn Forte 1988fcf3ce44SJohn Forte if (ubp == NULL) { 1989fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 1990291a2b48SSukumar Swaminathan "%s rcvd: sid=%x: Rejecting.", emlxs_elscmd_xlate(cmd), 1991291a2b48SSukumar Swaminathan sid); 1992fcf3ce44SJohn Forte 1993fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd, 1994fcf3ce44SJohn Forte LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 1995fcf3ce44SJohn Forte 1996fcf3ce44SJohn Forte goto drop_it; 1997fcf3ce44SJohn Forte } 1998291a2b48SSukumar Swaminathan 1999fcf3ce44SJohn Forte bcopy(bp, ubp->ub_buffer, size); 2000fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 2001fcf3ce44SJohn Forte ub_priv->cmd = cmd; 2002fcf3ce44SJohn Forte 2003fcf3ce44SJohn Forte /* Setup frame header */ 2004fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 2005fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 2006*82527734SSukumar Swaminathan ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID); 2007*82527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 2008fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 2009*82527734SSukumar Swaminathan ubp->ub_frame.rx_id = iocb->ULPCONTEXT; 2010fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 2011fcf3ce44SJohn Forte 2012fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2013291a2b48SSukumar Swaminathan "%s: sid=%x buffer=%p token=%x.", emlxs_elscmd_xlate(cmd), sid, 2014291a2b48SSukumar Swaminathan ubp, ub_priv->token); 2015fcf3ce44SJohn Forte 2016fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 2017fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 2018291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 2019fcf3ce44SJohn Forte 2020fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 2021fcf3ce44SJohn Forte 2022fcf3ce44SJohn Forte drop_it: 2023fcf3ce44SJohn Forte 2024fcf3ce44SJohn Forte return; 2025fcf3ce44SJohn Forte 2026*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_gen_cmd() */ 2027fcf3ce44SJohn Forte 2028fcf3ce44SJohn Forte 2029fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */ 2030fcf3ce44SJohn Forte /* ARGSUSED */ 2031fcf3ce44SJohn Forte static void 2032291a2b48SSukumar Swaminathan emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq, 2033291a2b48SSukumar Swaminathan uint32_t flag) 2034fcf3ce44SJohn Forte { 2035*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 2036fcf3ce44SJohn Forte fc_packet_t *pkt; 2037fcf3ce44SJohn Forte IOCB *iocb; 2038fcf3ce44SJohn Forte uint32_t did; 2039fcf3ce44SJohn Forte NODELIST *ndlp; 2040fcf3ce44SJohn Forte uint32_t ucmd; 2041fcf3ce44SJohn Forte uint32_t cmd; 2042fcf3ce44SJohn Forte uint32_t *lp; 2043fcf3ce44SJohn Forte 2044fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2045fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 2046*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 2047fcf3ce44SJohn Forte ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT; 2048fcf3ce44SJohn Forte lp = (uint32_t *)pkt->pkt_cmd; 2049fcf3ce44SJohn Forte cmd = *lp & ELS_CMD_MASK; 2050fcf3ce44SJohn Forte 2051fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 2052291a2b48SSukumar Swaminathan "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd), 2053*82527734SSukumar Swaminathan emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS), 2054fcf3ce44SJohn Forte emlxs_error_xlate(iocb->un.grsp.perr.statLocalError)); 2055fcf3ce44SJohn Forte 2056fcf3ce44SJohn Forte switch (ucmd) { 2057fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 2058fcf3ce44SJohn Forte case ELS_CMD_ADISC: 2059fcf3ce44SJohn Forte 2060fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 2061fcf3ce44SJohn Forte 2062fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 2063fcf3ce44SJohn Forte /* Open the node again */ 2064*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 2065*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_ip); 2066fcf3ce44SJohn Forte } 2067291a2b48SSukumar Swaminathan 2068fcf3ce44SJohn Forte break; 2069fcf3ce44SJohn Forte 2070fcf3ce44SJohn Forte case ELS_CMD_PRLI: 2071fcf3ce44SJohn Forte 2072fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 2073fcf3ce44SJohn Forte 2074fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 2075fcf3ce44SJohn Forte /* Open the node again */ 2076*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 2077fcf3ce44SJohn Forte } 2078291a2b48SSukumar Swaminathan 2079fcf3ce44SJohn Forte break; 2080fcf3ce44SJohn Forte } 2081fcf3ce44SJohn Forte 2082*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2083fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2084fcf3ce44SJohn Forte 2085fcf3ce44SJohn Forte return; 2086fcf3ce44SJohn Forte 2087*82527734SSukumar Swaminathan } /* emlxs_handle_acc() */ 2088fcf3ce44SJohn Forte 2089fcf3ce44SJohn Forte 2090fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */ 2091fcf3ce44SJohn Forte /* ARGSUSED */ 2092fcf3ce44SJohn Forte static void 2093291a2b48SSukumar Swaminathan emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq, 2094291a2b48SSukumar Swaminathan uint32_t flag) 2095fcf3ce44SJohn Forte { 2096*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 2097291a2b48SSukumar Swaminathan fc_packet_t *pkt; 2098291a2b48SSukumar Swaminathan NODELIST *ndlp; 2099291a2b48SSukumar Swaminathan IOCB *iocb; 2100291a2b48SSukumar Swaminathan uint32_t did; 2101291a2b48SSukumar Swaminathan uint32_t ucmd; 2102291a2b48SSukumar Swaminathan uint32_t cmd; 2103291a2b48SSukumar Swaminathan uint32_t *lp; 2104fcf3ce44SJohn Forte 2105fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2106fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 2107*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 2108fcf3ce44SJohn Forte ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT; 2109fcf3ce44SJohn Forte lp = (uint32_t *)pkt->pkt_cmd; 2110fcf3ce44SJohn Forte cmd = *lp & ELS_CMD_MASK; 2111fcf3ce44SJohn Forte 2112291a2b48SSukumar Swaminathan ndlp = emlxs_node_find_did(port, did); 2113291a2b48SSukumar Swaminathan 2114fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, 2115291a2b48SSukumar Swaminathan "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd), 2116*82527734SSukumar Swaminathan emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS), 2117fcf3ce44SJohn Forte emlxs_error_xlate(iocb->un.grsp.perr.statLocalError)); 2118fcf3ce44SJohn Forte 2119fcf3ce44SJohn Forte switch (ucmd) { 2120fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 2121fcf3ce44SJohn Forte 2122fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 2123fcf3ce44SJohn Forte /* Open the node again */ 2124*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 2125*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_ip); 2126fcf3ce44SJohn Forte } 2127291a2b48SSukumar Swaminathan 2128fcf3ce44SJohn Forte break; 2129fcf3ce44SJohn Forte 2130fcf3ce44SJohn Forte case ELS_CMD_PRLI: 2131fcf3ce44SJohn Forte 2132fcf3ce44SJohn Forte if (ndlp && ndlp->nlp_active) { 2133fcf3ce44SJohn Forte /* Open the node again */ 2134*82527734SSukumar Swaminathan emlxs_node_open(port, ndlp, hba->channel_fcp); 2135fcf3ce44SJohn Forte } 2136291a2b48SSukumar Swaminathan 2137fcf3ce44SJohn Forte break; 2138fcf3ce44SJohn Forte } 2139fcf3ce44SJohn Forte 2140*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2141fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2142fcf3ce44SJohn Forte 2143fcf3ce44SJohn Forte return; 2144fcf3ce44SJohn Forte 2145*82527734SSukumar Swaminathan } /* emlxs_handle_reject() */ 2146fcf3ce44SJohn Forte 2147fcf3ce44SJohn Forte 2148fcf3ce44SJohn Forte /* ARGSUSED */ 2149fcf3ce44SJohn Forte extern int32_t 2150fcf3ce44SJohn Forte emlxs_els_reply(emlxs_port_t *port, IOCBQ *iocbq, uint32_t type, 2151fcf3ce44SJohn Forte uint32_t type2, uint32_t reason, uint32_t explain) 2152fcf3ce44SJohn Forte { 2153fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2154fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 2155fcf3ce44SJohn Forte fc_packet_t *pkt; 2156fcf3ce44SJohn Forte ELS_PKT *els; 2157fcf3ce44SJohn Forte uint32_t rval; 2158fcf3ce44SJohn Forte IOCB *iocb; 2159fcf3ce44SJohn Forte 2160fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2161fcf3ce44SJohn Forte 2162fcf3ce44SJohn Forte switch (type) { 2163fcf3ce44SJohn Forte case ELS_CMD_ACC: /* Accept Response */ 2164fcf3ce44SJohn Forte 2165fcf3ce44SJohn Forte /* Allocate the pkt */ 2166fcf3ce44SJohn Forte switch (type2) { 2167fcf3ce44SJohn Forte case ELS_CMD_FLOGI: 2168fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 2169291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (SERV_PARM), 0, 2170291a2b48SSukumar Swaminathan 0, KM_NOSLEEP))) { 2171fcf3ce44SJohn Forte return (1); 2172fcf3ce44SJohn Forte } 2173fcf3ce44SJohn Forte break; 2174fcf3ce44SJohn Forte 2175fcf3ce44SJohn Forte case ELS_CMD_ADISC: 2176fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 2177291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (ADISC), 0, 0, 2178291a2b48SSukumar Swaminathan KM_NOSLEEP))) { 2179fcf3ce44SJohn Forte return (1); 2180fcf3ce44SJohn Forte } 2181fcf3ce44SJohn Forte break; 2182fcf3ce44SJohn Forte 2183fcf3ce44SJohn Forte case ELS_CMD_PRLI: 2184fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 2185291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (PRLI), 0, 0, 2186291a2b48SSukumar Swaminathan KM_NOSLEEP))) { 2187fcf3ce44SJohn Forte return (1); 2188fcf3ce44SJohn Forte } 2189fcf3ce44SJohn Forte break; 2190fcf3ce44SJohn Forte 2191fcf3ce44SJohn Forte case ELS_CMD_PRLO: 2192fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 2193291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (PRLO), 0, 0, 2194291a2b48SSukumar Swaminathan KM_NOSLEEP))) { 2195fcf3ce44SJohn Forte return (1); 2196fcf3ce44SJohn Forte } 2197fcf3ce44SJohn Forte break; 2198fcf3ce44SJohn Forte 2199fcf3ce44SJohn Forte case ELS_CMD_AUTH: 2200fcf3ce44SJohn Forte default: 2201fcf3ce44SJohn Forte 2202291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, sizeof (uint32_t), 2203291a2b48SSukumar Swaminathan 0, 0, KM_NOSLEEP))) { 2204fcf3ce44SJohn Forte return (1); 2205fcf3ce44SJohn Forte } 2206fcf3ce44SJohn Forte } 2207fcf3ce44SJohn Forte 2208fcf3ce44SJohn Forte /* Common initialization */ 2209fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2210fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 2211fcf3ce44SJohn Forte 2212*82527734SSukumar Swaminathan if ((uint32_t)iocb->ULPCLASS == CLASS2) { 2213fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 2214fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 2215fcf3ce44SJohn Forte } 2216291a2b48SSukumar Swaminathan 2217fcf3ce44SJohn Forte /* Build the fc header */ 2218fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = 2219*82527734SSukumar Swaminathan LE_SWAP24_LO(iocb->un.elsreq.remoteID); 2220291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 2221291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 2222*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 2223fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2224291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 2225291a2b48SSukumar Swaminathan F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2226fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2227fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2228fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2229fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff; 2230*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2231fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2232fcf3ce44SJohn Forte 2233fcf3ce44SJohn Forte /* 2234291a2b48SSukumar Swaminathan * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2235291a2b48SSukumar Swaminathan * "%s ACC send. oxid=%x", emlxs_elscmd_xlate(type2), 2236fcf3ce44SJohn Forte * pkt->pkt_cmd_fhdr.ox_id); 2237fcf3ce44SJohn Forte */ 2238fcf3ce44SJohn Forte 2239fcf3ce44SJohn Forte /* Build the command */ 2240291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_cmd; 2241fcf3ce44SJohn Forte els->elsCode = 0x02; 2242fcf3ce44SJohn Forte 2243fcf3ce44SJohn Forte /* Build the payload */ 2244fcf3ce44SJohn Forte switch (type2) { 2245fcf3ce44SJohn Forte case ELS_CMD_ADISC: 2246fcf3ce44SJohn Forte 2247fcf3ce44SJohn Forte els->un.adisc.hardAL_PA = 2248fcf3ce44SJohn Forte (uint8_t)cfg[CFG_ASSIGN_ALPA].current; 2249fcf3ce44SJohn Forte bcopy(&port->wwnn, &els->un.adisc.nodeName, 2250fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2251fcf3ce44SJohn Forte bcopy(&port->wwpn, &els->un.adisc.portName, 2252fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2253*82527734SSukumar Swaminathan els->un.adisc.DID = LE_SWAP24_LO(port->did); 2254fcf3ce44SJohn Forte 2255fcf3ce44SJohn Forte break; 2256fcf3ce44SJohn Forte 2257fcf3ce44SJohn Forte case ELS_CMD_PRLI: 2258fcf3ce44SJohn Forte 2259fcf3ce44SJohn Forte els->elsByte1 = 0x10; 2260fcf3ce44SJohn Forte els->elsByte2 = 0; 2261fcf3ce44SJohn Forte els->elsByte3 = 0x14; 2262fcf3ce44SJohn Forte 2263fcf3ce44SJohn Forte els->un.prli.prliType = PRLI_FCP_TYPE; 2264fcf3ce44SJohn Forte els->un.prli.estabImagePair = 1; 2265fcf3ce44SJohn Forte els->un.prli.acceptRspCode = PRLI_REQ_EXECUTED; 2266fcf3ce44SJohn Forte 2267fcf3ce44SJohn Forte if (port->ini_mode) { 2268fcf3ce44SJohn Forte els->un.prli.initiatorFunc = 1; 2269fcf3ce44SJohn Forte } 2270291a2b48SSukumar Swaminathan 2271fcf3ce44SJohn Forte if (port->tgt_mode) { 2272fcf3ce44SJohn Forte els->un.prli.targetFunc = 1; 2273fcf3ce44SJohn Forte } 2274291a2b48SSukumar Swaminathan 2275fcf3ce44SJohn Forte els->un.prli.readXferRdyDis = 1; 2276fcf3ce44SJohn Forte 2277fcf3ce44SJohn Forte if (hba->vpd.feaLevelHigh >= 0x02) { 2278fcf3ce44SJohn Forte els->un.prli.ConfmComplAllowed = 1; 2279fcf3ce44SJohn Forte els->un.prli.Retry = 1; 2280fcf3ce44SJohn Forte els->un.prli.TaskRetryIdReq = 1; 2281fcf3ce44SJohn Forte } else { 2282fcf3ce44SJohn Forte els->un.prli.ConfmComplAllowed = 0; 2283fcf3ce44SJohn Forte els->un.prli.Retry = 0; 2284fcf3ce44SJohn Forte els->un.prli.TaskRetryIdReq = 0; 2285fcf3ce44SJohn Forte } 2286fcf3ce44SJohn Forte 2287fcf3ce44SJohn Forte break; 2288fcf3ce44SJohn Forte 2289fcf3ce44SJohn Forte case ELS_CMD_PRLO: 2290fcf3ce44SJohn Forte 2291fcf3ce44SJohn Forte els->elsByte1 = 0x10; 2292fcf3ce44SJohn Forte els->elsByte2 = 0; 2293fcf3ce44SJohn Forte els->elsByte3 = 0x14; 2294fcf3ce44SJohn Forte 2295fcf3ce44SJohn Forte els->un.prlo.prloType = PRLO_FCP_TYPE; 2296fcf3ce44SJohn Forte els->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED; 2297fcf3ce44SJohn Forte 2298fcf3ce44SJohn Forte break; 2299fcf3ce44SJohn Forte 2300fcf3ce44SJohn Forte 2301fcf3ce44SJohn Forte } /* switch(type2) */ 2302fcf3ce44SJohn Forte break; 2303fcf3ce44SJohn Forte 2304fcf3ce44SJohn Forte case ELS_CMD_LS_RJT: /* reject response */ 2305fcf3ce44SJohn Forte 2306fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 2307fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (LS_RJT), 0, 0, KM_NOSLEEP))) { 2308fcf3ce44SJohn Forte return (1); 2309fcf3ce44SJohn Forte } 2310291a2b48SSukumar Swaminathan 2311fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2312fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 2313fcf3ce44SJohn Forte 2314*82527734SSukumar Swaminathan if ((uint32_t)iocb->ULPCLASS == CLASS2) { 2315fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 2316fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 2317fcf3ce44SJohn Forte } 2318291a2b48SSukumar Swaminathan 2319fcf3ce44SJohn Forte /* Build the fc header */ 2320fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = 2321*82527734SSukumar Swaminathan LE_SWAP24_LO(iocb->un.elsreq.remoteID); 2322291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 2323291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 2324*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID); 2325fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2326291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 2327291a2b48SSukumar Swaminathan F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2328fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2329fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2330fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2331fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff; 2332*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2333fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2334fcf3ce44SJohn Forte 2335fcf3ce44SJohn Forte /* 2336291a2b48SSukumar Swaminathan * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2337291a2b48SSukumar Swaminathan * "%s LS_RJT send. oxid=%x", emlxs_elscmd_xlate(type2), 2338fcf3ce44SJohn Forte * pkt->pkt_cmd_fhdr.ox_id); 2339fcf3ce44SJohn Forte */ 2340fcf3ce44SJohn Forte 2341fcf3ce44SJohn Forte /* Build the command */ 2342291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_cmd; 2343fcf3ce44SJohn Forte els->elsCode = 0x01; 2344fcf3ce44SJohn Forte els->un.lsRjt.un.b.lsRjtRsvd0 = 0; 2345fcf3ce44SJohn Forte els->un.lsRjt.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; 2346fcf3ce44SJohn Forte els->un.lsRjt.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; 2347fcf3ce44SJohn Forte els->un.lsRjt.un.b.vendorUnique = 0x01; 2348fcf3ce44SJohn Forte 2349fcf3ce44SJohn Forte break; 2350fcf3ce44SJohn Forte } 2351fcf3ce44SJohn Forte 2352fcf3ce44SJohn Forte if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) { 2353fcf3ce44SJohn Forte /* Free the pkt */ 2354fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 2355fcf3ce44SJohn Forte } 2356291a2b48SSukumar Swaminathan 2357fcf3ce44SJohn Forte return (rval); 2358fcf3ce44SJohn Forte 2359*82527734SSukumar Swaminathan } /* emlxs_els_reply() */ 2360fcf3ce44SJohn Forte 2361fcf3ce44SJohn Forte 2362fcf3ce44SJohn Forte #ifdef ULP_PATCH6 2363fcf3ce44SJohn Forte 2364fcf3ce44SJohn Forte extern uint32_t 2365fcf3ce44SJohn Forte emlxs_generate_rscn(emlxs_port_t *port, uint32_t d_id) 2366fcf3ce44SJohn Forte { 2367fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 2368fcf3ce44SJohn Forte fc_rscn_t *rscn; 2369fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 2370fcf3ce44SJohn Forte uint32_t *page; 2371fcf3ce44SJohn Forte 2372fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, 8, FC_ELS_DATA, 1); 2373fcf3ce44SJohn Forte 2374fcf3ce44SJohn Forte if (ubp == NULL) { 2375fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg, 2376291a2b48SSukumar Swaminathan "RSCN create: sid=0xfffffd 1 page(s): %08X, 00000000. " 2377291a2b48SSukumar Swaminathan "Creation failed.", d_id); 2378fcf3ce44SJohn Forte 2379fcf3ce44SJohn Forte return ((uint32_t)FC_FAILURE); 2380fcf3ce44SJohn Forte } 2381291a2b48SSukumar Swaminathan 2382fcf3ce44SJohn Forte /* Simulate an RSCN payload */ 2383fcf3ce44SJohn Forte rscn = (fc_rscn_t *)ubp->ub_buffer; 2384fcf3ce44SJohn Forte rscn->rscn_code = 0x61; 2385fcf3ce44SJohn Forte rscn->rscn_len = 0x04; 2386fcf3ce44SJohn Forte rscn->rscn_payload_len = 0x0008; 2387fcf3ce44SJohn Forte page = ((uint32_t *)rscn); 2388fcf3ce44SJohn Forte page++; 2389fcf3ce44SJohn Forte *page = d_id; 2390fcf3ce44SJohn Forte 2391fcf3ce44SJohn Forte #ifdef EMLXS_I386 2392fcf3ce44SJohn Forte /* Put payload in BE format */ 2393*82527734SSukumar Swaminathan rscn->rscn_payload_len = LE_SWAP16(rscn->rscn_payload_len); 2394*82527734SSukumar Swaminathan *page = LE_SWAP32(d_id); 2395291a2b48SSukumar Swaminathan #endif /* EMLXS_I386 */ 2396fcf3ce44SJohn Forte 2397fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 2398fcf3ce44SJohn Forte ub_priv->cmd = ELS_CMD_RSCN; 2399fcf3ce44SJohn Forte ub_priv->flags |= EMLXS_UB_INTERCEPT; 2400fcf3ce44SJohn Forte 2401fcf3ce44SJohn Forte ubp->ub_frame.r_ctl = FC_ELS_REQ; 2402fcf3ce44SJohn Forte ubp->ub_frame.type = FC_ELS_DATA; 2403fcf3ce44SJohn Forte ubp->ub_frame.s_id = 0xfffffd; 2404*82527734SSukumar Swaminathan ubp->ub_frame.d_id = LE_SWAP24_LO(port->did); 2405fcf3ce44SJohn Forte ubp->ub_frame.ox_id = ub_priv->token; 2406fcf3ce44SJohn Forte ubp->ub_frame.rx_id = 0xffff; 2407fcf3ce44SJohn Forte ubp->ub_class = FC_TRAN_CLASS3; 2408fcf3ce44SJohn Forte 2409fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2410291a2b48SSukumar Swaminathan "RSCN: sid=fffffd 1 page(s): %08X, 00000000 buffer=%p " 2411291a2b48SSukumar Swaminathan "token=%x. Created.", d_id, ubp, ub_priv->token); 2412fcf3ce44SJohn Forte 2413fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X) 2414fcf3ce44SJohn Forte emlxs_swap_els_ub(ubp); 2415291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */ 2416fcf3ce44SJohn Forte 2417fcf3ce44SJohn Forte emlxs_ub_callback(port, ubp); 2418fcf3ce44SJohn Forte 2419fcf3ce44SJohn Forte return (FC_SUCCESS); 2420fcf3ce44SJohn Forte 2421*82527734SSukumar Swaminathan } /* emlxs_generate_rscn() */ 2422fcf3ce44SJohn Forte 2423291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */ 2424fcf3ce44SJohn Forte 2425fcf3ce44SJohn Forte 2426fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 2427fcf3ce44SJohn Forte extern int 2428*82527734SSukumar Swaminathan emlxs_menlo_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 2429fcf3ce44SJohn Forte { 2430fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2431fcf3ce44SJohn Forte IOCB *iocb; 2432fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2433fcf3ce44SJohn Forte fc_packet_t *pkt; 2434fcf3ce44SJohn Forte uint32_t cmd_code = 0; 2435fcf3ce44SJohn Forte uint32_t rsp_code = 0; 2436fcf3ce44SJohn Forte menlo_cmd_t *cmd; 2437fcf3ce44SJohn Forte uint32_t *rsp; 2438fcf3ce44SJohn Forte 2439fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2440fcf3ce44SJohn Forte 2441fcf3ce44SJohn Forte HBASTATS.CtEvent++; 2442fcf3ce44SJohn Forte 2443fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 2444fcf3ce44SJohn Forte 2445fcf3ce44SJohn Forte if (!sbp) { 2446fcf3ce44SJohn Forte /* 2447fcf3ce44SJohn Forte * completion with missing xmit command 2448fcf3ce44SJohn Forte */ 2449fcf3ce44SJohn Forte HBASTATS.CtStray++; 2450fcf3ce44SJohn Forte 2451fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg, 2452fcf3ce44SJohn Forte "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x", 2453*82527734SSukumar Swaminathan iocbq, (uint32_t)iocb->ULPCOMMAND, 2454*82527734SSukumar Swaminathan (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS, 2455291a2b48SSukumar Swaminathan iocb->un.ulpWord[4]); 2456fcf3ce44SJohn Forte 2457fcf3ce44SJohn Forte return (1); 2458fcf3ce44SJohn Forte } 2459291a2b48SSukumar Swaminathan 2460*82527734SSukumar Swaminathan if (cp->channelno != hba->channel_ct) { 2461fcf3ce44SJohn Forte HBASTATS.CtStray++; 2462fcf3ce44SJohn Forte 2463fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg, 2464*82527734SSukumar Swaminathan "Invalid IO channel:%d iocbq=%p", cp->channelno, iocbq); 2465fcf3ce44SJohn Forte 2466fcf3ce44SJohn Forte return (1); 2467fcf3ce44SJohn Forte } 2468291a2b48SSukumar Swaminathan 2469fcf3ce44SJohn Forte port = sbp->iocbq.port; 2470fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 2471fcf3ce44SJohn Forte 2472fcf3ce44SJohn Forte cmd = (menlo_cmd_t *)pkt->pkt_cmd; 2473*82527734SSukumar Swaminathan cmd_code = BE_SWAP32(cmd->code); 2474fcf3ce44SJohn Forte 2475fcf3ce44SJohn Forte /* Check if a response buffer was provided */ 2476fcf3ce44SJohn Forte if (pkt->pkt_rsplen) { 2477*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen, 2478fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 2479fcf3ce44SJohn Forte } 2480291a2b48SSukumar Swaminathan 2481*82527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) { 2482291a2b48SSukumar Swaminathan /* 2483291a2b48SSukumar Swaminathan * MENLO Command completion 2484291a2b48SSukumar Swaminathan */ 2485fcf3ce44SJohn Forte case CMD_GEN_REQUEST64_CR: 2486fcf3ce44SJohn Forte case CMD_GEN_REQUEST64_CX: 2487fcf3ce44SJohn Forte 2488fcf3ce44SJohn Forte HBASTATS.CtCmdCompleted++; 2489fcf3ce44SJohn Forte 2490fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_CT_RSP_VALID; 2491fcf3ce44SJohn Forte 2492fcf3ce44SJohn Forte rsp = (uint32_t *)pkt->pkt_resp; 2493fcf3ce44SJohn Forte rsp_code = *rsp; 2494*82527734SSukumar Swaminathan rsp_code = BE_SWAP32(rsp_code); 2495fcf3ce44SJohn Forte 2496*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) { 2497fcf3ce44SJohn Forte pkt->pkt_resp_resid = 2498fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen; 2499fcf3ce44SJohn Forte } else 2500fcf3ce44SJohn Forte { 2501fcf3ce44SJohn Forte pkt->pkt_resp_resid = 2502fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize; 2503fcf3ce44SJohn Forte } 2504fcf3ce44SJohn Forte 2505fcf3ce44SJohn Forte pkt->pkt_data_resid = pkt->pkt_datalen; 2506*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT; 2507fcf3ce44SJohn Forte 2508*82527734SSukumar Swaminathan if ((iocb->ULPSTATUS == 0) && (rsp_code == MENLO_RSP_SUCCESS)) { 2509fcf3ce44SJohn Forte HBASTATS.CtCmdGood++; 2510fcf3ce44SJohn Forte 2511fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2512fcf3ce44SJohn Forte "%s: %s rxid=0x%x", 2513fcf3ce44SJohn Forte emlxs_menlo_cmd_xlate(cmd_code), 2514fcf3ce44SJohn Forte emlxs_menlo_rsp_xlate(rsp_code), 2515*82527734SSukumar Swaminathan iocb->ULPCONTEXT); 2516fcf3ce44SJohn Forte 2517fcf3ce44SJohn Forte } else { 2518fcf3ce44SJohn Forte HBASTATS.CtCmdError++; 2519fcf3ce44SJohn Forte 2520fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2521fcf3ce44SJohn Forte "%s: %s %s %s rxid=0x%x", 2522fcf3ce44SJohn Forte emlxs_menlo_cmd_xlate(cmd_code), 2523fcf3ce44SJohn Forte emlxs_menlo_rsp_xlate(rsp_code), 2524*82527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2525291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2526*82527734SSukumar Swaminathan statLocalError), iocb->ULPCONTEXT); 2527fcf3ce44SJohn Forte } 2528fcf3ce44SJohn Forte 2529*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2530fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2531fcf3ce44SJohn Forte 2532fcf3ce44SJohn Forte break; 2533fcf3ce44SJohn Forte 2534fcf3ce44SJohn Forte default: 2535fcf3ce44SJohn Forte 2536fcf3ce44SJohn Forte HBASTATS.CtStray++; 2537fcf3ce44SJohn Forte 2538fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg, 2539*82527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND); 2540fcf3ce44SJohn Forte 2541*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2542fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2543fcf3ce44SJohn Forte 2544fcf3ce44SJohn Forte break; 2545fcf3ce44SJohn Forte 2546*82527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */ 2547fcf3ce44SJohn Forte 2548fcf3ce44SJohn Forte return (0); 2549fcf3ce44SJohn Forte 2550*82527734SSukumar Swaminathan } /* emlxs_menlo_handle_event() */ 2551fcf3ce44SJohn Forte 2552291a2b48SSukumar Swaminathan #endif /* MENLO_SUPPORT */ 2553fcf3ce44SJohn Forte 2554fcf3ce44SJohn Forte 2555fcf3ce44SJohn Forte extern int 2556*82527734SSukumar Swaminathan emlxs_ct_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 2557fcf3ce44SJohn Forte { 2558fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2559fcf3ce44SJohn Forte IOCB *iocb; 2560fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2561fcf3ce44SJohn Forte fc_packet_t *pkt; 2562fcf3ce44SJohn Forte uint32_t *rsp; 2563fcf3ce44SJohn Forte SLI_CT_REQUEST *CtRsp; 2564fcf3ce44SJohn Forte SLI_CT_REQUEST *CtCmd; 2565fcf3ce44SJohn Forte uint32_t cmd_code = 0; 2566fcf3ce44SJohn Forte uint32_t rsp_code = 0; 2567fcf3ce44SJohn Forte 2568fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2569fcf3ce44SJohn Forte 2570fcf3ce44SJohn Forte HBASTATS.CtEvent++; 2571fcf3ce44SJohn Forte 2572fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 2573fcf3ce44SJohn Forte 2574fcf3ce44SJohn Forte if (!sbp) { 2575fcf3ce44SJohn Forte /* 2576fcf3ce44SJohn Forte * completion with missing xmit command 2577fcf3ce44SJohn Forte */ 2578fcf3ce44SJohn Forte HBASTATS.CtStray++; 2579fcf3ce44SJohn Forte 2580fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg, 2581fcf3ce44SJohn Forte "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x", 2582*82527734SSukumar Swaminathan iocbq, (uint32_t)iocb->ULPCOMMAND, 2583*82527734SSukumar Swaminathan (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS, 2584291a2b48SSukumar Swaminathan iocb->un.ulpWord[4]); 2585fcf3ce44SJohn Forte 2586fcf3ce44SJohn Forte return (1); 2587fcf3ce44SJohn Forte } 2588291a2b48SSukumar Swaminathan 2589*82527734SSukumar Swaminathan if (cp->channelno != hba->channel_ct) { 2590fcf3ce44SJohn Forte HBASTATS.CtStray++; 2591fcf3ce44SJohn Forte 2592fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg, 2593*82527734SSukumar Swaminathan "Invalid channel: channel=%d iocbq=%p", cp->channelno, 2594*82527734SSukumar Swaminathan iocbq); 2595fcf3ce44SJohn Forte 2596fcf3ce44SJohn Forte return (1); 2597fcf3ce44SJohn Forte } 2598291a2b48SSukumar Swaminathan 2599fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 2600fcf3ce44SJohn Forte port = sbp->iocbq.port; 2601291a2b48SSukumar Swaminathan CtCmd = (SLI_CT_REQUEST *)pkt->pkt_cmd; 2602*82527734SSukumar Swaminathan cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp); 2603fcf3ce44SJohn Forte 2604fcf3ce44SJohn Forte if (cmd_code == SLI_CT_LOOPBACK) { 2605fcf3ce44SJohn Forte HBASTATS.CtEvent--; 2606*82527734SSukumar Swaminathan return (emlxs_dfc_handle_event(hba, cp, iocbq)); 2607fcf3ce44SJohn Forte } 2608fcf3ce44SJohn Forte 2609fcf3ce44SJohn Forte /* Check if a response buffer was provided */ 2610fcf3ce44SJohn Forte if (pkt->pkt_rsplen) { 2611*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen, 2612fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 2613fcf3ce44SJohn Forte } 2614291a2b48SSukumar Swaminathan 2615*82527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) { 2616291a2b48SSukumar Swaminathan /* 2617291a2b48SSukumar Swaminathan * CT Reply completion 2618291a2b48SSukumar Swaminathan */ 2619fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE_CX: 2620fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE64_CX: 2621fcf3ce44SJohn Forte 2622fcf3ce44SJohn Forte HBASTATS.CtRspCompleted++; 2623fcf3ce44SJohn Forte 2624fcf3ce44SJohn Forte switch (CtCmd->FsType) { 2625fcf3ce44SJohn Forte case 0xFC: /* Name server */ 2626fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2627291a2b48SSukumar Swaminathan "%s: %s %s", emlxs_ctcmd_xlate(cmd_code), 2628*82527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2629291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2630291a2b48SSukumar Swaminathan statLocalError)); 2631fcf3ce44SJohn Forte break; 2632fcf3ce44SJohn Forte 2633fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 2634fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2635291a2b48SSukumar Swaminathan "%s: %s %s", emlxs_mscmd_xlate(cmd_code), 2636*82527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2637291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2638291a2b48SSukumar Swaminathan statLocalError)); 2639fcf3ce44SJohn Forte break; 2640fcf3ce44SJohn Forte 2641fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 2642fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2643291a2b48SSukumar Swaminathan "%s: %s %s", emlxs_rmcmd_xlate(cmd_code), 2644*82527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2645291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2646291a2b48SSukumar Swaminathan statLocalError)); 2647fcf3ce44SJohn Forte break; 2648fcf3ce44SJohn Forte 2649fcf3ce44SJohn Forte default: 2650fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2651291a2b48SSukumar Swaminathan "%s: %s %s", emlxs_ctcmd_xlate(cmd_code), 2652*82527734SSukumar Swaminathan emlxs_state_xlate(iocb->ULPSTATUS), 2653291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp.perr. 2654291a2b48SSukumar Swaminathan statLocalError)); 2655fcf3ce44SJohn Forte } 2656fcf3ce44SJohn Forte 2657*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2658fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2659fcf3ce44SJohn Forte 2660fcf3ce44SJohn Forte break; 2661fcf3ce44SJohn Forte 2662291a2b48SSukumar Swaminathan /* 2663291a2b48SSukumar Swaminathan * CT Command completion 2664291a2b48SSukumar Swaminathan */ 2665fcf3ce44SJohn Forte case CMD_GEN_REQUEST64_CR: 2666fcf3ce44SJohn Forte case CMD_GEN_REQUEST64_CX: 2667fcf3ce44SJohn Forte 2668fcf3ce44SJohn Forte HBASTATS.CtCmdCompleted++; 2669fcf3ce44SJohn Forte 2670fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_CT_RSP_VALID; 2671fcf3ce44SJohn Forte 2672fcf3ce44SJohn Forte rsp = (uint32_t *)pkt->pkt_resp; 2673fcf3ce44SJohn Forte CtRsp = (SLI_CT_REQUEST *)pkt->pkt_resp; 2674*82527734SSukumar Swaminathan rsp_code = LE_SWAP16(CtRsp->CommandResponse.bits.CmdRsp); 2675fcf3ce44SJohn Forte 2676*82527734SSukumar Swaminathan if (hba->sli_mode >= EMLXS_HBA_SLI3_MODE) { 2677fcf3ce44SJohn Forte pkt->pkt_resp_resid = 2678fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen; 2679fcf3ce44SJohn Forte } else 2680fcf3ce44SJohn Forte { 2681fcf3ce44SJohn Forte pkt->pkt_resp_resid = 2682fcf3ce44SJohn Forte pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize; 2683fcf3ce44SJohn Forte } 2684fcf3ce44SJohn Forte 2685fcf3ce44SJohn Forte pkt->pkt_data_resid = pkt->pkt_datalen; 2686fcf3ce44SJohn Forte 2687fcf3ce44SJohn Forte /* 2688291a2b48SSukumar Swaminathan * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg, 2689291a2b48SSukumar Swaminathan * "INFO: pkt_resid=%d %d %d %x", pkt->pkt_resp_resid, 2690fcf3ce44SJohn Forte * pkt->pkt_rsplen, iocb->un.genreq64.bdl.bdeSize, 2691fcf3ce44SJohn Forte * iocb->un.genreq64.bdl.bdeFlags); 2692fcf3ce44SJohn Forte */ 2693fcf3ce44SJohn Forte 2694*82527734SSukumar Swaminathan if ((iocb->ULPSTATUS == 0) && 2695fcf3ce44SJohn Forte (rsp_code == SLI_CT_RESPONSE_FS_ACC)) { 2696fcf3ce44SJohn Forte HBASTATS.CtCmdGood++; 2697fcf3ce44SJohn Forte 2698fcf3ce44SJohn Forte if (!(sbp->pkt_flags & PACKET_ALLOCATED)) { 2699291a2b48SSukumar Swaminathan /* ULP patch - ULP expects */ 2700291a2b48SSukumar Swaminathan /* resp_resid = 0 on success */ 2701fcf3ce44SJohn Forte pkt->pkt_resp_resid = 0; 2702fcf3ce44SJohn Forte } 2703291a2b48SSukumar Swaminathan 2704fcf3ce44SJohn Forte switch (CtCmd->FsType) { 2705fcf3ce44SJohn Forte case 0xFC: /* Name server */ 2706fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2707fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2708fcf3ce44SJohn Forte "%s: %s: Rsn=%x Exp=%x [%08x,%08x]", 2709fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 2710fcf3ce44SJohn Forte emlxs_ctcmd_xlate(rsp_code), 2711fcf3ce44SJohn Forte CtRsp->ReasonCode, CtRsp->Explanation, 2712*82527734SSukumar Swaminathan LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5])); 2713fcf3ce44SJohn Forte 2714fcf3ce44SJohn Forte #if (EMLXS_MODREV < EMLXS_MODREV4) 2715fcf3ce44SJohn Forte if (cmd_code == SLI_CTNS_RNN_ID) { 2716fcf3ce44SJohn Forte emlxs_send_rsnn(port); 2717fcf3ce44SJohn Forte } 2718291a2b48SSukumar Swaminathan #endif /* < EMLXS_MODREV4 */ 2719fcf3ce44SJohn Forte 2720fcf3ce44SJohn Forte break; 2721fcf3ce44SJohn Forte 2722fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 2723fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2724fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2725fcf3ce44SJohn Forte "%s: %s: Rsn=%x Exp=%x [%08x,%08x]", 2726fcf3ce44SJohn Forte emlxs_mscmd_xlate(cmd_code), 2727fcf3ce44SJohn Forte emlxs_mscmd_xlate(rsp_code), 2728fcf3ce44SJohn Forte CtRsp->ReasonCode, CtRsp->Explanation, 2729*82527734SSukumar Swaminathan LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5])); 2730fcf3ce44SJohn Forte break; 2731fcf3ce44SJohn Forte 2732fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 2733fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2734fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2735fcf3ce44SJohn Forte "%s: %s: Rsn=%x Exp=%x [%08x,%08x]", 2736fcf3ce44SJohn Forte emlxs_rmcmd_xlate(cmd_code), 2737fcf3ce44SJohn Forte emlxs_rmcmd_xlate(rsp_code), 2738fcf3ce44SJohn Forte CtRsp->ReasonCode, CtRsp->Explanation, 2739*82527734SSukumar Swaminathan LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5])); 2740fcf3ce44SJohn Forte break; 2741fcf3ce44SJohn Forte 2742fcf3ce44SJohn Forte default: 2743fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2744fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2745fcf3ce44SJohn Forte "%s: %s: Rsn=%x Exp=%x [%08x,%08x]", 2746fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 2747fcf3ce44SJohn Forte emlxs_ctcmd_xlate(rsp_code), 2748fcf3ce44SJohn Forte CtRsp->ReasonCode, CtRsp->Explanation, 2749*82527734SSukumar Swaminathan LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5])); 2750fcf3ce44SJohn Forte } 2751fcf3ce44SJohn Forte } else { 2752fcf3ce44SJohn Forte HBASTATS.CtCmdError++; 2753fcf3ce44SJohn Forte 2754fcf3ce44SJohn Forte if (rsp_code == SLI_CT_RESPONSE_FS_RJT) { 2755fcf3ce44SJohn Forte pkt->pkt_state = FC_PKT_FS_RJT; 2756fcf3ce44SJohn Forte pkt->pkt_action = FC_ACTION_RETRYABLE; 2757fcf3ce44SJohn Forte pkt->pkt_reason = CtRsp->ReasonCode; 2758fcf3ce44SJohn Forte pkt->pkt_expln = CtRsp->Explanation; 2759fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_STATE_VALID; 2760fcf3ce44SJohn Forte 2761fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2762fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2763fcf3ce44SJohn Forte "%s: Rejected. rsn=%x exp=%x", 2764fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 2765291a2b48SSukumar Swaminathan pkt->pkt_reason, pkt->pkt_expln); 2766*82527734SSukumar Swaminathan } else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) { 2767fcf3ce44SJohn Forte switch (CtCmd->FsType) { 2768fcf3ce44SJohn Forte case 0xFC: /* Name server */ 2769fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2770fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2771fcf3ce44SJohn Forte "%s: %s %s", 2772fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 2773291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 2774*82527734SSukumar Swaminathan ULPSTATUS), 2775291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp. 2776291a2b48SSukumar Swaminathan perr.statLocalError)); 2777fcf3ce44SJohn Forte break; 2778fcf3ce44SJohn Forte 2779fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 2780fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2781fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2782fcf3ce44SJohn Forte "%s: %s %s", 2783fcf3ce44SJohn Forte emlxs_mscmd_xlate(cmd_code), 2784291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 2785*82527734SSukumar Swaminathan ULPSTATUS), 2786291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp. 2787291a2b48SSukumar Swaminathan perr.statLocalError)); 2788fcf3ce44SJohn Forte break; 2789fcf3ce44SJohn Forte 2790fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 2791fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2792fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2793fcf3ce44SJohn Forte "%s: %s %s", 2794fcf3ce44SJohn Forte emlxs_rmcmd_xlate(cmd_code), 2795291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 2796*82527734SSukumar Swaminathan ULPSTATUS), 2797291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp. 2798291a2b48SSukumar Swaminathan perr.statLocalError)); 2799fcf3ce44SJohn Forte break; 2800fcf3ce44SJohn Forte 2801fcf3ce44SJohn Forte default: 2802fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2803fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2804fcf3ce44SJohn Forte "%s: %s %s", 2805fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 2806291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 2807*82527734SSukumar Swaminathan ULPSTATUS), 2808291a2b48SSukumar Swaminathan emlxs_error_xlate(iocb->un.grsp. 2809291a2b48SSukumar Swaminathan perr.statLocalError)); 2810fcf3ce44SJohn Forte } 2811fcf3ce44SJohn Forte } else { 2812fcf3ce44SJohn Forte switch (CtCmd->FsType) { 2813fcf3ce44SJohn Forte case 0xFC: /* Name server */ 2814fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2815fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2816fcf3ce44SJohn Forte "%s: %s (%02x%02x%02x%02x)", 2817fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 2818291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 2819*82527734SSukumar Swaminathan ULPSTATUS), 2820fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 2821fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 2822fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 2823291a2b48SSukumar Swaminathan iocb->un.grsp.perr. 2824291a2b48SSukumar Swaminathan statLocalError); 2825fcf3ce44SJohn Forte break; 2826fcf3ce44SJohn Forte 2827fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 2828fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2829fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2830fcf3ce44SJohn Forte "%s: %s (%02x%02x%02x%02x)", 2831fcf3ce44SJohn Forte emlxs_mscmd_xlate(cmd_code), 2832291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 2833*82527734SSukumar Swaminathan ULPSTATUS), 2834fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 2835fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 2836fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 2837291a2b48SSukumar Swaminathan iocb->un.grsp.perr. 2838291a2b48SSukumar Swaminathan statLocalError); 2839fcf3ce44SJohn Forte break; 2840fcf3ce44SJohn Forte 2841fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 2842fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2843fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2844fcf3ce44SJohn Forte "%s: %s (%02x%02x%02x%02x)", 2845fcf3ce44SJohn Forte emlxs_rmcmd_xlate(cmd_code), 2846291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 2847*82527734SSukumar Swaminathan ULPSTATUS), 2848fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 2849fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 2850fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 2851291a2b48SSukumar Swaminathan iocb->un.grsp.perr. 2852291a2b48SSukumar Swaminathan statLocalError); 2853fcf3ce44SJohn Forte break; 2854fcf3ce44SJohn Forte 2855fcf3ce44SJohn Forte default: 2856fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2857fcf3ce44SJohn Forte &emlxs_ct_completion_msg, 2858fcf3ce44SJohn Forte "%s: %s (%02x%02x%02x%02x)", 2859fcf3ce44SJohn Forte emlxs_ctcmd_xlate(cmd_code), 2860291a2b48SSukumar Swaminathan emlxs_state_xlate(iocb-> 2861*82527734SSukumar Swaminathan ULPSTATUS), 2862fcf3ce44SJohn Forte iocb->un.grsp.perr.statAction, 2863fcf3ce44SJohn Forte iocb->un.grsp.perr.statRsn, 2864fcf3ce44SJohn Forte iocb->un.grsp.perr.statBaExp, 2865291a2b48SSukumar Swaminathan iocb->un.grsp.perr. 2866291a2b48SSukumar Swaminathan statLocalError); 2867fcf3ce44SJohn Forte } 2868fcf3ce44SJohn Forte } 2869fcf3ce44SJohn Forte } 2870fcf3ce44SJohn Forte 2871*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2872fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2873fcf3ce44SJohn Forte 2874fcf3ce44SJohn Forte break; 2875fcf3ce44SJohn Forte 2876fcf3ce44SJohn Forte default: 2877fcf3ce44SJohn Forte 2878fcf3ce44SJohn Forte HBASTATS.CtStray++; 2879fcf3ce44SJohn Forte 2880fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg, 2881*82527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND); 2882fcf3ce44SJohn Forte 2883*82527734SSukumar Swaminathan emlxs_pkt_complete(sbp, iocb->ULPSTATUS, 2884fcf3ce44SJohn Forte iocb->un.grsp.perr.statLocalError, 1); 2885fcf3ce44SJohn Forte 2886fcf3ce44SJohn Forte break; 2887*82527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */ 2888fcf3ce44SJohn Forte 2889fcf3ce44SJohn Forte return (0); 2890fcf3ce44SJohn Forte 2891*82527734SSukumar Swaminathan } /* emlxs_ct_handle_event() */ 2892fcf3ce44SJohn Forte 2893fcf3ce44SJohn Forte 2894fcf3ce44SJohn Forte extern int 2895*82527734SSukumar Swaminathan emlxs_ct_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 2896fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 2897fcf3ce44SJohn Forte { 2898fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2899fcf3ce44SJohn Forte IOCB *iocb; 2900fcf3ce44SJohn Forte SLI_CT_REQUEST *CtCmd; 2901fcf3ce44SJohn Forte uint32_t cmd_code; 2902fcf3ce44SJohn Forte 2903fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2904fcf3ce44SJohn Forte 2905fcf3ce44SJohn Forte CtCmd = (SLI_CT_REQUEST *)mp->virt; 2906*82527734SSukumar Swaminathan cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp); 2907fcf3ce44SJohn Forte 2908fcf3ce44SJohn Forte if (cmd_code == SLI_CT_LOOPBACK) { 2909fcf3ce44SJohn Forte int rval; 2910fcf3ce44SJohn Forte 2911*82527734SSukumar Swaminathan rval = emlxs_dfc_handle_unsol_req(port, cp, iocbq, mp, size); 2912fcf3ce44SJohn Forte 2913fcf3ce44SJohn Forte return (rval); 2914fcf3ce44SJohn Forte } 2915fcf3ce44SJohn Forte 2916fcf3ce44SJohn Forte HBASTATS.CtCmdReceived++; 2917fcf3ce44SJohn Forte 2918fcf3ce44SJohn Forte switch (CtCmd->FsType) { 2919fcf3ce44SJohn Forte case 0xFC: /* Name server */ 2920fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 2921291a2b48SSukumar Swaminathan "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code), 2922*82527734SSukumar Swaminathan CtCmd, size, iocb->ULPCONTEXT); 2923fcf3ce44SJohn Forte break; 2924fcf3ce44SJohn Forte 2925fcf3ce44SJohn Forte case 0xFA: /* Managment server */ 2926fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 2927291a2b48SSukumar Swaminathan "%s: pl=%p size=%d rxid=%x", emlxs_mscmd_xlate(cmd_code), 2928*82527734SSukumar Swaminathan CtCmd, size, iocb->ULPCONTEXT); 2929fcf3ce44SJohn Forte break; 2930fcf3ce44SJohn Forte 2931fcf3ce44SJohn Forte case 0x0A: /* Emulex Remote server */ 2932fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 2933291a2b48SSukumar Swaminathan "%s: pl=%p size=%d rxid=%x", emlxs_rmcmd_xlate(cmd_code), 2934*82527734SSukumar Swaminathan CtCmd, size, iocb->ULPCONTEXT); 2935fcf3ce44SJohn Forte break; 2936fcf3ce44SJohn Forte 2937fcf3ce44SJohn Forte default: 2938fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 2939291a2b48SSukumar Swaminathan "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code), 2940*82527734SSukumar Swaminathan CtCmd, size, iocb->ULPCONTEXT); 2941fcf3ce44SJohn Forte } 2942fcf3ce44SJohn Forte 2943728bdc9bSSukumar Swaminathan if (emlxs_log_ct_event(port, (uint8_t *)mp->virt, size, 2944*82527734SSukumar Swaminathan iocb->ULPCONTEXT)) { 2945728bdc9bSSukumar Swaminathan /* Abort the exchange */ 2946*82527734SSukumar Swaminathan emlxs_abort_ct_exchange(hba, port, iocb->ULPCONTEXT); 2947728bdc9bSSukumar Swaminathan } 2948fcf3ce44SJohn Forte 2949fcf3ce44SJohn Forte return (0); 2950fcf3ce44SJohn Forte 2951*82527734SSukumar Swaminathan } /* emlxs_ct_handle_unsol_req() */ 2952fcf3ce44SJohn Forte 2953fcf3ce44SJohn Forte 2954fcf3ce44SJohn Forte static void 2955fcf3ce44SJohn Forte emlxs_send_rsnn(emlxs_port_t *port) 2956fcf3ce44SJohn Forte { 2957fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2958fcf3ce44SJohn Forte fc_packet_t *pkt; 2959fcf3ce44SJohn Forte SLI_CT_REQUEST *ct; 2960fcf3ce44SJohn Forte 2961291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, sizeof (SLI_CT_REQUEST), 2962291a2b48SSukumar Swaminathan sizeof (SLI_CT_REQUEST), 0, KM_NOSLEEP))) { 2963fcf3ce44SJohn Forte return; 2964fcf3ce44SJohn Forte } 2965291a2b48SSukumar Swaminathan 2966fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 2967fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 2968fcf3ce44SJohn Forte 2969fcf3ce44SJohn Forte /* Build the fc header */ 2970*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(NAMESERVER_DID); 2971fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL; 2972*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 2973fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES; 2974291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 2975291a2b48SSukumar Swaminathan F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 2976fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2977fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2978fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2979fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 2980fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff; 2981fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2982fcf3ce44SJohn Forte 2983fcf3ce44SJohn Forte /* Build the command */ 2984fcf3ce44SJohn Forte ct = (SLI_CT_REQUEST *)pkt->pkt_cmd; 2985fcf3ce44SJohn Forte 2986fcf3ce44SJohn Forte ct->RevisionId.bits.Revision = SLI_CT_REVISION; 2987fcf3ce44SJohn Forte ct->RevisionId.bits.InId = 0; 2988fcf3ce44SJohn Forte 2989fcf3ce44SJohn Forte ct->FsType = SLI_CT_DIRECTORY_SERVICE; 2990fcf3ce44SJohn Forte ct->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER; 2991fcf3ce44SJohn Forte 2992fcf3ce44SJohn Forte ct->CommandResponse.bits.Size = 0; 2993*82527734SSukumar Swaminathan ct->CommandResponse.bits.CmdRsp = LE_SWAP16(SLI_CTNS_RSNN_NN); 2994fcf3ce44SJohn Forte 2995fcf3ce44SJohn Forte bcopy((uint8_t *)&hba->wwnn, (char *)ct->un.rsnn.wwnn, 8); 2996fcf3ce44SJohn Forte 2997fcf3ce44SJohn Forte ct->un.rsnn.snn_len = strlen(port->snn); 2998fcf3ce44SJohn Forte bcopy(port->snn, (char *)ct->un.rsnn.snn, ct->un.rsnn.snn_len); 2999fcf3ce44SJohn Forte 3000291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_send_msg, "Sending RSNN_NN. [%s]", 3001fcf3ce44SJohn Forte port->snn); 3002fcf3ce44SJohn Forte 3003fcf3ce44SJohn Forte /* Send the pkt later in another thread */ 3004fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 0) != FC_SUCCESS) { 3005fcf3ce44SJohn Forte /* Free the pkt */ 3006fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3007fcf3ce44SJohn Forte } 3008291a2b48SSukumar Swaminathan 3009fcf3ce44SJohn Forte return; 3010fcf3ce44SJohn Forte 3011*82527734SSukumar Swaminathan } /* emlxs_send_rsnn() */ 3012fcf3ce44SJohn Forte 3013fcf3ce44SJohn Forte 3014fcf3ce44SJohn Forte extern uint32_t 3015fcf3ce44SJohn Forte emlxs_ub_send_login_acc(emlxs_port_t *port, fc_unsol_buf_t *ubp) 3016fcf3ce44SJohn Forte { 3017fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3018fcf3ce44SJohn Forte fc_packet_t *pkt; 3019fcf3ce44SJohn Forte ELS_PKT *els; 3020fcf3ce44SJohn Forte uint32_t rval; 3021fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 3022fcf3ce44SJohn Forte 3023fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 3024fcf3ce44SJohn Forte 3025fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, 3026fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (SERV_PARM), 0, 0, KM_NOSLEEP))) { 3027fcf3ce44SJohn Forte return (1); 3028fcf3ce44SJohn Forte } 3029291a2b48SSukumar Swaminathan 3030fcf3ce44SJohn Forte /* Common initialization */ 3031fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 3032fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 3033fcf3ce44SJohn Forte 3034fcf3ce44SJohn Forte if ((uint32_t)ubp->ub_class == FC_TRAN_CLASS2) { 3035fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3; 3036fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_CLASS2; 3037fcf3ce44SJohn Forte } 3038291a2b48SSukumar Swaminathan 3039fcf3ce44SJohn Forte /* Build the fc header */ 3040fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = ubp->ub_frame.s_id; 3041291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 3042291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 3043fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = ubp->ub_frame.d_id; 3044fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 3045291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 3046291a2b48SSukumar Swaminathan F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 3047fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3048fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3049fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3050fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = (ub_priv->cmd >> ELS_CMD_SHIFT) & 0xff; 3051fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = ubp->ub_frame.rx_id; 3052fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3053fcf3ce44SJohn Forte 3054fcf3ce44SJohn Forte /* Build the command */ 3055291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_cmd; 3056fcf3ce44SJohn Forte els->elsCode = 0x02; 3057291a2b48SSukumar Swaminathan bcopy((void *)&port->sparam, (void *)&els->un.logi, 3058291a2b48SSukumar Swaminathan sizeof (SERV_PARM)); 3059fcf3ce44SJohn Forte 3060fcf3ce44SJohn Forte if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) { 3061fcf3ce44SJohn Forte /* Free the pkt */ 3062fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3063fcf3ce44SJohn Forte } else { 3064fcf3ce44SJohn Forte ub_priv->flags |= EMLXS_UB_INTERCEPT; 3065fcf3ce44SJohn Forte } 3066fcf3ce44SJohn Forte 3067fcf3ce44SJohn Forte return (rval); 3068fcf3ce44SJohn Forte 3069*82527734SSukumar Swaminathan } /* emlxs_ub_send_login_acc */ 3070fcf3ce44SJohn Forte 3071fcf3ce44SJohn Forte 3072fcf3ce44SJohn Forte extern void 3073fcf3ce44SJohn Forte emlxs_send_logo(emlxs_port_t *port, uint32_t d_id) 3074fcf3ce44SJohn Forte { 3075fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3076fcf3ce44SJohn Forte fc_packet_t *pkt; 3077fcf3ce44SJohn Forte ELS_PKT *els; 3078fcf3ce44SJohn Forte 3079fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 3080fcf3ce44SJohn Forte return; 3081fcf3ce44SJohn Forte } 3082291a2b48SSukumar Swaminathan 3083291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, 3084291a2b48SSukumar Swaminathan sizeof (uint32_t) + sizeof (LOGO), 3085fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (LOGO), 0, KM_NOSLEEP))) { 3086fcf3ce44SJohn Forte return; 3087fcf3ce44SJohn Forte } 3088291a2b48SSukumar Swaminathan 3089fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 3090fcf3ce44SJohn Forte pkt->pkt_timeout = (2 * hba->fc_ratov); 3091fcf3ce44SJohn Forte 3092fcf3ce44SJohn Forte /* Build the fc header */ 3093*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(d_id); 3094291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 3095291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 3096*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 3097fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 3098291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 3099291a2b48SSukumar Swaminathan F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 3100fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3101fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3102fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3103fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 3104fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff; 3105fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3106fcf3ce44SJohn Forte 3107fcf3ce44SJohn Forte /* Build the command */ 3108fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_cmd; 3109fcf3ce44SJohn Forte els->elsCode = 0x05; 3110fcf3ce44SJohn Forte els->un.logo.un.nPortId32 = pkt->pkt_cmd_fhdr.s_id; 3111291a2b48SSukumar Swaminathan bcopy((uint8_t *)&port->wwpn, (uint8_t *)&els->un.logo.portName, 3112291a2b48SSukumar Swaminathan 8); 3113fcf3ce44SJohn Forte 3114fcf3ce44SJohn Forte /* Send the pkt now */ 3115fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 3116fcf3ce44SJohn Forte /* Free the pkt */ 3117fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3118fcf3ce44SJohn Forte } 3119291a2b48SSukumar Swaminathan 3120fcf3ce44SJohn Forte return; 3121fcf3ce44SJohn Forte 3122fcf3ce44SJohn Forte } /* emlxs_send_logo() */ 3123