1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte 22*fcf3ce44SJohn Forte /* 23*fcf3ce44SJohn Forte * Copyright 2008 Emulex. All rights reserved. 24*fcf3ce44SJohn Forte * Use is subject to License terms. 25*fcf3ce44SJohn Forte */ 26*fcf3ce44SJohn Forte 27*fcf3ce44SJohn Forte 28*fcf3ce44SJohn Forte #include "emlxs.h" 29*fcf3ce44SJohn Forte 30*fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 31*fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_MBOX_C); 32*fcf3ce44SJohn Forte 33*fcf3ce44SJohn Forte static void emlxs_mb_part_slim(emlxs_hba_t *hba, MAILBOX *mb, 34*fcf3ce44SJohn Forte uint32_t hbainit); 35*fcf3ce44SJohn Forte static void emlxs_mb_set_mask(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mask, 36*fcf3ce44SJohn Forte uint32_t ringno); 37*fcf3ce44SJohn Forte static void emlxs_mb_set_debug(emlxs_hba_t *hba, MAILBOX *mb, uint32_t word0, 38*fcf3ce44SJohn Forte uint32_t word1, uint32_t word2); 39*fcf3ce44SJohn Forte static int32_t emlxs_mb_handle_cmd(emlxs_hba_t *hba, MAILBOX *mb); 40*fcf3ce44SJohn Forte static void emlxs_mb_write_nv(emlxs_hba_t *hba, MAILBOX *mb); 41*fcf3ce44SJohn Forte 42*fcf3ce44SJohn Forte static void emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, 43*fcf3ce44SJohn Forte uint32_t tmo); 44*fcf3ce44SJohn Forte static void emlxs_mb_retry(emlxs_hba_t *hba, MAILBOX *mb); 45*fcf3ce44SJohn Forte 46*fcf3ce44SJohn Forte 47*fcf3ce44SJohn Forte emlxs_table_t emlxs_mb_cmd_table[] = 48*fcf3ce44SJohn Forte { 49*fcf3ce44SJohn Forte {MBX_SHUTDOWN, "SHUTDOWN"}, 50*fcf3ce44SJohn Forte {MBX_LOAD_SM, "LOAD_SM"}, 51*fcf3ce44SJohn Forte {MBX_READ_NV, "READ_NV"}, 52*fcf3ce44SJohn Forte {MBX_WRITE_NV, "WRITE_NV"}, 53*fcf3ce44SJohn Forte {MBX_RUN_BIU_DIAG, "RUN_BIU_DIAG"}, 54*fcf3ce44SJohn Forte {MBX_INIT_LINK, "INIT_LINK"}, 55*fcf3ce44SJohn Forte {MBX_DOWN_LINK, "DOWN_LINK"}, 56*fcf3ce44SJohn Forte {MBX_CONFIG_LINK, "CONFIG_LINK"}, 57*fcf3ce44SJohn Forte {MBX_PART_SLIM, "PART_SLIM"}, 58*fcf3ce44SJohn Forte {MBX_CONFIG_RING, "CONFIG_RING"}, 59*fcf3ce44SJohn Forte {MBX_RESET_RING, "RESET_RING"}, 60*fcf3ce44SJohn Forte {MBX_READ_CONFIG, "READ_CONFIG"}, 61*fcf3ce44SJohn Forte {MBX_READ_RCONFIG, "READ_RCONFIG"}, 62*fcf3ce44SJohn Forte {MBX_READ_SPARM, "READ_SPARM"}, 63*fcf3ce44SJohn Forte {MBX_READ_STATUS, "READ_STATUS"}, 64*fcf3ce44SJohn Forte {MBX_READ_RPI, "READ_RPI"}, 65*fcf3ce44SJohn Forte {MBX_READ_XRI, "READ_XRI"}, 66*fcf3ce44SJohn Forte {MBX_READ_REV, "READ_REV"}, 67*fcf3ce44SJohn Forte {MBX_READ_LNK_STAT, "READ_LNK_STAT"}, 68*fcf3ce44SJohn Forte {MBX_REG_LOGIN, "REG_LOGIN"}, 69*fcf3ce44SJohn Forte {MBX_UNREG_LOGIN, "UNREG_LOGIN"}, 70*fcf3ce44SJohn Forte {MBX_READ_LA, "READ_LA"}, 71*fcf3ce44SJohn Forte {MBX_CLEAR_LA, "CLEAR_LA"}, 72*fcf3ce44SJohn Forte {MBX_DUMP_MEMORY, "DUMP_MEMORY"}, 73*fcf3ce44SJohn Forte {MBX_DUMP_CONTEXT, "DUMP_CONTEXT"}, 74*fcf3ce44SJohn Forte {MBX_RUN_DIAGS, "RUN_DIAGS"}, 75*fcf3ce44SJohn Forte {MBX_RESTART, "RESTART"}, 76*fcf3ce44SJohn Forte {MBX_UPDATE_CFG, "UPDATE_CFG"}, 77*fcf3ce44SJohn Forte {MBX_DOWN_LOAD, "DOWN_LOAD"}, 78*fcf3ce44SJohn Forte {MBX_DEL_LD_ENTRY, "DEL_LD_ENTRY"}, 79*fcf3ce44SJohn Forte {MBX_RUN_PROGRAM, "RUN_PROGRAM"}, 80*fcf3ce44SJohn Forte {MBX_SET_MASK, "SET_MASK"}, 81*fcf3ce44SJohn Forte {MBX_SET_VARIABLE, "SET_VARIABLE"}, 82*fcf3ce44SJohn Forte {MBX_UNREG_D_ID, "UNREG_D_ID"}, 83*fcf3ce44SJohn Forte {MBX_KILL_BOARD, "KILL_BOARD"}, 84*fcf3ce44SJohn Forte {MBX_CONFIG_FARP, "CONFIG_FARP"}, 85*fcf3ce44SJohn Forte {MBX_LOAD_AREA, "LOAD_AREA"}, 86*fcf3ce44SJohn Forte {MBX_RUN_BIU_DIAG64, "RUN_BIU_DIAG64"}, 87*fcf3ce44SJohn Forte {MBX_CONFIG_PORT, "CONFIG_PORT"}, 88*fcf3ce44SJohn Forte {MBX_READ_SPARM64, "READ_SPARM64"}, 89*fcf3ce44SJohn Forte {MBX_READ_RPI64, "READ_RPI64"}, 90*fcf3ce44SJohn Forte {MBX_CONFIG_MSI, "CONFIG_MSI"}, 91*fcf3ce44SJohn Forte {MBX_CONFIG_MSIX, "CONFIG_MSIX"}, 92*fcf3ce44SJohn Forte {MBX_REG_LOGIN64, "REG_LOGIN64"}, 93*fcf3ce44SJohn Forte {MBX_READ_LA64, "READ_LA64"}, 94*fcf3ce44SJohn Forte {MBX_FLASH_WR_ULA, "FLASH_WR_ULA"}, 95*fcf3ce44SJohn Forte {MBX_SET_DEBUG, "SET_DEBUG"}, 96*fcf3ce44SJohn Forte {MBX_GET_DEBUG, "GET_DEBUG"}, 97*fcf3ce44SJohn Forte {MBX_LOAD_EXP_ROM, "LOAD_EXP_ROM"}, 98*fcf3ce44SJohn Forte {MBX_BEACON, "BEACON"}, 99*fcf3ce44SJohn Forte {MBX_CONFIG_HBQ, "CONFIG_HBQ"}, /* SLI3 */ 100*fcf3ce44SJohn Forte {MBX_REG_VPI, "REG_VPI"}, /* NPIV */ 101*fcf3ce44SJohn Forte {MBX_ASYNC_EVENT, "ASYNC_EVENT"}, 102*fcf3ce44SJohn Forte {MBX_HEARTBEAT, "HEARTBEAT"}, 103*fcf3ce44SJohn Forte {MBX_READ_EVENT_LOG_STATUS, "READ_EVENT_LOG_STATUS"}, 104*fcf3ce44SJohn Forte {MBX_READ_EVENT_LOG, "READ_EVENT_LOG"}, 105*fcf3ce44SJohn Forte {MBX_WRITE_EVENT_LOG, "WRITE_EVENT_LOG"}, 106*fcf3ce44SJohn Forte {MBX_NV_LOG, "NV_LOG"} 107*fcf3ce44SJohn Forte 108*fcf3ce44SJohn Forte }; /* emlxs_mb_cmd_table */ 109*fcf3ce44SJohn Forte 110*fcf3ce44SJohn Forte 111*fcf3ce44SJohn Forte /* ARGSUSED */ 112*fcf3ce44SJohn Forte extern void 113*fcf3ce44SJohn Forte emlxs_mb_async_event(emlxs_hba_t *hba, MAILBOX *mb) 114*fcf3ce44SJohn Forte { 115*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 116*fcf3ce44SJohn Forte 117*fcf3ce44SJohn Forte mb->mbxCommand = MBX_ASYNC_EVENT; 118*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 119*fcf3ce44SJohn Forte mb->un.varWords[0] = FC_ELS_RING; 120*fcf3ce44SJohn Forte 121*fcf3ce44SJohn Forte return; 122*fcf3ce44SJohn Forte 123*fcf3ce44SJohn Forte } /* emlxs_mb_async_event() */ 124*fcf3ce44SJohn Forte 125*fcf3ce44SJohn Forte 126*fcf3ce44SJohn Forte /* ARGSUSED */ 127*fcf3ce44SJohn Forte extern void 128*fcf3ce44SJohn Forte emlxs_mb_heartbeat(emlxs_hba_t *hba, MAILBOX *mb) 129*fcf3ce44SJohn Forte { 130*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 131*fcf3ce44SJohn Forte 132*fcf3ce44SJohn Forte mb->mbxCommand = MBX_HEARTBEAT; 133*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 134*fcf3ce44SJohn Forte 135*fcf3ce44SJohn Forte return; 136*fcf3ce44SJohn Forte 137*fcf3ce44SJohn Forte } /* emlxs_mb_heartbeat() */ 138*fcf3ce44SJohn Forte 139*fcf3ce44SJohn Forte 140*fcf3ce44SJohn Forte #ifdef MSI_SUPPORT 141*fcf3ce44SJohn Forte 142*fcf3ce44SJohn Forte /* ARGSUSED */ 143*fcf3ce44SJohn Forte extern void 144*fcf3ce44SJohn Forte emlxs_mb_config_msi(emlxs_hba_t *hba, MAILBOX *mb, uint32_t *intr_map, 145*fcf3ce44SJohn Forte uint32_t intr_count) 146*fcf3ce44SJohn Forte { 147*fcf3ce44SJohn Forte uint32_t i; 148*fcf3ce44SJohn Forte uint32_t mask; 149*fcf3ce44SJohn Forte 150*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 151*fcf3ce44SJohn Forte 152*fcf3ce44SJohn Forte mb->mbxCommand = MBX_CONFIG_MSI; 153*fcf3ce44SJohn Forte 154*fcf3ce44SJohn Forte /* Set the default message id to zero */ 155*fcf3ce44SJohn Forte mb->un.varCfgMSI.defaultPresent = 1; 156*fcf3ce44SJohn Forte mb->un.varCfgMSI.defaultMessageNumber = 0; 157*fcf3ce44SJohn Forte 158*fcf3ce44SJohn Forte for (i = 1; i < intr_count; i++) { 159*fcf3ce44SJohn Forte mask = intr_map[i]; 160*fcf3ce44SJohn Forte 161*fcf3ce44SJohn Forte mb->un.varCfgMSI.attConditions |= mask; 162*fcf3ce44SJohn Forte 163*fcf3ce44SJohn Forte #ifdef EMLXS_BIG_ENDIAN 164*fcf3ce44SJohn Forte if (mask & HA_R0ATT) { 165*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[3] = i; 166*fcf3ce44SJohn Forte } 167*fcf3ce44SJohn Forte if (mask & HA_R1ATT) { 168*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[7] = i; 169*fcf3ce44SJohn Forte } 170*fcf3ce44SJohn Forte if (mask & HA_R2ATT) { 171*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[11] = i; 172*fcf3ce44SJohn Forte } 173*fcf3ce44SJohn Forte if (mask & HA_R3ATT) { 174*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[15] = i; 175*fcf3ce44SJohn Forte } 176*fcf3ce44SJohn Forte if (mask & HA_LATT) { 177*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[29] = i; 178*fcf3ce44SJohn Forte } 179*fcf3ce44SJohn Forte if (mask & HA_MBATT) { 180*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[30] = i; 181*fcf3ce44SJohn Forte } 182*fcf3ce44SJohn Forte if (mask & HA_ERATT) { 183*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[31] = i; 184*fcf3ce44SJohn Forte } 185*fcf3ce44SJohn Forte #endif /* EMLXS_BIG_ENDIAN */ 186*fcf3ce44SJohn Forte 187*fcf3ce44SJohn Forte #ifdef EMLXS_LITTLE_ENDIAN 188*fcf3ce44SJohn Forte /* Accounts for half word swap of LE architecture */ 189*fcf3ce44SJohn Forte if (mask & HA_R0ATT) { 190*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[2] = i; 191*fcf3ce44SJohn Forte } 192*fcf3ce44SJohn Forte if (mask & HA_R1ATT) { 193*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[6] = i; 194*fcf3ce44SJohn Forte } 195*fcf3ce44SJohn Forte if (mask & HA_R2ATT) { 196*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[10] = i; 197*fcf3ce44SJohn Forte } 198*fcf3ce44SJohn Forte if (mask & HA_R3ATT) { 199*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[14] = i; 200*fcf3ce44SJohn Forte } 201*fcf3ce44SJohn Forte if (mask & HA_LATT) { 202*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[28] = i; 203*fcf3ce44SJohn Forte } 204*fcf3ce44SJohn Forte if (mask & HA_MBATT) { 205*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[31] = i; 206*fcf3ce44SJohn Forte } 207*fcf3ce44SJohn Forte if (mask & HA_ERATT) { 208*fcf3ce44SJohn Forte mb->un.varCfgMSI.messageNumberByHA[30] = i; 209*fcf3ce44SJohn Forte } 210*fcf3ce44SJohn Forte #endif /* EMLXS_LITTLE_ENDIAN */ 211*fcf3ce44SJohn Forte } 212*fcf3ce44SJohn Forte 213*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 214*fcf3ce44SJohn Forte 215*fcf3ce44SJohn Forte return; 216*fcf3ce44SJohn Forte 217*fcf3ce44SJohn Forte } /* emlxs_mb_config_msi() */ 218*fcf3ce44SJohn Forte 219*fcf3ce44SJohn Forte 220*fcf3ce44SJohn Forte /* ARGSUSED */ 221*fcf3ce44SJohn Forte extern void 222*fcf3ce44SJohn Forte emlxs_mb_config_msix(emlxs_hba_t *hba, MAILBOX *mb, uint32_t *intr_map, 223*fcf3ce44SJohn Forte uint32_t intr_count) 224*fcf3ce44SJohn Forte { 225*fcf3ce44SJohn Forte uint32_t i; 226*fcf3ce44SJohn Forte uint32_t mask; 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 229*fcf3ce44SJohn Forte 230*fcf3ce44SJohn Forte mb->mbxCommand = MBX_CONFIG_MSIX; 231*fcf3ce44SJohn Forte 232*fcf3ce44SJohn Forte /* Set the default message id to zero */ 233*fcf3ce44SJohn Forte mb->un.varCfgMSIX.defaultPresent = 1; 234*fcf3ce44SJohn Forte mb->un.varCfgMSIX.defaultMessageNumber = 0; 235*fcf3ce44SJohn Forte 236*fcf3ce44SJohn Forte for (i = 1; i < intr_count; i++) { 237*fcf3ce44SJohn Forte mask = intr_map[i]; 238*fcf3ce44SJohn Forte 239*fcf3ce44SJohn Forte mb->un.varCfgMSIX.attConditions1 |= mask; 240*fcf3ce44SJohn Forte 241*fcf3ce44SJohn Forte #ifdef EMLXS_BIG_ENDIAN 242*fcf3ce44SJohn Forte if (mask & HA_R0ATT) { 243*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[3] = i; 244*fcf3ce44SJohn Forte } 245*fcf3ce44SJohn Forte if (mask & HA_R1ATT) { 246*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[7] = i; 247*fcf3ce44SJohn Forte } 248*fcf3ce44SJohn Forte if (mask & HA_R2ATT) { 249*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[11] = i; 250*fcf3ce44SJohn Forte } 251*fcf3ce44SJohn Forte if (mask & HA_R3ATT) { 252*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[15] = i; 253*fcf3ce44SJohn Forte } 254*fcf3ce44SJohn Forte if (mask & HA_LATT) { 255*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[29] = i; 256*fcf3ce44SJohn Forte } 257*fcf3ce44SJohn Forte if (mask & HA_MBATT) { 258*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[30] = i; 259*fcf3ce44SJohn Forte } 260*fcf3ce44SJohn Forte if (mask & HA_ERATT) { 261*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[31] = i; 262*fcf3ce44SJohn Forte } 263*fcf3ce44SJohn Forte #endif /* EMLXS_BIG_ENDIAN */ 264*fcf3ce44SJohn Forte 265*fcf3ce44SJohn Forte #ifdef EMLXS_LITTLE_ENDIAN 266*fcf3ce44SJohn Forte /* Accounts for word swap of LE architecture */ 267*fcf3ce44SJohn Forte if (mask & HA_R0ATT) { 268*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[0] = i; 269*fcf3ce44SJohn Forte } 270*fcf3ce44SJohn Forte if (mask & HA_R1ATT) { 271*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[4] = i; 272*fcf3ce44SJohn Forte } 273*fcf3ce44SJohn Forte if (mask & HA_R2ATT) { 274*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[8] = i; 275*fcf3ce44SJohn Forte } 276*fcf3ce44SJohn Forte if (mask & HA_R3ATT) { 277*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[12] = i; 278*fcf3ce44SJohn Forte } 279*fcf3ce44SJohn Forte if (mask & HA_LATT) { 280*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[30] = i; 281*fcf3ce44SJohn Forte } 282*fcf3ce44SJohn Forte if (mask & HA_MBATT) { 283*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[29] = i; 284*fcf3ce44SJohn Forte } 285*fcf3ce44SJohn Forte if (mask & HA_ERATT) { 286*fcf3ce44SJohn Forte mb->un.varCfgMSIX.messageNumberByHA[28] = i; 287*fcf3ce44SJohn Forte } 288*fcf3ce44SJohn Forte #endif /* EMLXS_LITTLE_ENDIAN */ 289*fcf3ce44SJohn Forte } 290*fcf3ce44SJohn Forte 291*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 292*fcf3ce44SJohn Forte 293*fcf3ce44SJohn Forte return; 294*fcf3ce44SJohn Forte 295*fcf3ce44SJohn Forte } /* emlxs_mb_config_msix() */ 296*fcf3ce44SJohn Forte 297*fcf3ce44SJohn Forte 298*fcf3ce44SJohn Forte #endif /* MSI_SUPPORT */ 299*fcf3ce44SJohn Forte 300*fcf3ce44SJohn Forte /* ARGSUSED */ 301*fcf3ce44SJohn Forte extern void 302*fcf3ce44SJohn Forte emlxs_mb_reset_ring(emlxs_hba_t *hba, MAILBOX *mb, uint32_t ringno) 303*fcf3ce44SJohn Forte { 304*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 305*fcf3ce44SJohn Forte 306*fcf3ce44SJohn Forte mb->mbxCommand = MBX_RESET_RING; 307*fcf3ce44SJohn Forte mb->un.varRstRing.ring_no = ringno; 308*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 309*fcf3ce44SJohn Forte 310*fcf3ce44SJohn Forte return; 311*fcf3ce44SJohn Forte 312*fcf3ce44SJohn Forte } /* emlxs_mb_reset_ring() */ 313*fcf3ce44SJohn Forte 314*fcf3ce44SJohn Forte 315*fcf3ce44SJohn Forte 316*fcf3ce44SJohn Forte /* 317*fcf3ce44SJohn Forte * emlxs_mb_dump_vpd Issue a DUMP MEMORY 318*fcf3ce44SJohn Forte * mailbox command 319*fcf3ce44SJohn Forte */ 320*fcf3ce44SJohn Forte /* ARGSUSED */ 321*fcf3ce44SJohn Forte extern void 322*fcf3ce44SJohn Forte emlxs_mb_dump_vpd(emlxs_hba_t *hba, MAILBOX *mb, uint32_t offset) 323*fcf3ce44SJohn Forte { 324*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 325*fcf3ce44SJohn Forte 326*fcf3ce44SJohn Forte /* 327*fcf3ce44SJohn Forte * Setup to dump VPD region 328*fcf3ce44SJohn Forte */ 329*fcf3ce44SJohn Forte mb->mbxCommand = MBX_DUMP_MEMORY; 330*fcf3ce44SJohn Forte mb->un.varDmp.cv = 1; 331*fcf3ce44SJohn Forte mb->un.varDmp.type = DMP_NV_PARAMS; 332*fcf3ce44SJohn Forte mb->un.varDmp.entry_index = offset; 333*fcf3ce44SJohn Forte mb->un.varDmp.region_id = DMP_VPD_REGION; 334*fcf3ce44SJohn Forte mb->un.varDmp.word_cnt = DMP_VPD_DUMP_WCOUNT; /* limited by */ 335*fcf3ce44SJohn Forte /* mailbox size */ 336*fcf3ce44SJohn Forte 337*fcf3ce44SJohn Forte mb->un.varDmp.co = 0; 338*fcf3ce44SJohn Forte mb->un.varDmp.resp_offset = 0; 339*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 340*fcf3ce44SJohn Forte } /* emlxs_mb_dump_vpd() */ 341*fcf3ce44SJohn Forte 342*fcf3ce44SJohn Forte 343*fcf3ce44SJohn Forte /* 344*fcf3ce44SJohn Forte * emlxs_mb_read_nv Issue a READ NVPARAM 345*fcf3ce44SJohn Forte * mailbox command 346*fcf3ce44SJohn Forte */ 347*fcf3ce44SJohn Forte /* ARGSUSED */ 348*fcf3ce44SJohn Forte extern void 349*fcf3ce44SJohn Forte emlxs_mb_read_nv(emlxs_hba_t *hba, MAILBOX *mb) 350*fcf3ce44SJohn Forte { 351*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 352*fcf3ce44SJohn Forte 353*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_NV; 354*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 355*fcf3ce44SJohn Forte 356*fcf3ce44SJohn Forte } /* End emlxs_mb_read_nv */ 357*fcf3ce44SJohn Forte 358*fcf3ce44SJohn Forte 359*fcf3ce44SJohn Forte /* 360*fcf3ce44SJohn Forte * emlxs_mb_read_rev Issue a READ REV 361*fcf3ce44SJohn Forte * mailbox command 362*fcf3ce44SJohn Forte */ 363*fcf3ce44SJohn Forte /* ARGSUSED */ 364*fcf3ce44SJohn Forte extern void 365*fcf3ce44SJohn Forte emlxs_mb_read_rev(emlxs_hba_t *hba, MAILBOX *mb, uint32_t v3) 366*fcf3ce44SJohn Forte { 367*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 368*fcf3ce44SJohn Forte 369*fcf3ce44SJohn Forte mb->un.varRdRev.cv = 1; 370*fcf3ce44SJohn Forte 371*fcf3ce44SJohn Forte if (v3) { 372*fcf3ce44SJohn Forte mb->un.varRdRev.cv3 = 1; 373*fcf3ce44SJohn Forte } 374*fcf3ce44SJohn Forte 375*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_REV; 376*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 377*fcf3ce44SJohn Forte 378*fcf3ce44SJohn Forte } /* End emlxs_mb_read_rev */ 379*fcf3ce44SJohn Forte 380*fcf3ce44SJohn Forte 381*fcf3ce44SJohn Forte /* 382*fcf3ce44SJohn Forte * emlxs_mb_run_biu_diag Issue a RUN_BIU_DIAG 383*fcf3ce44SJohn Forte * mailbox command 384*fcf3ce44SJohn Forte */ 385*fcf3ce44SJohn Forte /* ARGSUSED */ 386*fcf3ce44SJohn Forte extern uint32_t 387*fcf3ce44SJohn Forte emlxs_mb_run_biu_diag(emlxs_hba_t *hba, MAILBOX *mb, uint64_t out, 388*fcf3ce44SJohn Forte uint64_t in) 389*fcf3ce44SJohn Forte { 390*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 391*fcf3ce44SJohn Forte 392*fcf3ce44SJohn Forte mb->mbxCommand = MBX_RUN_BIU_DIAG64; 393*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE; 394*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = 395*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(out); 396*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = 397*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(out); 398*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE; 399*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = 400*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(in); 401*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = (uint32_t)putPaddrLow(in); 402*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 403*fcf3ce44SJohn Forte 404*fcf3ce44SJohn Forte return (0); 405*fcf3ce44SJohn Forte 406*fcf3ce44SJohn Forte } /* End emlxs_mb_run_biu_diag */ 407*fcf3ce44SJohn Forte 408*fcf3ce44SJohn Forte 409*fcf3ce44SJohn Forte /* 410*fcf3ce44SJohn Forte * emlxs_mb_read_la Issue a READ LA 411*fcf3ce44SJohn Forte * mailbox command 412*fcf3ce44SJohn Forte */ 413*fcf3ce44SJohn Forte extern uint32_t 414*fcf3ce44SJohn Forte emlxs_mb_read_la(emlxs_hba_t *hba, MAILBOX *mb) 415*fcf3ce44SJohn Forte { 416*fcf3ce44SJohn Forte MATCHMAP *mp; 417*fcf3ce44SJohn Forte 418*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 419*fcf3ce44SJohn Forte 420*fcf3ce44SJohn Forte if ((mp = (MATCHMAP *) emlxs_mem_get(hba, MEM_BUF)) == 0) { 421*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_LA64; 422*fcf3ce44SJohn Forte 423*fcf3ce44SJohn Forte return (1); 424*fcf3ce44SJohn Forte } 425*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_LA64; 426*fcf3ce44SJohn Forte mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128; 427*fcf3ce44SJohn Forte mb->un.varReadLA.un.lilpBde64.addrHigh = 428*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(mp->phys); 429*fcf3ce44SJohn Forte mb->un.varReadLA.un.lilpBde64.addrLow = 430*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(mp->phys); 431*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 432*fcf3ce44SJohn Forte 433*fcf3ce44SJohn Forte /* 434*fcf3ce44SJohn Forte * save address for completion 435*fcf3ce44SJohn Forte */ 436*fcf3ce44SJohn Forte ((MAILBOXQ *)mb)->bp = (uint8_t *)mp; 437*fcf3ce44SJohn Forte 438*fcf3ce44SJohn Forte return (0); 439*fcf3ce44SJohn Forte 440*fcf3ce44SJohn Forte } /* emlxs_mb_read_la() */ 441*fcf3ce44SJohn Forte 442*fcf3ce44SJohn Forte 443*fcf3ce44SJohn Forte /* 444*fcf3ce44SJohn Forte * emlxs_mb_clear_la Issue a CLEAR LA 445*fcf3ce44SJohn Forte * mailbox command 446*fcf3ce44SJohn Forte */ 447*fcf3ce44SJohn Forte extern void 448*fcf3ce44SJohn Forte emlxs_mb_clear_la(emlxs_hba_t *hba, MAILBOX *mb) 449*fcf3ce44SJohn Forte { 450*fcf3ce44SJohn Forte #ifdef FC_RPI_CHECK 451*fcf3ce44SJohn Forte emlxs_rpi_check(hba); 452*fcf3ce44SJohn Forte #endif /* FC_RPI_CHECK */ 453*fcf3ce44SJohn Forte 454*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 455*fcf3ce44SJohn Forte 456*fcf3ce44SJohn Forte mb->un.varClearLA.eventTag = hba->link_event_tag; 457*fcf3ce44SJohn Forte mb->mbxCommand = MBX_CLEAR_LA; 458*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 459*fcf3ce44SJohn Forte 460*fcf3ce44SJohn Forte return; 461*fcf3ce44SJohn Forte 462*fcf3ce44SJohn Forte } /* End emlxs_mb_clear_la */ 463*fcf3ce44SJohn Forte 464*fcf3ce44SJohn Forte 465*fcf3ce44SJohn Forte /* 466*fcf3ce44SJohn Forte * emlxs_mb_read_status Issue a READ STATUS 467*fcf3ce44SJohn Forte * mailbox command 468*fcf3ce44SJohn Forte */ 469*fcf3ce44SJohn Forte /* ARGSUSED */ 470*fcf3ce44SJohn Forte extern void 471*fcf3ce44SJohn Forte emlxs_mb_read_status(emlxs_hba_t *hba, MAILBOX *mb) 472*fcf3ce44SJohn Forte { 473*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 474*fcf3ce44SJohn Forte 475*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_STATUS; 476*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 477*fcf3ce44SJohn Forte 478*fcf3ce44SJohn Forte } /* End fc_read_status */ 479*fcf3ce44SJohn Forte 480*fcf3ce44SJohn Forte 481*fcf3ce44SJohn Forte /* 482*fcf3ce44SJohn Forte * emlxs_mb_read_lnk_stat Issue a LINK STATUS 483*fcf3ce44SJohn Forte * mailbox command 484*fcf3ce44SJohn Forte */ 485*fcf3ce44SJohn Forte /* ARGSUSED */ 486*fcf3ce44SJohn Forte extern void 487*fcf3ce44SJohn Forte emlxs_mb_read_lnk_stat(emlxs_hba_t *hba, MAILBOX *mb) 488*fcf3ce44SJohn Forte { 489*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 490*fcf3ce44SJohn Forte 491*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_LNK_STAT; 492*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 493*fcf3ce44SJohn Forte 494*fcf3ce44SJohn Forte } /* End emlxs_mb_read_lnk_stat */ 495*fcf3ce44SJohn Forte 496*fcf3ce44SJohn Forte 497*fcf3ce44SJohn Forte /* 498*fcf3ce44SJohn Forte * emlxs_mb_write_nv Issue a WRITE NVPARAM 499*fcf3ce44SJohn Forte * mailbox command 500*fcf3ce44SJohn Forte */ 501*fcf3ce44SJohn Forte static void 502*fcf3ce44SJohn Forte emlxs_emb_mb_write_nv(emlxs_hba_t *hba, MAILBOX *mb) 503*fcf3ce44SJohn Forte { 504*fcf3ce44SJohn Forte int32_t i; 505*fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 506*fcf3ce44SJohn Forte 507*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 508*fcf3ce44SJohn Forte 509*fcf3ce44SJohn Forte bcopy((void *) &hba->wwnn, 510*fcf3ce44SJohn Forte (void *) mb->un.varWTnvp.nodename, 511*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 512*fcf3ce44SJohn Forte 513*fcf3ce44SJohn Forte bcopy((void *) &hba->wwpn, 514*fcf3ce44SJohn Forte (void *) mb->un.varWTnvp.portname, 515*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 516*fcf3ce44SJohn Forte 517*fcf3ce44SJohn Forte mb->un.varWTnvp.pref_DID = 0; 518*fcf3ce44SJohn Forte mb->un.varWTnvp.hardAL_PA = (uint8_t)cfg[CFG_ASSIGN_ALPA].current; 519*fcf3ce44SJohn Forte mb->un.varWTnvp.rsvd1[0] = 0xffffffff; 520*fcf3ce44SJohn Forte mb->un.varWTnvp.rsvd1[1] = 0xffffffff; 521*fcf3ce44SJohn Forte mb->un.varWTnvp.rsvd1[2] = 0xffffffff; 522*fcf3ce44SJohn Forte for (i = 0; i < 21; i++) { 523*fcf3ce44SJohn Forte mb->un.varWTnvp.rsvd3[i] = 0xffffffff; 524*fcf3ce44SJohn Forte } 525*fcf3ce44SJohn Forte 526*fcf3ce44SJohn Forte mb->mbxCommand = MBX_WRITE_NV; 527*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 528*fcf3ce44SJohn Forte } /* End emlxs_mb_write_nv */ 529*fcf3ce44SJohn Forte 530*fcf3ce44SJohn Forte 531*fcf3ce44SJohn Forte /* 532*fcf3ce44SJohn Forte * emlxs_mb_part_slim Issue a PARTITION SLIM 533*fcf3ce44SJohn Forte * mailbox command 534*fcf3ce44SJohn Forte */ 535*fcf3ce44SJohn Forte static void 536*fcf3ce44SJohn Forte emlxs_mb_part_slim(emlxs_hba_t *hba, MAILBOX *mb, uint32_t hbainit) 537*fcf3ce44SJohn Forte { 538*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 539*fcf3ce44SJohn Forte 540*fcf3ce44SJohn Forte 541*fcf3ce44SJohn Forte mb->un.varSlim.numRing = hba->ring_count; 542*fcf3ce44SJohn Forte mb->un.varSlim.hbainit = hbainit; 543*fcf3ce44SJohn Forte mb->mbxCommand = MBX_PART_SLIM; 544*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 545*fcf3ce44SJohn Forte 546*fcf3ce44SJohn Forte } /* End emlxs_mb_part_slim */ 547*fcf3ce44SJohn Forte 548*fcf3ce44SJohn Forte 549*fcf3ce44SJohn Forte /* 550*fcf3ce44SJohn Forte * emlxs_mb_config_ring Issue a CONFIG RING 551*fcf3ce44SJohn Forte * mailbox command 552*fcf3ce44SJohn Forte */ 553*fcf3ce44SJohn Forte extern void 554*fcf3ce44SJohn Forte emlxs_mb_config_ring(emlxs_hba_t *hba, int32_t ring, MAILBOX *mb) 555*fcf3ce44SJohn Forte { 556*fcf3ce44SJohn Forte int32_t i; 557*fcf3ce44SJohn Forte int32_t j; 558*fcf3ce44SJohn Forte 559*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 560*fcf3ce44SJohn Forte 561*fcf3ce44SJohn Forte j = 0; 562*fcf3ce44SJohn Forte for (i = 0; i < ring; i++) { 563*fcf3ce44SJohn Forte j += hba->ring_masks[i]; 564*fcf3ce44SJohn Forte } 565*fcf3ce44SJohn Forte 566*fcf3ce44SJohn Forte for (i = 0; i < hba->ring_masks[ring]; i++) { 567*fcf3ce44SJohn Forte if ((j + i) >= 6) { 568*fcf3ce44SJohn Forte break; 569*fcf3ce44SJohn Forte } 570*fcf3ce44SJohn Forte mb->un.varCfgRing.rrRegs[i].rval = hba->ring_rval[j + i]; 571*fcf3ce44SJohn Forte mb->un.varCfgRing.rrRegs[i].rmask = hba->ring_rmask[j + i]; 572*fcf3ce44SJohn Forte 573*fcf3ce44SJohn Forte mb->un.varCfgRing.rrRegs[i].tval = hba->ring_tval[j + i]; 574*fcf3ce44SJohn Forte mb->un.varCfgRing.rrRegs[i].tmask = hba->ring_tmask[j + i]; 575*fcf3ce44SJohn Forte } 576*fcf3ce44SJohn Forte 577*fcf3ce44SJohn Forte mb->un.varCfgRing.ring = ring; 578*fcf3ce44SJohn Forte mb->un.varCfgRing.profile = 0; 579*fcf3ce44SJohn Forte mb->un.varCfgRing.maxOrigXchg = 0; 580*fcf3ce44SJohn Forte mb->un.varCfgRing.maxRespXchg = 0; 581*fcf3ce44SJohn Forte mb->un.varCfgRing.recvNotify = 1; 582*fcf3ce44SJohn Forte mb->un.varCfgRing.numMask = hba->ring_masks[ring]; 583*fcf3ce44SJohn Forte mb->mbxCommand = MBX_CONFIG_RING; 584*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 585*fcf3ce44SJohn Forte 586*fcf3ce44SJohn Forte return; 587*fcf3ce44SJohn Forte 588*fcf3ce44SJohn Forte } /* End emlxs_mb_config_ring */ 589*fcf3ce44SJohn Forte 590*fcf3ce44SJohn Forte 591*fcf3ce44SJohn Forte /* 592*fcf3ce44SJohn Forte * emlxs_mb_config_link Issue a CONFIG LINK 593*fcf3ce44SJohn Forte * mailbox command 594*fcf3ce44SJohn Forte */ 595*fcf3ce44SJohn Forte extern void 596*fcf3ce44SJohn Forte emlxs_mb_config_link(emlxs_hba_t *hba, MAILBOX *mb) 597*fcf3ce44SJohn Forte { 598*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 599*fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 600*fcf3ce44SJohn Forte 601*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 602*fcf3ce44SJohn Forte 603*fcf3ce44SJohn Forte /* 604*fcf3ce44SJohn Forte * NEW_FEATURE SLI-2, Coalescing Response Feature. 605*fcf3ce44SJohn Forte */ 606*fcf3ce44SJohn Forte if (cfg[CFG_CR_DELAY].current) { 607*fcf3ce44SJohn Forte mb->un.varCfgLnk.cr = 1; 608*fcf3ce44SJohn Forte mb->un.varCfgLnk.ci = 1; 609*fcf3ce44SJohn Forte mb->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current; 610*fcf3ce44SJohn Forte mb->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current; 611*fcf3ce44SJohn Forte } 612*fcf3ce44SJohn Forte if (cfg[CFG_ACK0].current) 613*fcf3ce44SJohn Forte mb->un.varCfgLnk.ack0_enable = 1; 614*fcf3ce44SJohn Forte 615*fcf3ce44SJohn Forte mb->un.varCfgLnk.myId = port->did; 616*fcf3ce44SJohn Forte mb->un.varCfgLnk.edtov = hba->fc_edtov; 617*fcf3ce44SJohn Forte mb->un.varCfgLnk.arbtov = hba->fc_arbtov; 618*fcf3ce44SJohn Forte mb->un.varCfgLnk.ratov = hba->fc_ratov; 619*fcf3ce44SJohn Forte mb->un.varCfgLnk.rttov = hba->fc_rttov; 620*fcf3ce44SJohn Forte mb->un.varCfgLnk.altov = hba->fc_altov; 621*fcf3ce44SJohn Forte mb->un.varCfgLnk.crtov = hba->fc_crtov; 622*fcf3ce44SJohn Forte mb->un.varCfgLnk.citov = hba->fc_citov; 623*fcf3ce44SJohn Forte mb->mbxCommand = MBX_CONFIG_LINK; 624*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 625*fcf3ce44SJohn Forte 626*fcf3ce44SJohn Forte return; 627*fcf3ce44SJohn Forte 628*fcf3ce44SJohn Forte } /* emlxs_mb_config_link() */ 629*fcf3ce44SJohn Forte 630*fcf3ce44SJohn Forte 631*fcf3ce44SJohn Forte /* 632*fcf3ce44SJohn Forte * emlxs_mb_init_link Issue an INIT LINK 633*fcf3ce44SJohn Forte * mailbox command 634*fcf3ce44SJohn Forte */ 635*fcf3ce44SJohn Forte extern void 636*fcf3ce44SJohn Forte emlxs_mb_init_link(emlxs_hba_t *hba, MAILBOX *mb, uint32_t topology, 637*fcf3ce44SJohn Forte uint32_t linkspeed) 638*fcf3ce44SJohn Forte { 639*fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD; 640*fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 641*fcf3ce44SJohn Forte 642*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 643*fcf3ce44SJohn Forte 644*fcf3ce44SJohn Forte switch (topology) { 645*fcf3ce44SJohn Forte case FLAGS_LOCAL_LB: 646*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; 647*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags |= FLAGS_LOCAL_LB; 648*fcf3ce44SJohn Forte break; 649*fcf3ce44SJohn Forte case FLAGS_TOPOLOGY_MODE_LOOP_PT: 650*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; 651*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; 652*fcf3ce44SJohn Forte break; 653*fcf3ce44SJohn Forte case FLAGS_TOPOLOGY_MODE_PT_PT: 654*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; 655*fcf3ce44SJohn Forte break; 656*fcf3ce44SJohn Forte case FLAGS_TOPOLOGY_MODE_LOOP: 657*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; 658*fcf3ce44SJohn Forte break; 659*fcf3ce44SJohn Forte case FLAGS_TOPOLOGY_MODE_PT_LOOP: 660*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; 661*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; 662*fcf3ce44SJohn Forte break; 663*fcf3ce44SJohn Forte } 664*fcf3ce44SJohn Forte 665*fcf3ce44SJohn Forte if (cfg[CFG_LILP_ENABLE].current == 0) { 666*fcf3ce44SJohn Forte /* Disable LIRP/LILP support */ 667*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags |= FLAGS_LIRP_LILP; 668*fcf3ce44SJohn Forte } 669*fcf3ce44SJohn Forte /* 670*fcf3ce44SJohn Forte * Setting up the link speed 671*fcf3ce44SJohn Forte */ 672*fcf3ce44SJohn Forte switch (linkspeed) { 673*fcf3ce44SJohn Forte case 0: 674*fcf3ce44SJohn Forte break; 675*fcf3ce44SJohn Forte 676*fcf3ce44SJohn Forte case 1: 677*fcf3ce44SJohn Forte if (!(vpd->link_speed & LMT_1GB_CAPABLE)) { 678*fcf3ce44SJohn Forte linkspeed = 0; 679*fcf3ce44SJohn Forte } 680*fcf3ce44SJohn Forte break; 681*fcf3ce44SJohn Forte 682*fcf3ce44SJohn Forte case 2: 683*fcf3ce44SJohn Forte if (!(vpd->link_speed & LMT_2GB_CAPABLE)) { 684*fcf3ce44SJohn Forte linkspeed = 0; 685*fcf3ce44SJohn Forte } 686*fcf3ce44SJohn Forte break; 687*fcf3ce44SJohn Forte 688*fcf3ce44SJohn Forte case 4: 689*fcf3ce44SJohn Forte if (!(vpd->link_speed & LMT_4GB_CAPABLE)) { 690*fcf3ce44SJohn Forte linkspeed = 0; 691*fcf3ce44SJohn Forte } 692*fcf3ce44SJohn Forte break; 693*fcf3ce44SJohn Forte 694*fcf3ce44SJohn Forte case 8: 695*fcf3ce44SJohn Forte if (!(vpd->link_speed & LMT_8GB_CAPABLE)) { 696*fcf3ce44SJohn Forte linkspeed = 0; 697*fcf3ce44SJohn Forte } 698*fcf3ce44SJohn Forte break; 699*fcf3ce44SJohn Forte 700*fcf3ce44SJohn Forte case 10: 701*fcf3ce44SJohn Forte if (!(vpd->link_speed & LMT_10GB_CAPABLE)) { 702*fcf3ce44SJohn Forte linkspeed = 0; 703*fcf3ce44SJohn Forte } 704*fcf3ce44SJohn Forte break; 705*fcf3ce44SJohn Forte 706*fcf3ce44SJohn Forte default: 707*fcf3ce44SJohn Forte linkspeed = 0; 708*fcf3ce44SJohn Forte break; 709*fcf3ce44SJohn Forte 710*fcf3ce44SJohn Forte } 711*fcf3ce44SJohn Forte 712*fcf3ce44SJohn Forte if ((linkspeed > 0) && (vpd->feaLevelHigh >= 0x02)) { 713*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; 714*fcf3ce44SJohn Forte mb->un.varInitLnk.link_speed = linkspeed; 715*fcf3ce44SJohn Forte } 716*fcf3ce44SJohn Forte mb->un.varInitLnk.link_flags |= FLAGS_PREABORT_RETURN; 717*fcf3ce44SJohn Forte 718*fcf3ce44SJohn Forte mb->un.varInitLnk.fabric_AL_PA = (uint8_t)cfg[CFG_ASSIGN_ALPA].current; 719*fcf3ce44SJohn Forte mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK; 720*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 721*fcf3ce44SJohn Forte 722*fcf3ce44SJohn Forte 723*fcf3ce44SJohn Forte return; 724*fcf3ce44SJohn Forte 725*fcf3ce44SJohn Forte } /* emlxs_mb_init_link() */ 726*fcf3ce44SJohn Forte 727*fcf3ce44SJohn Forte 728*fcf3ce44SJohn Forte /* 729*fcf3ce44SJohn Forte * emlxs_mb_down_link Issue a DOWN LINK 730*fcf3ce44SJohn Forte * mailbox command 731*fcf3ce44SJohn Forte */ 732*fcf3ce44SJohn Forte /* ARGSUSED */ 733*fcf3ce44SJohn Forte extern void 734*fcf3ce44SJohn Forte emlxs_mb_down_link(emlxs_hba_t *hba, MAILBOX *mb) 735*fcf3ce44SJohn Forte { 736*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 737*fcf3ce44SJohn Forte 738*fcf3ce44SJohn Forte mb->mbxCommand = MBX_DOWN_LINK; 739*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 740*fcf3ce44SJohn Forte 741*fcf3ce44SJohn Forte return; 742*fcf3ce44SJohn Forte 743*fcf3ce44SJohn Forte } /* emlxs_mb_down_link() */ 744*fcf3ce44SJohn Forte 745*fcf3ce44SJohn Forte 746*fcf3ce44SJohn Forte /* 747*fcf3ce44SJohn Forte * emlxs_mb_read_sparam Issue a READ SPARAM 748*fcf3ce44SJohn Forte * mailbox command 749*fcf3ce44SJohn Forte */ 750*fcf3ce44SJohn Forte extern uint32_t 751*fcf3ce44SJohn Forte emlxs_mb_read_sparam(emlxs_hba_t *hba, MAILBOX *mb) 752*fcf3ce44SJohn Forte { 753*fcf3ce44SJohn Forte MATCHMAP *mp; 754*fcf3ce44SJohn Forte 755*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 756*fcf3ce44SJohn Forte 757*fcf3ce44SJohn Forte if ((mp = (MATCHMAP *) emlxs_mem_get(hba, MEM_BUF)) == 0) { 758*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_SPARM64; 759*fcf3ce44SJohn Forte 760*fcf3ce44SJohn Forte return (1); 761*fcf3ce44SJohn Forte } 762*fcf3ce44SJohn Forte mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM); 763*fcf3ce44SJohn Forte mb->un.varRdSparm.un.sp64.addrHigh = (uint32_t)putPaddrHigh(mp->phys); 764*fcf3ce44SJohn Forte mb->un.varRdSparm.un.sp64.addrLow = (uint32_t)putPaddrLow(mp->phys); 765*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_SPARM64; 766*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 767*fcf3ce44SJohn Forte 768*fcf3ce44SJohn Forte /* 769*fcf3ce44SJohn Forte * save address for completion 770*fcf3ce44SJohn Forte */ 771*fcf3ce44SJohn Forte ((MAILBOXQ *)mb)->bp = (uint8_t *)mp; 772*fcf3ce44SJohn Forte 773*fcf3ce44SJohn Forte return (0); 774*fcf3ce44SJohn Forte 775*fcf3ce44SJohn Forte } /* emlxs_mb_read_sparam() */ 776*fcf3ce44SJohn Forte 777*fcf3ce44SJohn Forte 778*fcf3ce44SJohn Forte /* 779*fcf3ce44SJohn Forte * emlxs_mb_read_rpi Issue a READ RPI 780*fcf3ce44SJohn Forte * mailbox command 781*fcf3ce44SJohn Forte */ 782*fcf3ce44SJohn Forte /* ARGSUSED */ 783*fcf3ce44SJohn Forte extern uint32_t 784*fcf3ce44SJohn Forte emlxs_mb_read_rpi(emlxs_hba_t *hba, uint32_t rpi, MAILBOX *mb, uint32_t flag) 785*fcf3ce44SJohn Forte { 786*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 787*fcf3ce44SJohn Forte 788*fcf3ce44SJohn Forte /* 789*fcf3ce44SJohn Forte * Set flag to issue action on cmpl 790*fcf3ce44SJohn Forte */ 791*fcf3ce44SJohn Forte mb->un.varWords[30] = flag; 792*fcf3ce44SJohn Forte mb->un.varRdRPI.reqRpi = (volatile uint16_t) rpi; 793*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_RPI64; 794*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 795*fcf3ce44SJohn Forte 796*fcf3ce44SJohn Forte return (0); 797*fcf3ce44SJohn Forte 798*fcf3ce44SJohn Forte } /* End emlxs_mb_read_rpi */ 799*fcf3ce44SJohn Forte 800*fcf3ce44SJohn Forte 801*fcf3ce44SJohn Forte /* 802*fcf3ce44SJohn Forte * emlxs_mb_read_xri Issue a READ XRI 803*fcf3ce44SJohn Forte * mailbox command 804*fcf3ce44SJohn Forte */ 805*fcf3ce44SJohn Forte /* ARGSUSED */ 806*fcf3ce44SJohn Forte extern uint32_t 807*fcf3ce44SJohn Forte emlxs_mb_read_xri(emlxs_hba_t *hba, uint32_t xri, MAILBOX *mb, uint32_t flag) 808*fcf3ce44SJohn Forte { 809*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 810*fcf3ce44SJohn Forte 811*fcf3ce44SJohn Forte /* 812*fcf3ce44SJohn Forte * Set flag to issue action on cmpl 813*fcf3ce44SJohn Forte */ 814*fcf3ce44SJohn Forte mb->un.varWords[30] = flag; 815*fcf3ce44SJohn Forte mb->un.varRdXRI.reqXri = (volatile uint16_t) xri; 816*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_XRI; 817*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 818*fcf3ce44SJohn Forte 819*fcf3ce44SJohn Forte return (0); 820*fcf3ce44SJohn Forte 821*fcf3ce44SJohn Forte } /* End emlxs_mb_read_xri */ 822*fcf3ce44SJohn Forte 823*fcf3ce44SJohn Forte 824*fcf3ce44SJohn Forte /* ARGSUSED */ 825*fcf3ce44SJohn Forte extern int32_t 826*fcf3ce44SJohn Forte emlxs_mb_check_sparm(emlxs_hba_t *hba, SERV_PARM *nsp) 827*fcf3ce44SJohn Forte { 828*fcf3ce44SJohn Forte uint32_t nsp_value; 829*fcf3ce44SJohn Forte uint32_t *iptr; 830*fcf3ce44SJohn Forte 831*fcf3ce44SJohn Forte if (nsp->cmn.fPort) { 832*fcf3ce44SJohn Forte return (0); 833*fcf3ce44SJohn Forte } 834*fcf3ce44SJohn Forte /* Validate the service parameters */ 835*fcf3ce44SJohn Forte iptr = (uint32_t *)& nsp->portName; 836*fcf3ce44SJohn Forte if (iptr[0] == 0 && iptr[1] == 0) { 837*fcf3ce44SJohn Forte return (1); 838*fcf3ce44SJohn Forte } 839*fcf3ce44SJohn Forte iptr = (uint32_t *)& nsp->nodeName; 840*fcf3ce44SJohn Forte if (iptr[0] == 0 && iptr[1] == 0) { 841*fcf3ce44SJohn Forte return (2); 842*fcf3ce44SJohn Forte } 843*fcf3ce44SJohn Forte if (nsp->cls2.classValid) { 844*fcf3ce44SJohn Forte nsp_value = ((nsp->cls2.rcvDataSizeMsb & 0x0f) << 8) | 845*fcf3ce44SJohn Forte nsp->cls2.rcvDataSizeLsb; 846*fcf3ce44SJohn Forte 847*fcf3ce44SJohn Forte /* 848*fcf3ce44SJohn Forte * If the receive data length is zero then set it to the CSP 849*fcf3ce44SJohn Forte * value 850*fcf3ce44SJohn Forte */ 851*fcf3ce44SJohn Forte if (!nsp_value) { 852*fcf3ce44SJohn Forte nsp->cls2.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb; 853*fcf3ce44SJohn Forte nsp->cls2.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb; 854*fcf3ce44SJohn Forte return (0); 855*fcf3ce44SJohn Forte } 856*fcf3ce44SJohn Forte } 857*fcf3ce44SJohn Forte if (nsp->cls3.classValid) { 858*fcf3ce44SJohn Forte nsp_value = ((nsp->cls3.rcvDataSizeMsb & 0x0f) << 8) | 859*fcf3ce44SJohn Forte nsp->cls3.rcvDataSizeLsb; 860*fcf3ce44SJohn Forte 861*fcf3ce44SJohn Forte /* 862*fcf3ce44SJohn Forte * If the receive data length is zero then set it to the CSP 863*fcf3ce44SJohn Forte * value 864*fcf3ce44SJohn Forte */ 865*fcf3ce44SJohn Forte /* This prevents a Emulex adapter bug from occurring */ 866*fcf3ce44SJohn Forte if (!nsp_value) { 867*fcf3ce44SJohn Forte nsp->cls3.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb; 868*fcf3ce44SJohn Forte nsp->cls3.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb; 869*fcf3ce44SJohn Forte return (0); 870*fcf3ce44SJohn Forte } 871*fcf3ce44SJohn Forte } 872*fcf3ce44SJohn Forte return (0); 873*fcf3ce44SJohn Forte 874*fcf3ce44SJohn Forte } /* emlxs_mb_check_sparm() */ 875*fcf3ce44SJohn Forte 876*fcf3ce44SJohn Forte 877*fcf3ce44SJohn Forte /* 878*fcf3ce44SJohn Forte * emlxs_mb_reg_did Issue a REG_LOGIN 879*fcf3ce44SJohn Forte * mailbox command 880*fcf3ce44SJohn Forte */ 881*fcf3ce44SJohn Forte extern uint32_t 882*fcf3ce44SJohn Forte emlxs_mb_reg_did(emlxs_port_t *port, uint32_t did, SERV_PARM *param, 883*fcf3ce44SJohn Forte emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq) 884*fcf3ce44SJohn Forte { 885*fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 886*fcf3ce44SJohn Forte MATCHMAP *mp; 887*fcf3ce44SJohn Forte MAILBOXQ *mbq; 888*fcf3ce44SJohn Forte MAILBOX *mb; 889*fcf3ce44SJohn Forte uint32_t rval; 890*fcf3ce44SJohn Forte 891*fcf3ce44SJohn Forte /* Check for invalid node ids to register */ 892*fcf3ce44SJohn Forte if (did == 0 || (did & 0xff000000)) { 893*fcf3ce44SJohn Forte return (1); 894*fcf3ce44SJohn Forte } 895*fcf3ce44SJohn Forte if ((rval = emlxs_mb_check_sparm(hba, param))) { 896*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg, 897*fcf3ce44SJohn Forte "Invalid service parameters. did=%06x rval=%d", did, rval); 898*fcf3ce44SJohn Forte 899*fcf3ce44SJohn Forte return (1); 900*fcf3ce44SJohn Forte } 901*fcf3ce44SJohn Forte /* Check if the node limit has been reached */ 902*fcf3ce44SJohn Forte if (port->node_count >= hba->max_nodes) { 903*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg, 904*fcf3ce44SJohn Forte "Limit reached. did=%06x count=%d", did, port->node_count); 905*fcf3ce44SJohn Forte 906*fcf3ce44SJohn Forte return (1); 907*fcf3ce44SJohn Forte } 908*fcf3ce44SJohn Forte if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) { 909*fcf3ce44SJohn Forte return (1); 910*fcf3ce44SJohn Forte } 911*fcf3ce44SJohn Forte /* Build login request */ 912*fcf3ce44SJohn Forte if ((mp = (MATCHMAP *) emlxs_mem_get(hba, MEM_BUF | MEM_PRI)) == 0) { 913*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 914*fcf3ce44SJohn Forte return (1); 915*fcf3ce44SJohn Forte } 916*fcf3ce44SJohn Forte bcopy((void *) param, (void *) mp->virt, sizeof (SERV_PARM)); 917*fcf3ce44SJohn Forte 918*fcf3ce44SJohn Forte mb = (MAILBOX *) mbq->mbox; 919*fcf3ce44SJohn Forte mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM); 920*fcf3ce44SJohn Forte mb->un.varRegLogin.un.sp64.addrHigh = (uint32_t)putPaddrHigh(mp->phys); 921*fcf3ce44SJohn Forte mb->un.varRegLogin.un.sp64.addrLow = (uint32_t)putPaddrLow(mp->phys); 922*fcf3ce44SJohn Forte mb->un.varRegLogin.rpi = 0; 923*fcf3ce44SJohn Forte mb->un.varRegLogin.did = did; 924*fcf3ce44SJohn Forte mb->un.varWords[30] = 0; /* flags */ 925*fcf3ce44SJohn Forte mb->mbxCommand = MBX_REG_LOGIN64; 926*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 927*fcf3ce44SJohn Forte 928*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 929*fcf3ce44SJohn Forte mb->un.varRegLogin.vpi = 930*fcf3ce44SJohn Forte port->vpi; 931*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 932*fcf3ce44SJohn Forte 933*fcf3ce44SJohn Forte mbq->sbp = (uint8_t *)sbp; 934*fcf3ce44SJohn Forte mbq->ubp = (uint8_t *)ubp; 935*fcf3ce44SJohn Forte mbq->iocbq = (uint8_t *)iocbq; 936*fcf3ce44SJohn Forte mbq->bp = (uint8_t *)mp; 937*fcf3ce44SJohn Forte 938*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) { 939*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 940*fcf3ce44SJohn Forte } 941*fcf3ce44SJohn Forte return (0); 942*fcf3ce44SJohn Forte 943*fcf3ce44SJohn Forte } /* emlxs_mb_reg_did() */ 944*fcf3ce44SJohn Forte 945*fcf3ce44SJohn Forte /* 946*fcf3ce44SJohn Forte * emlxs_mb_unreg_rpi Issue a UNREG_LOGIN 947*fcf3ce44SJohn Forte * mailbox command 948*fcf3ce44SJohn Forte */ 949*fcf3ce44SJohn Forte extern uint32_t 950*fcf3ce44SJohn Forte emlxs_mb_unreg_rpi(emlxs_port_t *port, uint32_t rpi, emlxs_buf_t *sbp, 951*fcf3ce44SJohn Forte fc_unsol_buf_t *ubp, IOCBQ *iocbq) 952*fcf3ce44SJohn Forte { 953*fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 954*fcf3ce44SJohn Forte MAILBOXQ *mbq; 955*fcf3ce44SJohn Forte MAILBOX *mb; 956*fcf3ce44SJohn Forte NODELIST *ndlp; 957*fcf3ce44SJohn Forte 958*fcf3ce44SJohn Forte if (rpi != 0xffff) { 959*fcf3ce44SJohn Forte /* Make sure the node does already exist */ 960*fcf3ce44SJohn Forte ndlp = emlxs_node_find_rpi(port, rpi); 961*fcf3ce44SJohn Forte 962*fcf3ce44SJohn Forte 963*fcf3ce44SJohn Forte if (ndlp) { 964*fcf3ce44SJohn Forte /* 965*fcf3ce44SJohn Forte * If we just unregistered the host node then clear 966*fcf3ce44SJohn Forte * the host DID 967*fcf3ce44SJohn Forte */ 968*fcf3ce44SJohn Forte if (ndlp->nlp_DID == port->did) { 969*fcf3ce44SJohn Forte port->did = 0; 970*fcf3ce44SJohn Forte } 971*fcf3ce44SJohn Forte /* remove it */ 972*fcf3ce44SJohn Forte emlxs_node_rm(port, ndlp); 973*fcf3ce44SJohn Forte 974*fcf3ce44SJohn Forte } else { 975*fcf3ce44SJohn Forte return (1); 976*fcf3ce44SJohn Forte } 977*fcf3ce44SJohn Forte } else { /* Unreg all */ 978*fcf3ce44SJohn Forte emlxs_node_destroy_all(port); 979*fcf3ce44SJohn Forte } 980*fcf3ce44SJohn Forte 981*fcf3ce44SJohn Forte if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) { 982*fcf3ce44SJohn Forte return (1); 983*fcf3ce44SJohn Forte } 984*fcf3ce44SJohn Forte mb = (MAILBOX *) mbq->mbox; 985*fcf3ce44SJohn Forte mb->un.varUnregLogin.rpi = (uint16_t)rpi; 986*fcf3ce44SJohn Forte 987*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 988*fcf3ce44SJohn Forte mb->un.varUnregLogin.vpi = port->vpi; 989*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 990*fcf3ce44SJohn Forte 991*fcf3ce44SJohn Forte mb->mbxCommand = MBX_UNREG_LOGIN; 992*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 993*fcf3ce44SJohn Forte mbq->sbp = (uint8_t *)sbp; 994*fcf3ce44SJohn Forte mbq->ubp = (uint8_t *)ubp; 995*fcf3ce44SJohn Forte mbq->iocbq = (uint8_t *)iocbq; 996*fcf3ce44SJohn Forte 997*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) { 998*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 999*fcf3ce44SJohn Forte } 1000*fcf3ce44SJohn Forte return (0); 1001*fcf3ce44SJohn Forte } /* emlxs_mb_unreg_rpi() */ 1002*fcf3ce44SJohn Forte 1003*fcf3ce44SJohn Forte /* 1004*fcf3ce44SJohn Forte * emlxs_mb_unreg_did Issue a UNREG_DID 1005*fcf3ce44SJohn Forte * mailbox command 1006*fcf3ce44SJohn Forte */ 1007*fcf3ce44SJohn Forte extern uint32_t 1008*fcf3ce44SJohn Forte emlxs_mb_unreg_did(emlxs_port_t *port, uint32_t did, emlxs_buf_t *sbp, 1009*fcf3ce44SJohn Forte fc_unsol_buf_t *ubp, IOCBQ *iocbq) 1010*fcf3ce44SJohn Forte { 1011*fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1012*fcf3ce44SJohn Forte NODELIST *ndlp; 1013*fcf3ce44SJohn Forte MAILBOXQ *mbq; 1014*fcf3ce44SJohn Forte MAILBOX *mb; 1015*fcf3ce44SJohn Forte 1016*fcf3ce44SJohn Forte /* 1017*fcf3ce44SJohn Forte * Unregister all default RPIs if did == 0xffffffff 1018*fcf3ce44SJohn Forte */ 1019*fcf3ce44SJohn Forte if (did != 0xffffffff) { 1020*fcf3ce44SJohn Forte /* Check for base node */ 1021*fcf3ce44SJohn Forte if (did == Bcast_DID) { 1022*fcf3ce44SJohn Forte /* just flush base node */ 1023*fcf3ce44SJohn Forte (void) emlxs_tx_node_flush(port, &port->node_base, 1024*fcf3ce44SJohn Forte 0, 0, 0); 1025*fcf3ce44SJohn Forte (void) emlxs_chipq_node_flush(port, 0, &port->node_base, 1026*fcf3ce44SJohn Forte 0); 1027*fcf3ce44SJohn Forte 1028*fcf3ce44SJohn Forte /* Return now */ 1029*fcf3ce44SJohn Forte return (1); 1030*fcf3ce44SJohn Forte } 1031*fcf3ce44SJohn Forte /* 1032*fcf3ce44SJohn Forte * A zero DID means that we are trying to unreg the host node 1033*fcf3ce44SJohn Forte * after a link bounce 1034*fcf3ce44SJohn Forte */ 1035*fcf3ce44SJohn Forte 1036*fcf3ce44SJohn Forte /* 1037*fcf3ce44SJohn Forte * If the prev_did == 0 then the adapter has been reset and 1038*fcf3ce44SJohn Forte * there is no need in unregistering 1039*fcf3ce44SJohn Forte */ 1040*fcf3ce44SJohn Forte 1041*fcf3ce44SJohn Forte /* 1042*fcf3ce44SJohn Forte * If the prev_did != 0 then we can look for the hosts last 1043*fcf3ce44SJohn Forte * known DID node 1044*fcf3ce44SJohn Forte */ 1045*fcf3ce44SJohn Forte 1046*fcf3ce44SJohn Forte if (did == 0) { 1047*fcf3ce44SJohn Forte if (port->prev_did == 0) { 1048*fcf3ce44SJohn Forte return (1); 1049*fcf3ce44SJohn Forte } 1050*fcf3ce44SJohn Forte did = port->prev_did; 1051*fcf3ce44SJohn Forte } 1052*fcf3ce44SJohn Forte /* Make sure the node does already exist */ 1053*fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 1054*fcf3ce44SJohn Forte 1055*fcf3ce44SJohn Forte 1056*fcf3ce44SJohn Forte if (ndlp) { 1057*fcf3ce44SJohn Forte /* remove it */ 1058*fcf3ce44SJohn Forte emlxs_node_rm(port, ndlp); 1059*fcf3ce44SJohn Forte 1060*fcf3ce44SJohn Forte /* 1061*fcf3ce44SJohn Forte * If we just unregistered the host node then clear 1062*fcf3ce44SJohn Forte * the host DID 1063*fcf3ce44SJohn Forte */ 1064*fcf3ce44SJohn Forte if (did == port->did) { 1065*fcf3ce44SJohn Forte port->did = 0; 1066*fcf3ce44SJohn Forte } 1067*fcf3ce44SJohn Forte } else { 1068*fcf3ce44SJohn Forte return (1); 1069*fcf3ce44SJohn Forte } 1070*fcf3ce44SJohn Forte } 1071*fcf3ce44SJohn Forte if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) { 1072*fcf3ce44SJohn Forte return (1); 1073*fcf3ce44SJohn Forte } 1074*fcf3ce44SJohn Forte mb = (MAILBOX *) mbq->mbox; 1075*fcf3ce44SJohn Forte mb->un.varUnregDID.did = did; 1076*fcf3ce44SJohn Forte 1077*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 1078*fcf3ce44SJohn Forte mb->un.varUnregDID.vpi = port->vpi; 1079*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 1080*fcf3ce44SJohn Forte 1081*fcf3ce44SJohn Forte mb->mbxCommand = MBX_UNREG_D_ID; 1082*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1083*fcf3ce44SJohn Forte mbq->sbp = (uint8_t *)sbp; 1084*fcf3ce44SJohn Forte mbq->ubp = (uint8_t *)ubp; 1085*fcf3ce44SJohn Forte mbq->iocbq = (uint8_t *)iocbq; 1086*fcf3ce44SJohn Forte 1087*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) { 1088*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 1089*fcf3ce44SJohn Forte } 1090*fcf3ce44SJohn Forte return (0); 1091*fcf3ce44SJohn Forte 1092*fcf3ce44SJohn Forte } /* End emlxs_mb_unreg_did */ 1093*fcf3ce44SJohn Forte 1094*fcf3ce44SJohn Forte 1095*fcf3ce44SJohn Forte /* 1096*fcf3ce44SJohn Forte * emlxs_mb_set_mask Issue a SET MASK 1097*fcf3ce44SJohn Forte * mailbox command 1098*fcf3ce44SJohn Forte */ 1099*fcf3ce44SJohn Forte /* ARGSUSED */ 1100*fcf3ce44SJohn Forte static void 1101*fcf3ce44SJohn Forte emlxs_mb_set_mask(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mask, 1102*fcf3ce44SJohn Forte uint32_t ringno) 1103*fcf3ce44SJohn Forte { 1104*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1105*fcf3ce44SJohn Forte 1106*fcf3ce44SJohn Forte mb->un.varWords[0] = 0x11223344; /* set passwd */ 1107*fcf3ce44SJohn Forte mb->un.varWords[1] = mask; /* set mask */ 1108*fcf3ce44SJohn Forte mb->un.varWords[2] = ringno; /* set ringno */ 1109*fcf3ce44SJohn Forte mb->mbxCommand = MBX_SET_MASK; 1110*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1111*fcf3ce44SJohn Forte 1112*fcf3ce44SJohn Forte } /* End emlxs_mb_set_mask */ 1113*fcf3ce44SJohn Forte 1114*fcf3ce44SJohn Forte 1115*fcf3ce44SJohn Forte /* 1116*fcf3ce44SJohn Forte * emlxs_mb_set_debug Issue a special debug 1117*fcf3ce44SJohn Forte * mailbox command 1118*fcf3ce44SJohn Forte */ 1119*fcf3ce44SJohn Forte /* ARGSUSED */ 1120*fcf3ce44SJohn Forte static void 1121*fcf3ce44SJohn Forte emlxs_mb_set_debug(emlxs_hba_t *hba, MAILBOX *mb, uint32_t word0, 1122*fcf3ce44SJohn Forte uint32_t word1, uint32_t word2) 1123*fcf3ce44SJohn Forte { 1124*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1125*fcf3ce44SJohn Forte 1126*fcf3ce44SJohn Forte mb->un.varWords[0] = word0; 1127*fcf3ce44SJohn Forte mb->un.varWords[1] = word1; 1128*fcf3ce44SJohn Forte mb->un.varWords[2] = word2; 1129*fcf3ce44SJohn Forte mb->mbxCommand = MBX_SET_DEBUG; 1130*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1131*fcf3ce44SJohn Forte 1132*fcf3ce44SJohn Forte } /* End emlxs_mb_set_debug */ 1133*fcf3ce44SJohn Forte 1134*fcf3ce44SJohn Forte 1135*fcf3ce44SJohn Forte /* 1136*fcf3ce44SJohn Forte * emlxs_mb_set_var Issue a special debug mbox 1137*fcf3ce44SJohn Forte * command to write slim 1138*fcf3ce44SJohn Forte */ 1139*fcf3ce44SJohn Forte /* ARGSUSED */ 1140*fcf3ce44SJohn Forte extern void 1141*fcf3ce44SJohn Forte emlxs_mb_set_var(emlxs_hba_t *hba, MAILBOX *mb, uint32_t addr, uint32_t value) 1142*fcf3ce44SJohn Forte { 1143*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1144*fcf3ce44SJohn Forte 1145*fcf3ce44SJohn Forte /* addr = 0x090597 is AUTO ABTS disable for ELS commands */ 1146*fcf3ce44SJohn Forte /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */ 1147*fcf3ce44SJohn Forte /* addr = 0x100506 is for setting PCI MAX READ value */ 1148*fcf3ce44SJohn Forte 1149*fcf3ce44SJohn Forte /* 1150*fcf3ce44SJohn Forte * Always turn on DELAYED ABTS for ELS timeouts 1151*fcf3ce44SJohn Forte */ 1152*fcf3ce44SJohn Forte if ((addr == 0x052198) && (value == 0)) { 1153*fcf3ce44SJohn Forte value = 1; 1154*fcf3ce44SJohn Forte } 1155*fcf3ce44SJohn Forte mb->un.varWords[0] = addr; 1156*fcf3ce44SJohn Forte mb->un.varWords[1] = value; 1157*fcf3ce44SJohn Forte mb->mbxCommand = MBX_SET_VARIABLE; 1158*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1159*fcf3ce44SJohn Forte 1160*fcf3ce44SJohn Forte } /* End emlxs_mb_set_var */ 1161*fcf3ce44SJohn Forte 1162*fcf3ce44SJohn Forte 1163*fcf3ce44SJohn Forte /* 1164*fcf3ce44SJohn Forte * Disable Traffic Cop 1165*fcf3ce44SJohn Forte */ 1166*fcf3ce44SJohn Forte /* ARGSUSED */ 1167*fcf3ce44SJohn Forte extern void 1168*fcf3ce44SJohn Forte emlxs_disable_tc(emlxs_hba_t *hba, MAILBOX *mb) 1169*fcf3ce44SJohn Forte { 1170*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1171*fcf3ce44SJohn Forte 1172*fcf3ce44SJohn Forte mb->un.varWords[0] = 0x50797; 1173*fcf3ce44SJohn Forte mb->un.varWords[1] = 0; 1174*fcf3ce44SJohn Forte mb->un.varWords[2] = 0xfffffffe; 1175*fcf3ce44SJohn Forte mb->mbxCommand = MBX_SET_VARIABLE; 1176*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1177*fcf3ce44SJohn Forte 1178*fcf3ce44SJohn Forte } /* End emlxs_disable_tc */ 1179*fcf3ce44SJohn Forte 1180*fcf3ce44SJohn Forte 1181*fcf3ce44SJohn Forte /* 1182*fcf3ce44SJohn Forte * emlxs_mb_config_port Issue a CONFIG_PORT 1183*fcf3ce44SJohn Forte * mailbox command 1184*fcf3ce44SJohn Forte */ 1185*fcf3ce44SJohn Forte extern uint32_t 1186*fcf3ce44SJohn Forte emlxs_mb_config_port(emlxs_hba_t *hba, MAILBOX *mb, uint32_t sli_mode, 1187*fcf3ce44SJohn Forte uint32_t hbainit) 1188*fcf3ce44SJohn Forte { 1189*fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD; 1190*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1191*fcf3ce44SJohn Forte emlxs_config_t *cfg; 1192*fcf3ce44SJohn Forte RING *rp; 1193*fcf3ce44SJohn Forte uint64_t pcb; 1194*fcf3ce44SJohn Forte uint64_t mbx; 1195*fcf3ce44SJohn Forte uint64_t hgp; 1196*fcf3ce44SJohn Forte uint64_t pgp; 1197*fcf3ce44SJohn Forte uint64_t rgp; 1198*fcf3ce44SJohn Forte MAILBOX *mbox; 1199*fcf3ce44SJohn Forte SLIM2 *slim; 1200*fcf3ce44SJohn Forte SLI2_RDSC *rdsc; 1201*fcf3ce44SJohn Forte uint64_t offset; 1202*fcf3ce44SJohn Forte uint32_t Laddr; 1203*fcf3ce44SJohn Forte uint32_t i; 1204*fcf3ce44SJohn Forte 1205*fcf3ce44SJohn Forte cfg = &CFG; 1206*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1207*fcf3ce44SJohn Forte mbox = NULL; 1208*fcf3ce44SJohn Forte slim = NULL; 1209*fcf3ce44SJohn Forte 1210*fcf3ce44SJohn Forte mb->mbxCommand = MBX_CONFIG_PORT; 1211*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1212*fcf3ce44SJohn Forte 1213*fcf3ce44SJohn Forte mb->un.varCfgPort.pcbLen = sizeof (PCB); 1214*fcf3ce44SJohn Forte 1215*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 1216*fcf3ce44SJohn Forte mb->un.varCfgPort.hbainit[0] = hbainit; 1217*fcf3ce44SJohn Forte #else /* SLI3_SUPPORT */ 1218*fcf3ce44SJohn Forte mb->un.varCfgPort.hbainit = hbainit; 1219*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 1220*fcf3ce44SJohn Forte 1221*fcf3ce44SJohn Forte pcb = hba->slim2.phys + (uint64_t)(unsigned long)& (slim->pcb); 1222*fcf3ce44SJohn Forte mb->un.varCfgPort.pcbLow = (uint32_t)putPaddrLow(pcb); 1223*fcf3ce44SJohn Forte mb->un.varCfgPort.pcbHigh = (uint32_t)putPaddrHigh(pcb); 1224*fcf3ce44SJohn Forte 1225*fcf3ce44SJohn Forte /* Set Host pointers in SLIM flag */ 1226*fcf3ce44SJohn Forte mb->un.varCfgPort.hps = 1; 1227*fcf3ce44SJohn Forte 1228*fcf3ce44SJohn Forte /* Initialize hba structure for assumed default SLI2 mode */ 1229*fcf3ce44SJohn Forte /* If config port succeeds, then we will update it then */ 1230*fcf3ce44SJohn Forte hba->sli_mode = 2; 1231*fcf3ce44SJohn Forte hba->vpi_max = 1; 1232*fcf3ce44SJohn Forte hba->flag &= ~FC_NPIV_ENABLED; 1233*fcf3ce44SJohn Forte 1234*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 1235*fcf3ce44SJohn Forte if (sli_mode >= 3) { 1236*fcf3ce44SJohn Forte mb->un.varCfgPort.sli_mode = 3; 1237*fcf3ce44SJohn Forte mb->un.varCfgPort.cerbm = 1; 1238*fcf3ce44SJohn Forte mb->un.varCfgPort.max_hbq = EMLXS_NUM_HBQ; 1239*fcf3ce44SJohn Forte 1240*fcf3ce44SJohn Forte #ifdef NPIV_SUPPORT 1241*fcf3ce44SJohn Forte if (cfg[CFG_NPIV_ENABLE].current) { 1242*fcf3ce44SJohn Forte if (vpd->feaLevelHigh >= 0x09) { 1243*fcf3ce44SJohn Forte if (hba->model_info.chip >= EMLXS_SATURN_CHIP) { 1244*fcf3ce44SJohn Forte mb->un.varCfgPort.vpi_max = 1245*fcf3ce44SJohn Forte MAX_VPORTS - 1; 1246*fcf3ce44SJohn Forte } else { 1247*fcf3ce44SJohn Forte mb->un.varCfgPort.vpi_max = 1248*fcf3ce44SJohn Forte MAX_VPORTS_LIMITED - 1; 1249*fcf3ce44SJohn Forte } 1250*fcf3ce44SJohn Forte 1251*fcf3ce44SJohn Forte mb->un.varCfgPort.cmv = 1; 1252*fcf3ce44SJohn Forte } else { 1253*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1254*fcf3ce44SJohn Forte "CFGPORT: Firmware does not support NPIV. " 1255*fcf3ce44SJohn Forte "level=%d", vpd->feaLevelHigh); 1256*fcf3ce44SJohn Forte } 1257*fcf3ce44SJohn Forte 1258*fcf3ce44SJohn Forte } 1259*fcf3ce44SJohn Forte #endif /* NPIV_SUPPORT */ 1260*fcf3ce44SJohn Forte } 1261*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 1262*fcf3ce44SJohn Forte 1263*fcf3ce44SJohn Forte /* 1264*fcf3ce44SJohn Forte * Now setup pcb 1265*fcf3ce44SJohn Forte */ 1266*fcf3ce44SJohn Forte ((SLIM2 *) hba->slim2.virt)->pcb.type = TYPE_NATIVE_SLI2; 1267*fcf3ce44SJohn Forte ((SLIM2 *) hba->slim2.virt)->pcb.feature = FEATURE_INITIAL_SLI2; 1268*fcf3ce44SJohn Forte ((SLIM2 *) hba->slim2.virt)->pcb.maxRing = (hba->ring_count - 1); 1269*fcf3ce44SJohn Forte ((SLIM2 *) hba->slim2.virt)->pcb.mailBoxSize = sizeof (MAILBOX) + 1270*fcf3ce44SJohn Forte MBOX_EXTENSION_SIZE; 1271*fcf3ce44SJohn Forte 1272*fcf3ce44SJohn Forte mbx = hba->slim2.phys + (uint64_t)(unsigned long)& (slim->mbx); 1273*fcf3ce44SJohn Forte ((SLIM2 *)hba->slim2.virt)->pcb.mbAddrHigh = 1274*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(mbx); 1275*fcf3ce44SJohn Forte ((SLIM2 *)hba->slim2.virt)->pcb.mbAddrLow = (uint32_t)putPaddrLow(mbx); 1276*fcf3ce44SJohn Forte 1277*fcf3ce44SJohn Forte 1278*fcf3ce44SJohn Forte /* 1279*fcf3ce44SJohn Forte * Set up HGP - Port Memory 1280*fcf3ce44SJohn Forte * 1281*fcf3ce44SJohn Forte * CR0Put - SLI2(no HBQs) = 0xc0, With HBQs = 0x80 1282*fcf3ce44SJohn Forte * RR0Get 0xc4 0x84 1283*fcf3ce44SJohn Forte * CR1Put 0xc8 0x88 1284*fcf3ce44SJohn Forte * RR1Get 0xcc 0x8c 1285*fcf3ce44SJohn Forte * CR2Put 0xd0 0x90 1286*fcf3ce44SJohn Forte * RR2Get 0xd4 0x94 1287*fcf3ce44SJohn Forte * CR3Put 0xd8 0x98 1288*fcf3ce44SJohn Forte * RR3Get 0xdc 0x9c 1289*fcf3ce44SJohn Forte * 1290*fcf3ce44SJohn Forte * Reserved 0xa0-0xbf 1291*fcf3ce44SJohn Forte * 1292*fcf3ce44SJohn Forte * If HBQs configured: 1293*fcf3ce44SJohn Forte * HBQ 0 Put ptr 0xc0 1294*fcf3ce44SJohn Forte * HBQ 1 Put ptr 0xc4 1295*fcf3ce44SJohn Forte * HBQ 2 Put ptr 0xc8 1296*fcf3ce44SJohn Forte * ...... 1297*fcf3ce44SJohn Forte * HBQ(M-1)Put Pointer 0xc0+(M-1)*4 1298*fcf3ce44SJohn Forte */ 1299*fcf3ce44SJohn Forte 1300*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 1301*fcf3ce44SJohn Forte if (sli_mode >= 3) { 1302*fcf3ce44SJohn Forte /* ERBM is enabled */ 1303*fcf3ce44SJohn Forte hba->hgp_ring_offset = 0x80; 1304*fcf3ce44SJohn Forte hba->hgp_hbq_offset = 0xC0; 1305*fcf3ce44SJohn Forte 1306*fcf3ce44SJohn Forte hba->iocb_cmd_size = SLI3_IOCB_CMD_SIZE; 1307*fcf3ce44SJohn Forte hba->iocb_rsp_size = SLI3_IOCB_RSP_SIZE; 1308*fcf3ce44SJohn Forte 1309*fcf3ce44SJohn Forte } else /* SLI2 */ 1310*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 1311*fcf3ce44SJohn Forte { 1312*fcf3ce44SJohn Forte /* ERBM is disabled */ 1313*fcf3ce44SJohn Forte hba->hgp_ring_offset = 0xC0; 1314*fcf3ce44SJohn Forte hba->hgp_hbq_offset = 0; 1315*fcf3ce44SJohn Forte 1316*fcf3ce44SJohn Forte hba->iocb_cmd_size = SLI2_IOCB_CMD_SIZE; 1317*fcf3ce44SJohn Forte hba->iocb_rsp_size = SLI2_IOCB_RSP_SIZE; 1318*fcf3ce44SJohn Forte } 1319*fcf3ce44SJohn Forte 1320*fcf3ce44SJohn Forte /* The Sbus card uses Host Memory. The PCI card uses SLIM POINTER */ 1321*fcf3ce44SJohn Forte if (hba->bus_type == SBUS_FC) { 1322*fcf3ce44SJohn Forte hgp = hba->slim2.phys + 1323*fcf3ce44SJohn Forte (uint64_t)(unsigned long)& (mbox->us.s2.host); 1324*fcf3ce44SJohn Forte ((SLIM2 *)hba->slim2.virt)->pcb.hgpAddrHigh = 1325*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(hgp); 1326*fcf3ce44SJohn Forte ((SLIM2 *)hba->slim2.virt)->pcb.hgpAddrLow = 1327*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(hgp); 1328*fcf3ce44SJohn Forte } else { 1329*fcf3ce44SJohn Forte ((SLIM2 *)hba->slim2.virt)->pcb.hgpAddrHigh = 1330*fcf3ce44SJohn Forte (uint32_t)ddi_get32(hba->pci_acc_handle, 1331*fcf3ce44SJohn Forte (uint32_t *)(hba->pci_addr + PCI_BAR_1_REGISTER)); 1332*fcf3ce44SJohn Forte 1333*fcf3ce44SJohn Forte Laddr = ddi_get32(hba->pci_acc_handle, 1334*fcf3ce44SJohn Forte (uint32_t *)(hba->pci_addr + PCI_BAR_0_REGISTER)); 1335*fcf3ce44SJohn Forte Laddr &= ~0x4; 1336*fcf3ce44SJohn Forte ((SLIM2 *)hba->slim2.virt)->pcb.hgpAddrLow = 1337*fcf3ce44SJohn Forte (uint32_t)(Laddr + hba->hgp_ring_offset); 1338*fcf3ce44SJohn Forte 1339*fcf3ce44SJohn Forte } 1340*fcf3ce44SJohn Forte 1341*fcf3ce44SJohn Forte pgp = hba->slim2.phys + (uint64_t)(unsigned long)& (mbox->us.s2.port); 1342*fcf3ce44SJohn Forte ((SLIM2 *)hba->slim2.virt)->pcb.pgpAddrHigh = 1343*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(pgp); 1344*fcf3ce44SJohn Forte ((SLIM2 *)hba->slim2.virt)->pcb.pgpAddrLow = (uint32_t)putPaddrLow(pgp); 1345*fcf3ce44SJohn Forte 1346*fcf3ce44SJohn Forte offset = 0; 1347*fcf3ce44SJohn Forte for (i = 0; i < 4; i++) { 1348*fcf3ce44SJohn Forte rp = &hba->ring[i]; 1349*fcf3ce44SJohn Forte rdsc = &((SLIM2 *) hba->slim2.virt)->pcb.rdsc[i]; 1350*fcf3ce44SJohn Forte 1351*fcf3ce44SJohn Forte /* Setup command ring */ 1352*fcf3ce44SJohn Forte rgp = hba->slim2.phys + 1353*fcf3ce44SJohn Forte (uint64_t)(unsigned long)& (slim->IOCBs[offset]); 1354*fcf3ce44SJohn Forte rdsc->cmdAddrHigh = (uint32_t)putPaddrHigh(rgp); 1355*fcf3ce44SJohn Forte rdsc->cmdAddrLow = (uint32_t)putPaddrLow(rgp); 1356*fcf3ce44SJohn Forte rdsc->cmdEntries = rp->fc_numCiocb; 1357*fcf3ce44SJohn Forte 1358*fcf3ce44SJohn Forte rp->fc_cmdringaddr = (void *) &((SLIM2 *) hba->slim2.virt)-> 1359*fcf3ce44SJohn Forte IOCBs[offset]; 1360*fcf3ce44SJohn Forte offset += rdsc->cmdEntries * hba->iocb_cmd_size; 1361*fcf3ce44SJohn Forte 1362*fcf3ce44SJohn Forte /* Setup response ring */ 1363*fcf3ce44SJohn Forte rgp = hba->slim2.phys + 1364*fcf3ce44SJohn Forte (uint64_t)(unsigned long)& (slim->IOCBs[offset]); 1365*fcf3ce44SJohn Forte rdsc->rspAddrHigh = (uint32_t)putPaddrHigh(rgp); 1366*fcf3ce44SJohn Forte rdsc->rspAddrLow = (uint32_t)putPaddrLow(rgp); 1367*fcf3ce44SJohn Forte rdsc->rspEntries = rp->fc_numRiocb; 1368*fcf3ce44SJohn Forte 1369*fcf3ce44SJohn Forte rp->fc_rspringaddr = (void *) &((SLIM2 *) hba->slim2.virt)-> 1370*fcf3ce44SJohn Forte IOCBs[offset]; 1371*fcf3ce44SJohn Forte offset += rdsc->rspEntries * hba->iocb_rsp_size; 1372*fcf3ce44SJohn Forte } 1373*fcf3ce44SJohn Forte 1374*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)(&((SLIM2 *) hba->slim2.virt)->pcb), 1375*fcf3ce44SJohn Forte (uint32_t *)(&((SLIM2 *) hba->slim2.virt)->pcb), sizeof (PCB)); 1376*fcf3ce44SJohn Forte 1377*fcf3ce44SJohn Forte offset = 1378*fcf3ce44SJohn Forte ((uint64_t)(unsigned long)& (((SLIM2 *) hba->slim2.virt)->pcb) - 1379*fcf3ce44SJohn Forte (uint64_t)(unsigned long)hba->slim2.virt); 1380*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, (off_t)offset, sizeof (PCB), 1381*fcf3ce44SJohn Forte DDI_DMA_SYNC_FORDEV); 1382*fcf3ce44SJohn Forte 1383*fcf3ce44SJohn Forte return (0); 1384*fcf3ce44SJohn Forte 1385*fcf3ce44SJohn Forte } /* emlxs_mb_config_port() */ 1386*fcf3ce44SJohn Forte 1387*fcf3ce44SJohn Forte 1388*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 1389*fcf3ce44SJohn Forte extern void 1390*fcf3ce44SJohn Forte emlxs_mb_config_hbq(emlxs_hba_t *hba, MAILBOX *mb, int hbq_id) 1391*fcf3ce44SJohn Forte { 1392*fcf3ce44SJohn Forte HBQ_INIT_t *hbq; 1393*fcf3ce44SJohn Forte int i; 1394*fcf3ce44SJohn Forte 1395*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1396*fcf3ce44SJohn Forte 1397*fcf3ce44SJohn Forte hbq = &hba->hbq_table[hbq_id]; 1398*fcf3ce44SJohn Forte 1399*fcf3ce44SJohn Forte mb->un.varCfgHbq.hbqId = hbq_id; 1400*fcf3ce44SJohn Forte mb->un.varCfgHbq.numEntries = hbq->HBQ_numEntries; 1401*fcf3ce44SJohn Forte mb->un.varCfgHbq.recvNotify = hbq->HBQ_recvNotify; 1402*fcf3ce44SJohn Forte mb->un.varCfgHbq.numMask = hbq->HBQ_num_mask; 1403*fcf3ce44SJohn Forte mb->un.varCfgHbq.profile = hbq->HBQ_profile; 1404*fcf3ce44SJohn Forte mb->un.varCfgHbq.ringMask = hbq->HBQ_ringMask; 1405*fcf3ce44SJohn Forte mb->un.varCfgHbq.headerLen = hbq->HBQ_headerLen; 1406*fcf3ce44SJohn Forte mb->un.varCfgHbq.logEntry = hbq->HBQ_logEntry; 1407*fcf3ce44SJohn Forte mb->un.varCfgHbq.hbqaddrLow = putPaddrLow(hbq->HBQ_host_buf.phys); 1408*fcf3ce44SJohn Forte mb->un.varCfgHbq.hbqaddrHigh = putPaddrHigh(hbq->HBQ_host_buf.phys); 1409*fcf3ce44SJohn Forte mb->mbxCommand = MBX_CONFIG_HBQ; 1410*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1411*fcf3ce44SJohn Forte 1412*fcf3ce44SJohn Forte /* Copy info for profiles 2,3,5. Other profiles this area is reserved */ 1413*fcf3ce44SJohn Forte if ((hbq->HBQ_profile == 2) || (hbq->HBQ_profile == 3) || 1414*fcf3ce44SJohn Forte (hbq->HBQ_profile == 5)) { 1415*fcf3ce44SJohn Forte bcopy(&hbq->profiles.allprofiles, 1416*fcf3ce44SJohn Forte &mb->un.varCfgHbq.profiles.allprofiles, 1417*fcf3ce44SJohn Forte sizeof (hbq->profiles)); 1418*fcf3ce44SJohn Forte } 1419*fcf3ce44SJohn Forte /* Return if no rctl / type masks for this HBQ */ 1420*fcf3ce44SJohn Forte if (!hbq->HBQ_num_mask) { 1421*fcf3ce44SJohn Forte return; 1422*fcf3ce44SJohn Forte } 1423*fcf3ce44SJohn Forte /* Otherwise we setup specific rctl / type masks for this HBQ */ 1424*fcf3ce44SJohn Forte for (i = 0; i < hbq->HBQ_num_mask; i++) { 1425*fcf3ce44SJohn Forte mb->un.varCfgHbq.hbqMasks[i].tmatch = hbq->HBQ_Masks[i].tmatch; 1426*fcf3ce44SJohn Forte mb->un.varCfgHbq.hbqMasks[i].tmask = hbq->HBQ_Masks[i].tmask; 1427*fcf3ce44SJohn Forte mb->un.varCfgHbq.hbqMasks[i].rctlmatch = 1428*fcf3ce44SJohn Forte hbq->HBQ_Masks[i].rctlmatch; 1429*fcf3ce44SJohn Forte mb->un.varCfgHbq.hbqMasks[i].rctlmask = 1430*fcf3ce44SJohn Forte hbq->HBQ_Masks[i].rctlmask; 1431*fcf3ce44SJohn Forte } 1432*fcf3ce44SJohn Forte 1433*fcf3ce44SJohn Forte return; 1434*fcf3ce44SJohn Forte 1435*fcf3ce44SJohn Forte } /* emlxs_mb_config_hbq() */ 1436*fcf3ce44SJohn Forte 1437*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 1438*fcf3ce44SJohn Forte 1439*fcf3ce44SJohn Forte 1440*fcf3ce44SJohn Forte extern uint32_t 1441*fcf3ce44SJohn Forte emlxs_mb_reg_vpi(emlxs_port_t *port) 1442*fcf3ce44SJohn Forte { 1443*fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1444*fcf3ce44SJohn Forte MAILBOXQ *mbq; 1445*fcf3ce44SJohn Forte MAILBOX *mb; 1446*fcf3ce44SJohn Forte 1447*fcf3ce44SJohn Forte if (!(hba->flag & FC_NPIV_ENABLED)) { 1448*fcf3ce44SJohn Forte return (0); 1449*fcf3ce44SJohn Forte } 1450*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1451*fcf3ce44SJohn Forte 1452*fcf3ce44SJohn Forte /* Can't reg vpi until ClearLA is sent */ 1453*fcf3ce44SJohn Forte if (hba->state != FC_READY) { 1454*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1455*fcf3ce44SJohn Forte 1456*fcf3ce44SJohn Forte return (1); 1457*fcf3ce44SJohn Forte } 1458*fcf3ce44SJohn Forte /* Must have port id */ 1459*fcf3ce44SJohn Forte if (!port->did) { 1460*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1461*fcf3ce44SJohn Forte 1462*fcf3ce44SJohn Forte return (1); 1463*fcf3ce44SJohn Forte } 1464*fcf3ce44SJohn Forte if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) { 1465*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1466*fcf3ce44SJohn Forte 1467*fcf3ce44SJohn Forte return (1); 1468*fcf3ce44SJohn Forte } 1469*fcf3ce44SJohn Forte port->flag |= EMLXS_PORT_REGISTERED; 1470*fcf3ce44SJohn Forte 1471*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1472*fcf3ce44SJohn Forte 1473*fcf3ce44SJohn Forte mb = (MAILBOX *) mbq->mbox; 1474*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1475*fcf3ce44SJohn Forte mb->un.varRegVpi.vpi = port->vpi; 1476*fcf3ce44SJohn Forte mb->un.varRegVpi.sid = port->did; 1477*fcf3ce44SJohn Forte mb->mbxCommand = MBX_REG_VPI; 1478*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1479*fcf3ce44SJohn Forte 1480*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) { 1481*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 1482*fcf3ce44SJohn Forte } 1483*fcf3ce44SJohn Forte return (0); 1484*fcf3ce44SJohn Forte 1485*fcf3ce44SJohn Forte } /* emlxs_mb_reg_vpi() */ 1486*fcf3ce44SJohn Forte 1487*fcf3ce44SJohn Forte 1488*fcf3ce44SJohn Forte extern uint32_t 1489*fcf3ce44SJohn Forte emlxs_mb_unreg_vpi(emlxs_port_t *port) 1490*fcf3ce44SJohn Forte { 1491*fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1492*fcf3ce44SJohn Forte MAILBOXQ *mbq; 1493*fcf3ce44SJohn Forte MAILBOX *mb; 1494*fcf3ce44SJohn Forte 1495*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1496*fcf3ce44SJohn Forte 1497*fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_REGISTERED)) { 1498*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1499*fcf3ce44SJohn Forte 1500*fcf3ce44SJohn Forte return (0); 1501*fcf3ce44SJohn Forte } 1502*fcf3ce44SJohn Forte if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) { 1503*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1504*fcf3ce44SJohn Forte 1505*fcf3ce44SJohn Forte return (1); 1506*fcf3ce44SJohn Forte } 1507*fcf3ce44SJohn Forte port->flag &= ~EMLXS_PORT_REGISTERED; 1508*fcf3ce44SJohn Forte 1509*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1510*fcf3ce44SJohn Forte 1511*fcf3ce44SJohn Forte mb = (MAILBOX *) mbq->mbox; 1512*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1513*fcf3ce44SJohn Forte mb->un.varUnregVpi.vpi = port->vpi; 1514*fcf3ce44SJohn Forte mb->mbxCommand = MBX_UNREG_VPI; 1515*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1516*fcf3ce44SJohn Forte 1517*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) { 1518*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 1519*fcf3ce44SJohn Forte } 1520*fcf3ce44SJohn Forte return (0); 1521*fcf3ce44SJohn Forte 1522*fcf3ce44SJohn Forte } /* emlxs_mb_unreg_vpi() */ 1523*fcf3ce44SJohn Forte 1524*fcf3ce44SJohn Forte 1525*fcf3ce44SJohn Forte /* 1526*fcf3ce44SJohn Forte * emlxs_mb_config_farp Issue a CONFIG FARP 1527*fcf3ce44SJohn Forte * mailbox command 1528*fcf3ce44SJohn Forte */ 1529*fcf3ce44SJohn Forte extern void 1530*fcf3ce44SJohn Forte emlxs_mb_config_farp(emlxs_hba_t *hba, MAILBOX *mb) 1531*fcf3ce44SJohn Forte { 1532*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1533*fcf3ce44SJohn Forte 1534*fcf3ce44SJohn Forte bcopy((uint8_t *)& hba->wwpn, 1535*fcf3ce44SJohn Forte (uint8_t *)& mb->un.varCfgFarp.portname, 1536*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 1537*fcf3ce44SJohn Forte 1538*fcf3ce44SJohn Forte bcopy((uint8_t *)& hba->wwpn, 1539*fcf3ce44SJohn Forte (uint8_t *)& mb->un.varCfgFarp.nodename, 1540*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 1541*fcf3ce44SJohn Forte 1542*fcf3ce44SJohn Forte mb->un.varCfgFarp.filterEnable = 1; 1543*fcf3ce44SJohn Forte mb->un.varCfgFarp.portName = 1; 1544*fcf3ce44SJohn Forte mb->un.varCfgFarp.nodeName = 1; 1545*fcf3ce44SJohn Forte mb->mbxCommand = MBX_CONFIG_FARP; 1546*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1547*fcf3ce44SJohn Forte } /* emlxs_mb_config_farp() */ 1548*fcf3ce44SJohn Forte 1549*fcf3ce44SJohn Forte 1550*fcf3ce44SJohn Forte /* 1551*fcf3ce44SJohn Forte * emlxs_mb_read_nv Issue a READ CONFIG 1552*fcf3ce44SJohn Forte * mailbox command 1553*fcf3ce44SJohn Forte */ 1554*fcf3ce44SJohn Forte /* ARGSUSED */ 1555*fcf3ce44SJohn Forte extern void 1556*fcf3ce44SJohn Forte emlxs_mb_read_config(emlxs_hba_t *hba, MAILBOX *mb) 1557*fcf3ce44SJohn Forte { 1558*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 1559*fcf3ce44SJohn Forte 1560*fcf3ce44SJohn Forte mb->mbxCommand = MBX_READ_CONFIG; 1561*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1562*fcf3ce44SJohn Forte 1563*fcf3ce44SJohn Forte } /* emlxs_mb_read_config() */ 1564*fcf3ce44SJohn Forte 1565*fcf3ce44SJohn Forte 1566*fcf3ce44SJohn Forte 1567*fcf3ce44SJohn Forte /* 1568*fcf3ce44SJohn Forte * NAME: emlxs_mb_put 1569*fcf3ce44SJohn Forte * 1570*fcf3ce44SJohn Forte * FUNCTION: put mailbox cmd onto the mailbox queue. 1571*fcf3ce44SJohn Forte * 1572*fcf3ce44SJohn Forte * EXECUTION ENVIRONMENT: process and interrupt level. 1573*fcf3ce44SJohn Forte * 1574*fcf3ce44SJohn Forte * NOTES: 1575*fcf3ce44SJohn Forte * 1576*fcf3ce44SJohn Forte * CALLED FROM: emlxs_mb_issue_cmd 1577*fcf3ce44SJohn Forte * 1578*fcf3ce44SJohn Forte * INPUT: hba - pointer to the device info area mbp 1579*fcf3ce44SJohn Forte * - pointer to mailbox queue entry of mailbox cmd 1580*fcf3ce44SJohn Forte * 1581*fcf3ce44SJohn Forte * RETURNS: NULL - command queued 1582*fcf3ce44SJohn Forte */ 1583*fcf3ce44SJohn Forte extern void 1584*fcf3ce44SJohn Forte emlxs_mb_put(emlxs_hba_t *hba, MAILBOXQ *mbq) 1585*fcf3ce44SJohn Forte { 1586*fcf3ce44SJohn Forte 1587*fcf3ce44SJohn Forte mutex_enter(&EMLXS_MBOX_LOCK); 1588*fcf3ce44SJohn Forte 1589*fcf3ce44SJohn Forte if (hba->mbox_queue.q_first) { 1590*fcf3ce44SJohn Forte 1591*fcf3ce44SJohn Forte /* 1592*fcf3ce44SJohn Forte * queue command to end of list 1593*fcf3ce44SJohn Forte */ 1594*fcf3ce44SJohn Forte ((MAILBOXQ *) hba->mbox_queue.q_last)->next = mbq; 1595*fcf3ce44SJohn Forte hba->mbox_queue.q_last = (uint8_t *)mbq; 1596*fcf3ce44SJohn Forte hba->mbox_queue.q_cnt++; 1597*fcf3ce44SJohn Forte } else { 1598*fcf3ce44SJohn Forte 1599*fcf3ce44SJohn Forte /* 1600*fcf3ce44SJohn Forte * add command to empty list 1601*fcf3ce44SJohn Forte */ 1602*fcf3ce44SJohn Forte hba->mbox_queue.q_first = (uint8_t *)mbq; 1603*fcf3ce44SJohn Forte hba->mbox_queue.q_last = (uint8_t *)mbq; 1604*fcf3ce44SJohn Forte hba->mbox_queue.q_cnt = 1; 1605*fcf3ce44SJohn Forte } 1606*fcf3ce44SJohn Forte 1607*fcf3ce44SJohn Forte mbq->next = NULL; 1608*fcf3ce44SJohn Forte 1609*fcf3ce44SJohn Forte mutex_exit(&EMLXS_MBOX_LOCK); 1610*fcf3ce44SJohn Forte } /* emlxs_mb_put() */ 1611*fcf3ce44SJohn Forte 1612*fcf3ce44SJohn Forte 1613*fcf3ce44SJohn Forte /* 1614*fcf3ce44SJohn Forte * NAME: emlxs_mb_get 1615*fcf3ce44SJohn Forte * 1616*fcf3ce44SJohn Forte * FUNCTION: get a mailbox command from mailbox command queue 1617*fcf3ce44SJohn Forte * 1618*fcf3ce44SJohn Forte * EXECUTION ENVIRONMENT: interrupt level. 1619*fcf3ce44SJohn Forte * 1620*fcf3ce44SJohn Forte * NOTES: 1621*fcf3ce44SJohn Forte * 1622*fcf3ce44SJohn Forte * CALLED FROM: emlxs_handle_mb_event 1623*fcf3ce44SJohn Forte * 1624*fcf3ce44SJohn Forte * INPUT: hba - pointer to the device info area 1625*fcf3ce44SJohn Forte * 1626*fcf3ce44SJohn Forte * RETURNS: NULL - no match found mb pointer - pointer to a mailbox command 1627*fcf3ce44SJohn Forte */ 1628*fcf3ce44SJohn Forte extern MAILBOXQ * 1629*fcf3ce44SJohn Forte emlxs_mb_get(emlxs_hba_t *hba) 1630*fcf3ce44SJohn Forte { 1631*fcf3ce44SJohn Forte MAILBOXQ *p_first = NULL; 1632*fcf3ce44SJohn Forte 1633*fcf3ce44SJohn Forte mutex_enter(&EMLXS_MBOX_LOCK); 1634*fcf3ce44SJohn Forte 1635*fcf3ce44SJohn Forte if (hba->mbox_queue.q_first) { 1636*fcf3ce44SJohn Forte p_first = (MAILBOXQ *) hba->mbox_queue.q_first; 1637*fcf3ce44SJohn Forte hba->mbox_queue.q_first = (uint8_t *)p_first->next; 1638*fcf3ce44SJohn Forte 1639*fcf3ce44SJohn Forte if (hba->mbox_queue.q_first == NULL) { 1640*fcf3ce44SJohn Forte hba->mbox_queue.q_last = NULL; 1641*fcf3ce44SJohn Forte hba->mbox_queue.q_cnt = 0; 1642*fcf3ce44SJohn Forte } else { 1643*fcf3ce44SJohn Forte hba->mbox_queue.q_cnt--; 1644*fcf3ce44SJohn Forte } 1645*fcf3ce44SJohn Forte 1646*fcf3ce44SJohn Forte p_first->next = NULL; 1647*fcf3ce44SJohn Forte } 1648*fcf3ce44SJohn Forte mutex_exit(&EMLXS_MBOX_LOCK); 1649*fcf3ce44SJohn Forte 1650*fcf3ce44SJohn Forte return (p_first); 1651*fcf3ce44SJohn Forte 1652*fcf3ce44SJohn Forte } /* emlxs_mb_get() */ 1653*fcf3ce44SJohn Forte 1654*fcf3ce44SJohn Forte 1655*fcf3ce44SJohn Forte 1656*fcf3ce44SJohn Forte /* EMLXS_PORT_LOCK must be held when calling this */ 1657*fcf3ce44SJohn Forte static void 1658*fcf3ce44SJohn Forte emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, uint32_t tmo) 1659*fcf3ce44SJohn Forte { 1660*fcf3ce44SJohn Forte MATCHMAP *mp; 1661*fcf3ce44SJohn Forte 1662*fcf3ce44SJohn Forte HBASTATS.MboxIssued++; 1663*fcf3ce44SJohn Forte hba->mbox_queue_flag = flag; 1664*fcf3ce44SJohn Forte 1665*fcf3ce44SJohn Forte /* Set the Mailbox timer */ 1666*fcf3ce44SJohn Forte hba->mbox_timer = hba->timer_tics + tmo; 1667*fcf3ce44SJohn Forte 1668*fcf3ce44SJohn Forte /* Initialize mailbox */ 1669*fcf3ce44SJohn Forte mbq->flag &= MBQ_INIT_MASK; 1670*fcf3ce44SJohn Forte hba->mbox_mbqflag = mbq->flag; 1671*fcf3ce44SJohn Forte 1672*fcf3ce44SJohn Forte mbq->next = 0; 1673*fcf3ce44SJohn Forte 1674*fcf3ce44SJohn Forte mutex_enter(&EMLXS_MBOX_LOCK); 1675*fcf3ce44SJohn Forte if (flag == MBX_NOWAIT) { 1676*fcf3ce44SJohn Forte hba->mbox_mbq = 0; 1677*fcf3ce44SJohn Forte } else { 1678*fcf3ce44SJohn Forte hba->mbox_mbq = (uint8_t *)mbq; 1679*fcf3ce44SJohn Forte } 1680*fcf3ce44SJohn Forte mutex_exit(&EMLXS_MBOX_LOCK); 1681*fcf3ce44SJohn Forte 1682*fcf3ce44SJohn Forte if (mbq->bp) { 1683*fcf3ce44SJohn Forte mp = (MATCHMAP *) mbq->bp; 1684*fcf3ce44SJohn Forte emlxs_mpdata_sync(mp->dma_handle, 0, mp->size, 1685*fcf3ce44SJohn Forte DDI_DMA_SYNC_FORDEV); 1686*fcf3ce44SJohn Forte 1687*fcf3ce44SJohn Forte hba->mbox_bp = mbq->bp; 1688*fcf3ce44SJohn Forte mbq->bp = 0; 1689*fcf3ce44SJohn Forte } 1690*fcf3ce44SJohn Forte if (mbq->sbp) { 1691*fcf3ce44SJohn Forte hba->mbox_sbp = mbq->sbp; 1692*fcf3ce44SJohn Forte mbq->sbp = 0; 1693*fcf3ce44SJohn Forte } 1694*fcf3ce44SJohn Forte if (mbq->ubp) { 1695*fcf3ce44SJohn Forte hba->mbox_ubp = mbq->ubp; 1696*fcf3ce44SJohn Forte mbq->ubp = 0; 1697*fcf3ce44SJohn Forte } 1698*fcf3ce44SJohn Forte if (mbq->iocbq) { 1699*fcf3ce44SJohn Forte hba->mbox_iocbq = mbq->iocbq; 1700*fcf3ce44SJohn Forte mbq->iocbq = 0; 1701*fcf3ce44SJohn Forte } 1702*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 1703*fcf3ce44SJohn Forte if (mbq->extbuf && mbq->extsize) { 1704*fcf3ce44SJohn Forte hba->mbox_ext = mbq->extbuf; 1705*fcf3ce44SJohn Forte hba->mbox_ext_size = mbq->extsize; 1706*fcf3ce44SJohn Forte } 1707*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 1708*fcf3ce44SJohn Forte 1709*fcf3ce44SJohn Forte return; 1710*fcf3ce44SJohn Forte 1711*fcf3ce44SJohn Forte } /* emlxs_mb_init() */ 1712*fcf3ce44SJohn Forte 1713*fcf3ce44SJohn Forte 1714*fcf3ce44SJohn Forte extern void 1715*fcf3ce44SJohn Forte emlxs_mb_fini(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mbxStatus) 1716*fcf3ce44SJohn Forte { 1717*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1718*fcf3ce44SJohn Forte MATCHMAP *mbox_bp; 1719*fcf3ce44SJohn Forte emlxs_buf_t *mbox_sbp; 1720*fcf3ce44SJohn Forte fc_unsol_buf_t *mbox_ubp; 1721*fcf3ce44SJohn Forte IOCBQ *mbox_iocbq; 1722*fcf3ce44SJohn Forte MAILBOXQ *mbox_mbq; 1723*fcf3ce44SJohn Forte MAILBOX *mbox; 1724*fcf3ce44SJohn Forte uint32_t mbox_queue_flag; 1725*fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 1726*fcf3ce44SJohn Forte 1727*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1728*fcf3ce44SJohn Forte 1729*fcf3ce44SJohn Forte if (hba->mbox_queue_flag) { 1730*fcf3ce44SJohn Forte HBASTATS.MboxCompleted++; 1731*fcf3ce44SJohn Forte 1732*fcf3ce44SJohn Forte if (mbxStatus != MBX_SUCCESS) { 1733*fcf3ce44SJohn Forte HBASTATS.MboxError++; 1734*fcf3ce44SJohn Forte } else { 1735*fcf3ce44SJohn Forte HBASTATS.MboxGood++; 1736*fcf3ce44SJohn Forte } 1737*fcf3ce44SJohn Forte } 1738*fcf3ce44SJohn Forte mbox_bp = (MATCHMAP *) hba->mbox_bp; 1739*fcf3ce44SJohn Forte mbox_sbp = (emlxs_buf_t *)hba->mbox_sbp; 1740*fcf3ce44SJohn Forte mbox_ubp = (fc_unsol_buf_t *)hba->mbox_ubp; 1741*fcf3ce44SJohn Forte mbox_iocbq = (IOCBQ *) hba->mbox_iocbq; 1742*fcf3ce44SJohn Forte mbox_mbq = (MAILBOXQ *) hba->mbox_mbq; 1743*fcf3ce44SJohn Forte mbox_queue_flag = hba->mbox_queue_flag; 1744*fcf3ce44SJohn Forte 1745*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 1746*fcf3ce44SJohn Forte hba->mbox_ext = 0; 1747*fcf3ce44SJohn Forte hba->mbox_ext_size = 0; 1748*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 1749*fcf3ce44SJohn Forte 1750*fcf3ce44SJohn Forte hba->mbox_bp = 0; 1751*fcf3ce44SJohn Forte hba->mbox_sbp = 0; 1752*fcf3ce44SJohn Forte hba->mbox_ubp = 0; 1753*fcf3ce44SJohn Forte hba->mbox_iocbq = 0; 1754*fcf3ce44SJohn Forte hba->mbox_mbqflag = 0; 1755*fcf3ce44SJohn Forte hba->mbox_mbq = 0; 1756*fcf3ce44SJohn Forte hba->mbox_timer = 0; 1757*fcf3ce44SJohn Forte hba->mbox_queue_flag = 0; 1758*fcf3ce44SJohn Forte 1759*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1760*fcf3ce44SJohn Forte 1761*fcf3ce44SJohn Forte if (mbox_mbq) { 1762*fcf3ce44SJohn Forte if (mb) { 1763*fcf3ce44SJohn Forte /* 1764*fcf3ce44SJohn Forte * Copy the local mailbox provided back into the 1765*fcf3ce44SJohn Forte * original mailbox 1766*fcf3ce44SJohn Forte */ 1767*fcf3ce44SJohn Forte bcopy((uint32_t *)mb, (uint32_t *)mbox_mbq, 1768*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE); 1769*fcf3ce44SJohn Forte } 1770*fcf3ce44SJohn Forte mbox = (MAILBOX *) mbox_mbq; 1771*fcf3ce44SJohn Forte mbox->mbxStatus = mbxStatus; 1772*fcf3ce44SJohn Forte 1773*fcf3ce44SJohn Forte /* Mark mailbox complete */ 1774*fcf3ce44SJohn Forte mbox_mbq->flag |= MBQ_COMPLETED; 1775*fcf3ce44SJohn Forte 1776*fcf3ce44SJohn Forte /* Wake up the sleeping thread */ 1777*fcf3ce44SJohn Forte if (mbox_queue_flag == MBX_SLEEP) { 1778*fcf3ce44SJohn Forte mutex_enter(&EMLXS_MBOX_LOCK); 1779*fcf3ce44SJohn Forte cv_broadcast(&EMLXS_MBOX_CV); 1780*fcf3ce44SJohn Forte mutex_exit(&EMLXS_MBOX_LOCK); 1781*fcf3ce44SJohn Forte } 1782*fcf3ce44SJohn Forte } 1783*fcf3ce44SJohn Forte /* Check for deferred MBUF cleanup */ 1784*fcf3ce44SJohn Forte if (mbox_bp && (mbox_queue_flag == MBX_NOWAIT)) { 1785*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mbox_bp); 1786*fcf3ce44SJohn Forte } 1787*fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 1788*fcf3ce44SJohn Forte if (mbox_sbp && mbox_sbp->fct_cmd) { 1789*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1790*fcf3ce44SJohn Forte "FCT mailbox: %s: status=%x", 1791*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 1792*fcf3ce44SJohn Forte (uint32_t)mb->mbxStatus); 1793*fcf3ce44SJohn Forte } 1794*fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 1795*fcf3ce44SJohn Forte 1796*fcf3ce44SJohn Forte /* Check for deferred pkt completion */ 1797*fcf3ce44SJohn Forte if (mbox_sbp) { 1798*fcf3ce44SJohn Forte if (mbxStatus != MBX_SUCCESS) { 1799*fcf3ce44SJohn Forte /* Set error status */ 1800*fcf3ce44SJohn Forte mbox_sbp->pkt_flags &= ~PACKET_STATE_VALID; 1801*fcf3ce44SJohn Forte emlxs_set_pkt_state(mbox_sbp, IOSTAT_LOCAL_REJECT, 1802*fcf3ce44SJohn Forte IOERR_NO_RESOURCES, 1); 1803*fcf3ce44SJohn Forte } 1804*fcf3ce44SJohn Forte emlxs_pkt_complete(mbox_sbp, -1, 0, 1); 1805*fcf3ce44SJohn Forte } 1806*fcf3ce44SJohn Forte /* Check for deferred ub completion */ 1807*fcf3ce44SJohn Forte if (mbox_ubp) { 1808*fcf3ce44SJohn Forte ub_priv = mbox_ubp->ub_fca_private; 1809*fcf3ce44SJohn Forte port = ub_priv->port; 1810*fcf3ce44SJohn Forte 1811*fcf3ce44SJohn Forte emlxs_ub_callback(port, mbox_ubp); 1812*fcf3ce44SJohn Forte } 1813*fcf3ce44SJohn Forte /* Check for deferred iocb tx */ 1814*fcf3ce44SJohn Forte if (mbox_iocbq) { 1815*fcf3ce44SJohn Forte emlxs_issue_iocb_cmd(hba, mbox_iocbq->ring, mbox_iocbq); 1816*fcf3ce44SJohn Forte } 1817*fcf3ce44SJohn Forte return; 1818*fcf3ce44SJohn Forte 1819*fcf3ce44SJohn Forte } /* emlxs_mb_fini() */ 1820*fcf3ce44SJohn Forte 1821*fcf3ce44SJohn Forte 1822*fcf3ce44SJohn Forte 1823*fcf3ce44SJohn Forte /* This should only be called with active MBX_NOWAIT mailboxes */ 1824*fcf3ce44SJohn Forte static void 1825*fcf3ce44SJohn Forte emlxs_mb_retry(emlxs_hba_t *hba, MAILBOX *mb) 1826*fcf3ce44SJohn Forte { 1827*fcf3ce44SJohn Forte MAILBOXQ *mbq; 1828*fcf3ce44SJohn Forte 1829*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1830*fcf3ce44SJohn Forte 1831*fcf3ce44SJohn Forte HBASTATS.MboxCompleted++; 1832*fcf3ce44SJohn Forte 1833*fcf3ce44SJohn Forte if (mb->mbxStatus != 0) { 1834*fcf3ce44SJohn Forte HBASTATS.MboxError++; 1835*fcf3ce44SJohn Forte } else { 1836*fcf3ce44SJohn Forte HBASTATS.MboxGood++; 1837*fcf3ce44SJohn Forte } 1838*fcf3ce44SJohn Forte 1839*fcf3ce44SJohn Forte mbq = (MAILBOXQ *) mb; 1840*fcf3ce44SJohn Forte mbq->bp = (uint8_t *)hba->mbox_bp; 1841*fcf3ce44SJohn Forte mbq->sbp = (uint8_t *)hba->mbox_sbp; 1842*fcf3ce44SJohn Forte mbq->ubp = (uint8_t *)hba->mbox_ubp; 1843*fcf3ce44SJohn Forte mbq->iocbq = (uint8_t *)hba->mbox_iocbq; 1844*fcf3ce44SJohn Forte 1845*fcf3ce44SJohn Forte hba->mbox_bp = 0; 1846*fcf3ce44SJohn Forte hba->mbox_sbp = 0; 1847*fcf3ce44SJohn Forte hba->mbox_ubp = 0; 1848*fcf3ce44SJohn Forte hba->mbox_iocbq = 0; 1849*fcf3ce44SJohn Forte hba->mbox_mbq = 0; 1850*fcf3ce44SJohn Forte hba->mbox_mbqflag = 0; 1851*fcf3ce44SJohn Forte hba->mbox_queue_flag = 0; 1852*fcf3ce44SJohn Forte 1853*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1854*fcf3ce44SJohn Forte 1855*fcf3ce44SJohn Forte return; 1856*fcf3ce44SJohn Forte 1857*fcf3ce44SJohn Forte } /* emlxs_mb_retry() */ 1858*fcf3ce44SJohn Forte 1859*fcf3ce44SJohn Forte 1860*fcf3ce44SJohn Forte 1861*fcf3ce44SJohn Forte /* 1862*fcf3ce44SJohn Forte * emlxs_handle_mb_event 1863*fcf3ce44SJohn Forte * 1864*fcf3ce44SJohn Forte * Description: Process a Mailbox Attention. 1865*fcf3ce44SJohn Forte * Called from host_interrupt to process MBATT 1866*fcf3ce44SJohn Forte * 1867*fcf3ce44SJohn Forte * Returns: 1868*fcf3ce44SJohn Forte * 1869*fcf3ce44SJohn Forte */ 1870*fcf3ce44SJohn Forte extern uint32_t 1871*fcf3ce44SJohn Forte emlxs_handle_mb_event(emlxs_hba_t *hba) 1872*fcf3ce44SJohn Forte { 1873*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1874*fcf3ce44SJohn Forte MAILBOX *mb; 1875*fcf3ce44SJohn Forte MAILBOX *swpmb; 1876*fcf3ce44SJohn Forte MAILBOX *mbox; 1877*fcf3ce44SJohn Forte MAILBOXQ *mbq; 1878*fcf3ce44SJohn Forte emlxs_config_t *cfg; 1879*fcf3ce44SJohn Forte uint32_t control; 1880*fcf3ce44SJohn Forte volatile uint32_t word0; 1881*fcf3ce44SJohn Forte MATCHMAP *mbox_bp; 1882*fcf3ce44SJohn Forte uint32_t la_enable; 1883*fcf3ce44SJohn Forte off_t offset; 1884*fcf3ce44SJohn Forte uint32_t i; 1885*fcf3ce44SJohn Forte MAILBOXQ mailbox; 1886*fcf3ce44SJohn Forte 1887*fcf3ce44SJohn Forte cfg = &CFG; 1888*fcf3ce44SJohn Forte swpmb = (MAILBOX *) & word0; 1889*fcf3ce44SJohn Forte mb = (MAILBOX *) & mailbox; 1890*fcf3ce44SJohn Forte 1891*fcf3ce44SJohn Forte switch (hba->mbox_queue_flag) { 1892*fcf3ce44SJohn Forte case 0: 1893*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg, 1894*fcf3ce44SJohn Forte "No mailbox active."); 1895*fcf3ce44SJohn Forte return (0); 1896*fcf3ce44SJohn Forte 1897*fcf3ce44SJohn Forte case MBX_POLL: 1898*fcf3ce44SJohn Forte 1899*fcf3ce44SJohn Forte /* 1900*fcf3ce44SJohn Forte * Mark mailbox complete, this should wake up any polling 1901*fcf3ce44SJohn Forte * threads 1902*fcf3ce44SJohn Forte */ 1903*fcf3ce44SJohn Forte /* 1904*fcf3ce44SJohn Forte * This can happen if interrupts are enabled while a polled 1905*fcf3ce44SJohn Forte * mailbox command is outstanding 1906*fcf3ce44SJohn Forte */ 1907*fcf3ce44SJohn Forte /* 1908*fcf3ce44SJohn Forte * If we don't set MBQ_COMPLETED here, the polling thread may 1909*fcf3ce44SJohn Forte * wait until timeout error occurs 1910*fcf3ce44SJohn Forte */ 1911*fcf3ce44SJohn Forte 1912*fcf3ce44SJohn Forte mutex_enter(&EMLXS_MBOX_LOCK); 1913*fcf3ce44SJohn Forte mbq = (MAILBOXQ *) hba->mbox_mbq; 1914*fcf3ce44SJohn Forte if (mbq) { 1915*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 1916*fcf3ce44SJohn Forte "Mailbox event. Completing Polled command."); 1917*fcf3ce44SJohn Forte mbq->flag |= MBQ_COMPLETED; 1918*fcf3ce44SJohn Forte } 1919*fcf3ce44SJohn Forte mutex_exit(&EMLXS_MBOX_LOCK); 1920*fcf3ce44SJohn Forte 1921*fcf3ce44SJohn Forte return (0); 1922*fcf3ce44SJohn Forte 1923*fcf3ce44SJohn Forte case MBX_SLEEP: 1924*fcf3ce44SJohn Forte case MBX_NOWAIT: 1925*fcf3ce44SJohn Forte break; 1926*fcf3ce44SJohn Forte 1927*fcf3ce44SJohn Forte default: 1928*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg, 1929*fcf3ce44SJohn Forte "Invalid Mailbox flag (%x)."); 1930*fcf3ce44SJohn Forte return (0); 1931*fcf3ce44SJohn Forte } 1932*fcf3ce44SJohn Forte 1933*fcf3ce44SJohn Forte /* Get first word of mailbox */ 1934*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1935*fcf3ce44SJohn Forte mbox = FC_SLIM2_MAILBOX(hba); 1936*fcf3ce44SJohn Forte offset = (off_t)((uint64_t)(unsigned long)mbox - 1937*fcf3ce44SJohn Forte (uint64_t)(unsigned long)hba->slim2.virt); 1938*fcf3ce44SJohn Forte 1939*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset, 1940*fcf3ce44SJohn Forte sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL); 1941*fcf3ce44SJohn Forte word0 = *((volatile uint32_t *) mbox); 1942*fcf3ce44SJohn Forte word0 = PCIMEM_LONG(word0); 1943*fcf3ce44SJohn Forte } else { 1944*fcf3ce44SJohn Forte mbox = FC_SLIM1_MAILBOX(hba); 1945*fcf3ce44SJohn Forte word0 = READ_SLIM_ADDR(hba, ((volatile uint32_t *) mbox)); 1946*fcf3ce44SJohn Forte } 1947*fcf3ce44SJohn Forte 1948*fcf3ce44SJohn Forte i = 0; 1949*fcf3ce44SJohn Forte while (swpmb->mbxOwner == OWN_CHIP) { 1950*fcf3ce44SJohn Forte if (i++ > 10000) { 1951*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg, 1952*fcf3ce44SJohn Forte "OWN_CHIP: %s: status=%x", 1953*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(swpmb->mbxCommand), 1954*fcf3ce44SJohn Forte swpmb->mbxStatus); 1955*fcf3ce44SJohn Forte 1956*fcf3ce44SJohn Forte return (1); 1957*fcf3ce44SJohn Forte } 1958*fcf3ce44SJohn Forte /* Get first word of mailbox */ 1959*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1960*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset, 1961*fcf3ce44SJohn Forte sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL); 1962*fcf3ce44SJohn Forte word0 = *((volatile uint32_t *) mbox); 1963*fcf3ce44SJohn Forte word0 = PCIMEM_LONG(word0); 1964*fcf3ce44SJohn Forte } else { 1965*fcf3ce44SJohn Forte word0 = READ_SLIM_ADDR(hba, 1966*fcf3ce44SJohn Forte ((volatile uint32_t *) mbox)); 1967*fcf3ce44SJohn Forte } 1968*fcf3ce44SJohn Forte } 1969*fcf3ce44SJohn Forte 1970*fcf3ce44SJohn Forte /* Now that we are the owner, DMA Sync entire mailbox if needed */ 1971*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1972*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset, 1973*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL); 1974*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)mbox, (uint32_t *)mb, 1975*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE); 1976*fcf3ce44SJohn Forte } else { 1977*fcf3ce44SJohn Forte READ_SLIM_COPY(hba, (uint32_t *)mb, (uint32_t *)mbox, 1978*fcf3ce44SJohn Forte MAILBOX_CMD_WSIZE); 1979*fcf3ce44SJohn Forte } 1980*fcf3ce44SJohn Forte 1981*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 1982*fcf3ce44SJohn Forte if (hba->mbox_ext) { 1983*fcf3ce44SJohn Forte uint32_t *mbox_ext = (uint32_t *)((uint8_t *)mbox + 1984*fcf3ce44SJohn Forte MBOX_EXTENSION_OFFSET); 1985*fcf3ce44SJohn Forte off_t offset_ext = offset + MBOX_EXTENSION_OFFSET; 1986*fcf3ce44SJohn Forte 1987*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1988*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset_ext, 1989*fcf3ce44SJohn Forte hba->mbox_ext_size, DDI_DMA_SYNC_FORKERNEL); 1990*fcf3ce44SJohn Forte emlxs_pcimem_bcopy(mbox_ext, (uint32_t *)hba->mbox_ext, 1991*fcf3ce44SJohn Forte hba->mbox_ext_size); 1992*fcf3ce44SJohn Forte } else { 1993*fcf3ce44SJohn Forte READ_SLIM_COPY(hba, (uint32_t *)hba->mbox_ext, mbox_ext, 1994*fcf3ce44SJohn Forte (hba->mbox_ext_size / 4)); 1995*fcf3ce44SJohn Forte } 1996*fcf3ce44SJohn Forte } 1997*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 1998*fcf3ce44SJohn Forte 1999*fcf3ce44SJohn Forte /* Now sync the memory buffer if one was used */ 2000*fcf3ce44SJohn Forte if (hba->mbox_bp) { 2001*fcf3ce44SJohn Forte mbox_bp = (MATCHMAP *) hba->mbox_bp; 2002*fcf3ce44SJohn Forte emlxs_mpdata_sync(mbox_bp->dma_handle, 0, mbox_bp->size, 2003*fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 2004*fcf3ce44SJohn Forte } 2005*fcf3ce44SJohn Forte /* Mailbox has been completely received at this point */ 2006*fcf3ce44SJohn Forte 2007*fcf3ce44SJohn Forte if (mb->mbxCommand == MBX_HEARTBEAT) { 2008*fcf3ce44SJohn Forte hba->heartbeat_active = 0; 2009*fcf3ce44SJohn Forte goto done; 2010*fcf3ce44SJohn Forte } 2011*fcf3ce44SJohn Forte if (hba->mbox_queue_flag == MBX_SLEEP) { 2012*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2013*fcf3ce44SJohn Forte "Received. %s: status=%x Sleep.", 2014*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(swpmb->mbxCommand), swpmb->mbxStatus); 2015*fcf3ce44SJohn Forte } else { 2016*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2017*fcf3ce44SJohn Forte "Completed. %s: status=%x", 2018*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(swpmb->mbxCommand), swpmb->mbxStatus); 2019*fcf3ce44SJohn Forte } 2020*fcf3ce44SJohn Forte 2021*fcf3ce44SJohn Forte /* Filter out passthru mailbox */ 2022*fcf3ce44SJohn Forte if (hba->mbox_mbqflag & MBQ_PASSTHRU) { 2023*fcf3ce44SJohn Forte goto done; 2024*fcf3ce44SJohn Forte } 2025*fcf3ce44SJohn Forte /* If succesful, process the result */ 2026*fcf3ce44SJohn Forte if (mb->mbxStatus == 0) { 2027*fcf3ce44SJohn Forte (void) emlxs_mb_handle_cmd(hba, mb); 2028*fcf3ce44SJohn Forte goto done; 2029*fcf3ce44SJohn Forte } 2030*fcf3ce44SJohn Forte /* ERROR RETURNED */ 2031*fcf3ce44SJohn Forte 2032*fcf3ce44SJohn Forte /* Check for no resources */ 2033*fcf3ce44SJohn Forte if ((mb->mbxStatus == MBXERR_NO_RESOURCES) && 2034*fcf3ce44SJohn Forte (hba->mbox_queue_flag == MBX_NOWAIT)) { 2035*fcf3ce44SJohn Forte /* Retry only MBX_NOWAIT requests */ 2036*fcf3ce44SJohn Forte 2037*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg, 2038*fcf3ce44SJohn Forte "Retrying. %s: status=%x", 2039*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 2040*fcf3ce44SJohn Forte (uint32_t)mb->mbxStatus); 2041*fcf3ce44SJohn Forte 2042*fcf3ce44SJohn Forte if ((mbox = (MAILBOX *) emlxs_mem_get(hba, MEM_MBOX))) { 2043*fcf3ce44SJohn Forte bcopy((uint8_t *)mb, (uint8_t *)mbox, 2044*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE); 2045*fcf3ce44SJohn Forte 2046*fcf3ce44SJohn Forte switch (mbox->mbxCommand) { 2047*fcf3ce44SJohn Forte case MBX_READ_SPARM: 2048*fcf3ce44SJohn Forte control = mbox->un.varRdSparm.un.sp.bdeSize; 2049*fcf3ce44SJohn Forte if (control == 0) { 2050*fcf3ce44SJohn Forte (void) emlxs_mb_read_sparam(hba, mbox); 2051*fcf3ce44SJohn Forte } 2052*fcf3ce44SJohn Forte break; 2053*fcf3ce44SJohn Forte 2054*fcf3ce44SJohn Forte case MBX_READ_SPARM64: 2055*fcf3ce44SJohn Forte control = mbox->un.varRdSparm.un.sp64.tus.f. 2056*fcf3ce44SJohn Forte bdeSize; 2057*fcf3ce44SJohn Forte if (control == 0) { 2058*fcf3ce44SJohn Forte (void) emlxs_mb_read_sparam(hba, mbox); 2059*fcf3ce44SJohn Forte } 2060*fcf3ce44SJohn Forte break; 2061*fcf3ce44SJohn Forte 2062*fcf3ce44SJohn Forte case MBX_REG_LOGIN: 2063*fcf3ce44SJohn Forte control = mbox->un.varRegLogin.un.sp.bdeSize; 2064*fcf3ce44SJohn Forte if (control == 0) { 2065*fcf3ce44SJohn Forte goto done; 2066*fcf3ce44SJohn Forte } 2067*fcf3ce44SJohn Forte break; 2068*fcf3ce44SJohn Forte 2069*fcf3ce44SJohn Forte case MBX_REG_LOGIN64: 2070*fcf3ce44SJohn Forte control = mbox->un.varRegLogin.un.sp64.tus.f. 2071*fcf3ce44SJohn Forte bdeSize; 2072*fcf3ce44SJohn Forte if (control == 0) { 2073*fcf3ce44SJohn Forte goto done; 2074*fcf3ce44SJohn Forte } 2075*fcf3ce44SJohn Forte break; 2076*fcf3ce44SJohn Forte 2077*fcf3ce44SJohn Forte case MBX_READ_LA: 2078*fcf3ce44SJohn Forte control = mbox->un.varReadLA.un.lilpBde.bdeSize; 2079*fcf3ce44SJohn Forte if (control == 0) { 2080*fcf3ce44SJohn Forte (void) emlxs_mb_read_la(hba, mbox); 2081*fcf3ce44SJohn Forte } 2082*fcf3ce44SJohn Forte break; 2083*fcf3ce44SJohn Forte 2084*fcf3ce44SJohn Forte case MBX_READ_LA64: 2085*fcf3ce44SJohn Forte control = mbox->un.varReadLA.un.lilpBde64.tus.f. 2086*fcf3ce44SJohn Forte bdeSize; 2087*fcf3ce44SJohn Forte if (control == 0) { 2088*fcf3ce44SJohn Forte (void) emlxs_mb_read_la(hba, mbox); 2089*fcf3ce44SJohn Forte } 2090*fcf3ce44SJohn Forte break; 2091*fcf3ce44SJohn Forte } 2092*fcf3ce44SJohn Forte 2093*fcf3ce44SJohn Forte mbox->mbxOwner = OWN_HOST; 2094*fcf3ce44SJohn Forte mbox->mbxStatus = 0; 2095*fcf3ce44SJohn Forte 2096*fcf3ce44SJohn Forte /* Refresh the mailbox area */ 2097*fcf3ce44SJohn Forte emlxs_mb_retry(hba, mbox); 2098*fcf3ce44SJohn Forte 2099*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mbox, MBX_NOWAIT, 0) != 2100*fcf3ce44SJohn Forte MBX_BUSY) { 2101*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, 2102*fcf3ce44SJohn Forte (uint8_t *)mbox); 2103*fcf3ce44SJohn Forte } 2104*fcf3ce44SJohn Forte return (0); 2105*fcf3ce44SJohn Forte } 2106*fcf3ce44SJohn Forte } 2107*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg, 2108*fcf3ce44SJohn Forte "%s: status=0x%x", emlxs_mb_cmd_xlate(mb->mbxCommand), 2109*fcf3ce44SJohn Forte (uint32_t)mb->mbxStatus); 2110*fcf3ce44SJohn Forte 2111*fcf3ce44SJohn Forte /* 2112*fcf3ce44SJohn Forte * ERROR: process mailbox command error 2113*fcf3ce44SJohn Forte */ 2114*fcf3ce44SJohn Forte switch (mb->mbxCommand) { 2115*fcf3ce44SJohn Forte case MBX_REG_LOGIN: 2116*fcf3ce44SJohn Forte case MBX_REG_LOGIN64: 2117*fcf3ce44SJohn Forte 2118*fcf3ce44SJohn Forte if (mb->mbxStatus == MBXERR_RPI_FULL) { 2119*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 2120*fcf3ce44SJohn Forte port = &VPORT(mb->un.varRegLogin.vpi); 2121*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 2122*fcf3ce44SJohn Forte 2123*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg, 2124*fcf3ce44SJohn Forte "Limit reached. count=%d", port->node_count); 2125*fcf3ce44SJohn Forte } 2126*fcf3ce44SJohn Forte break; 2127*fcf3ce44SJohn Forte 2128*fcf3ce44SJohn Forte case MBX_READ_LA: 2129*fcf3ce44SJohn Forte case MBX_READ_LA64: 2130*fcf3ce44SJohn Forte 2131*fcf3ce44SJohn Forte /* Enable Link Attention interrupts */ 2132*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2133*fcf3ce44SJohn Forte 2134*fcf3ce44SJohn Forte if (!(hba->hc_copy & HC_LAINT_ENA)) { 2135*fcf3ce44SJohn Forte /* 2136*fcf3ce44SJohn Forte * hba->hc_copy = READ_CSR_REG(hba, FC_HC_REG(hba, 2137*fcf3ce44SJohn Forte * hba->csr_addr)); 2138*fcf3ce44SJohn Forte */ 2139*fcf3ce44SJohn Forte hba->hc_copy |= HC_LAINT_ENA; 2140*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, FC_HC_REG(hba, hba->csr_addr), 2141*fcf3ce44SJohn Forte hba->hc_copy); 2142*fcf3ce44SJohn Forte } 2143*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2144*fcf3ce44SJohn Forte 2145*fcf3ce44SJohn Forte break; 2146*fcf3ce44SJohn Forte 2147*fcf3ce44SJohn Forte 2148*fcf3ce44SJohn Forte case MBX_CLEAR_LA: 2149*fcf3ce44SJohn Forte 2150*fcf3ce44SJohn Forte la_enable = 1; 2151*fcf3ce44SJohn Forte 2152*fcf3ce44SJohn Forte if (mb->mbxStatus == 0x1601) { 2153*fcf3ce44SJohn Forte /* 2154*fcf3ce44SJohn Forte * Get a buffer which will be used for mailbox 2155*fcf3ce44SJohn Forte * commands 2156*fcf3ce44SJohn Forte */ 2157*fcf3ce44SJohn Forte if ((mbox = (MAILBOX *) emlxs_mem_get(hba, MEM_MBOX | 2158*fcf3ce44SJohn Forte MEM_PRI))) { 2159*fcf3ce44SJohn Forte /* Get link attention message */ 2160*fcf3ce44SJohn Forte if (emlxs_mb_read_la(hba, mbox) == 0) { 2161*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mbox, 2162*fcf3ce44SJohn Forte MBX_NOWAIT, 0) != MBX_BUSY) { 2163*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, 2164*fcf3ce44SJohn Forte MEM_MBOX, (uint8_t *)mbox); 2165*fcf3ce44SJohn Forte } 2166*fcf3ce44SJohn Forte la_enable = 0; 2167*fcf3ce44SJohn Forte } else { 2168*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, 2169*fcf3ce44SJohn Forte (uint8_t *)mbox); 2170*fcf3ce44SJohn Forte } 2171*fcf3ce44SJohn Forte } 2172*fcf3ce44SJohn Forte } 2173*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2174*fcf3ce44SJohn Forte if (la_enable) { 2175*fcf3ce44SJohn Forte if (!(hba->hc_copy & HC_LAINT_ENA)) { 2176*fcf3ce44SJohn Forte /* Enable Link Attention interrupts */ 2177*fcf3ce44SJohn Forte /* 2178*fcf3ce44SJohn Forte * hba->hc_copy = READ_CSR_REG(hba, 2179*fcf3ce44SJohn Forte * FC_HC_REG(hba, hba->csr_addr)); 2180*fcf3ce44SJohn Forte */ 2181*fcf3ce44SJohn Forte hba->hc_copy |= HC_LAINT_ENA; 2182*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, 2183*fcf3ce44SJohn Forte FC_HC_REG(hba, hba->csr_addr), 2184*fcf3ce44SJohn Forte hba->hc_copy); 2185*fcf3ce44SJohn Forte } 2186*fcf3ce44SJohn Forte } else { 2187*fcf3ce44SJohn Forte if (hba->hc_copy & HC_LAINT_ENA) { 2188*fcf3ce44SJohn Forte /* Disable Link Attention interrupts */ 2189*fcf3ce44SJohn Forte /* 2190*fcf3ce44SJohn Forte * hba->hc_copy = READ_CSR_REG(hba, 2191*fcf3ce44SJohn Forte * FC_HC_REG(hba, hba->csr_addr)); 2192*fcf3ce44SJohn Forte */ 2193*fcf3ce44SJohn Forte hba->hc_copy &= ~HC_LAINT_ENA; 2194*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, 2195*fcf3ce44SJohn Forte FC_HC_REG(hba, hba->csr_addr), 2196*fcf3ce44SJohn Forte hba->hc_copy); 2197*fcf3ce44SJohn Forte } 2198*fcf3ce44SJohn Forte } 2199*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2200*fcf3ce44SJohn Forte 2201*fcf3ce44SJohn Forte break; 2202*fcf3ce44SJohn Forte 2203*fcf3ce44SJohn Forte case MBX_INIT_LINK: 2204*fcf3ce44SJohn Forte if ((hba->flag & FC_SLIM2_MODE) && 2205*fcf3ce44SJohn Forte (hba->mbox_queue_flag == MBX_NOWAIT)) { 2206*fcf3ce44SJohn Forte /* Retry only MBX_NOWAIT requests */ 2207*fcf3ce44SJohn Forte 2208*fcf3ce44SJohn Forte if ((cfg[CFG_LINK_SPEED].current > 0) && 2209*fcf3ce44SJohn Forte ((mb->mbxStatus == 0x0011) || 2210*fcf3ce44SJohn Forte (mb->mbxStatus == 0x0500))) { 2211*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg, 2212*fcf3ce44SJohn Forte "Retrying. %s: status=%x. Auto-speed set.", 2213*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 2214*fcf3ce44SJohn Forte (uint32_t)mb->mbxStatus); 2215*fcf3ce44SJohn Forte 2216*fcf3ce44SJohn Forte if ((mbox = (MAILBOX *) emlxs_mem_get(hba, 2217*fcf3ce44SJohn Forte MEM_MBOX))) { 2218*fcf3ce44SJohn Forte bcopy((uint8_t *)mb, (uint8_t *)mbox, 2219*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE); 2220*fcf3ce44SJohn Forte 2221*fcf3ce44SJohn Forte mbox->un.varInitLnk.link_flags &= 2222*fcf3ce44SJohn Forte ~FLAGS_LINK_SPEED; 2223*fcf3ce44SJohn Forte mbox->un.varInitLnk.link_speed = 0; 2224*fcf3ce44SJohn Forte mbox->mbxOwner = OWN_HOST; 2225*fcf3ce44SJohn Forte mbox->mbxStatus = 0; 2226*fcf3ce44SJohn Forte 2227*fcf3ce44SJohn Forte /* Refresh the mailbox area */ 2228*fcf3ce44SJohn Forte emlxs_mb_retry(hba, mbox); 2229*fcf3ce44SJohn Forte 2230*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mbox, 2231*fcf3ce44SJohn Forte MBX_NOWAIT, 0) != MBX_BUSY) { 2232*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, 2233*fcf3ce44SJohn Forte MEM_MBOX, (uint8_t *)mbox); 2234*fcf3ce44SJohn Forte } 2235*fcf3ce44SJohn Forte return (0); 2236*fcf3ce44SJohn Forte } 2237*fcf3ce44SJohn Forte } 2238*fcf3ce44SJohn Forte } 2239*fcf3ce44SJohn Forte break; 2240*fcf3ce44SJohn Forte } 2241*fcf3ce44SJohn Forte 2242*fcf3ce44SJohn Forte done: 2243*fcf3ce44SJohn Forte 2244*fcf3ce44SJohn Forte /* Clean up the mailbox area */ 2245*fcf3ce44SJohn Forte emlxs_mb_fini(hba, mb, mb->mbxStatus); 2246*fcf3ce44SJohn Forte 2247*fcf3ce44SJohn Forte /* Attempt to send pending mailboxes */ 2248*fcf3ce44SJohn Forte if ((mbox = (MAILBOX *) emlxs_mb_get(hba))) { 2249*fcf3ce44SJohn Forte if (emlxs_mb_issue_cmd(hba, mbox, MBX_NOWAIT, 0) != MBX_BUSY) { 2250*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox); 2251*fcf3ce44SJohn Forte } 2252*fcf3ce44SJohn Forte } 2253*fcf3ce44SJohn Forte return (0); 2254*fcf3ce44SJohn Forte 2255*fcf3ce44SJohn Forte } /* emlxs_handle_mb_event() */ 2256*fcf3ce44SJohn Forte 2257*fcf3ce44SJohn Forte 2258*fcf3ce44SJohn Forte 2259*fcf3ce44SJohn Forte /* 2260*fcf3ce44SJohn Forte * emlxs_mb_handle_cmd 2261*fcf3ce44SJohn Forte * 2262*fcf3ce44SJohn Forte * Description: Process a Mailbox Command. 2263*fcf3ce44SJohn Forte * Called from host_interrupt to process MBATT 2264*fcf3ce44SJohn Forte * 2265*fcf3ce44SJohn Forte * Returns: 2266*fcf3ce44SJohn Forte * 2267*fcf3ce44SJohn Forte */ 2268*fcf3ce44SJohn Forte static int 2269*fcf3ce44SJohn Forte emlxs_mb_handle_cmd(emlxs_hba_t *hba, MAILBOX *mb) 2270*fcf3ce44SJohn Forte { 2271*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2272*fcf3ce44SJohn Forte emlxs_port_t *vport; 2273*fcf3ce44SJohn Forte MAILBOXQ *mbox; 2274*fcf3ce44SJohn Forte NODELIST *ndlp; 2275*fcf3ce44SJohn Forte volatile SERV_PARM *sp; 2276*fcf3ce44SJohn Forte int32_t i; 2277*fcf3ce44SJohn Forte uint32_t ldata; 2278*fcf3ce44SJohn Forte uint32_t ldid; 2279*fcf3ce44SJohn Forte uint16_t lrpi; 2280*fcf3ce44SJohn Forte uint16_t lvpi; 2281*fcf3ce44SJohn Forte MATCHMAP *mp; 2282*fcf3ce44SJohn Forte uint8_t *wwn; 2283*fcf3ce44SJohn Forte READ_LA_VAR la; 2284*fcf3ce44SJohn Forte 2285*fcf3ce44SJohn Forte if (mb->mbxStatus != 0) { 2286*fcf3ce44SJohn Forte return (1); 2287*fcf3ce44SJohn Forte } 2288*fcf3ce44SJohn Forte mp = (MATCHMAP *) hba->mbox_bp; 2289*fcf3ce44SJohn Forte 2290*fcf3ce44SJohn Forte /* 2291*fcf3ce44SJohn Forte * Mailbox command completed successfully, process completion 2292*fcf3ce44SJohn Forte */ 2293*fcf3ce44SJohn Forte switch (mb->mbxCommand) { 2294*fcf3ce44SJohn Forte case MBX_SHUTDOWN: 2295*fcf3ce44SJohn Forte case MBX_LOAD_SM: 2296*fcf3ce44SJohn Forte case MBX_READ_NV: 2297*fcf3ce44SJohn Forte case MBX_WRITE_NV: 2298*fcf3ce44SJohn Forte case MBX_RUN_BIU_DIAG: 2299*fcf3ce44SJohn Forte case MBX_RUN_BIU_DIAG64: 2300*fcf3ce44SJohn Forte case MBX_INIT_LINK: 2301*fcf3ce44SJohn Forte case MBX_DOWN_LINK: 2302*fcf3ce44SJohn Forte case MBX_CONFIG_LINK: 2303*fcf3ce44SJohn Forte case MBX_PART_SLIM: 2304*fcf3ce44SJohn Forte case MBX_CONFIG_RING: 2305*fcf3ce44SJohn Forte case MBX_RESET_RING: 2306*fcf3ce44SJohn Forte case MBX_READ_CONFIG: 2307*fcf3ce44SJohn Forte case MBX_READ_RCONFIG: 2308*fcf3ce44SJohn Forte case MBX_READ_STATUS: 2309*fcf3ce44SJohn Forte case MBX_READ_XRI: 2310*fcf3ce44SJohn Forte case MBX_READ_REV: 2311*fcf3ce44SJohn Forte case MBX_READ_LNK_STAT: 2312*fcf3ce44SJohn Forte case MBX_UNREG_LOGIN: 2313*fcf3ce44SJohn Forte case MBX_DUMP_MEMORY: 2314*fcf3ce44SJohn Forte case MBX_DUMP_CONTEXT: 2315*fcf3ce44SJohn Forte case MBX_RUN_DIAGS: 2316*fcf3ce44SJohn Forte case MBX_RESTART: 2317*fcf3ce44SJohn Forte case MBX_UPDATE_CFG: 2318*fcf3ce44SJohn Forte case MBX_DOWN_LOAD: 2319*fcf3ce44SJohn Forte case MBX_DEL_LD_ENTRY: 2320*fcf3ce44SJohn Forte case MBX_RUN_PROGRAM: 2321*fcf3ce44SJohn Forte case MBX_SET_MASK: 2322*fcf3ce44SJohn Forte case MBX_SET_VARIABLE: 2323*fcf3ce44SJohn Forte case MBX_UNREG_D_ID: 2324*fcf3ce44SJohn Forte case MBX_KILL_BOARD: 2325*fcf3ce44SJohn Forte case MBX_CONFIG_FARP: 2326*fcf3ce44SJohn Forte case MBX_LOAD_AREA: 2327*fcf3ce44SJohn Forte case MBX_CONFIG_PORT: 2328*fcf3ce44SJohn Forte case MBX_CONFIG_MSI: 2329*fcf3ce44SJohn Forte case MBX_FLASH_WR_ULA: 2330*fcf3ce44SJohn Forte case MBX_SET_DEBUG: 2331*fcf3ce44SJohn Forte case MBX_GET_DEBUG: 2332*fcf3ce44SJohn Forte case MBX_LOAD_EXP_ROM: 2333*fcf3ce44SJohn Forte case MBX_BEACON: 2334*fcf3ce44SJohn Forte case MBX_READ_RPI: 2335*fcf3ce44SJohn Forte case MBX_READ_RPI64: 2336*fcf3ce44SJohn Forte case MBX_REG_VPI: 2337*fcf3ce44SJohn Forte case MBX_UNREG_VPI: 2338*fcf3ce44SJohn Forte case MBX_CONFIG_HBQ: 2339*fcf3ce44SJohn Forte case MBX_ASYNC_EVENT: 2340*fcf3ce44SJohn Forte case MBX_HEARTBEAT: 2341*fcf3ce44SJohn Forte break; 2342*fcf3ce44SJohn Forte 2343*fcf3ce44SJohn Forte case MBX_CONFIG_MSIX: 2344*fcf3ce44SJohn Forte break; 2345*fcf3ce44SJohn Forte 2346*fcf3ce44SJohn Forte case MBX_READ_SPARM: /* a READ SPARAM command completed */ 2347*fcf3ce44SJohn Forte case MBX_READ_SPARM64: /* a READ SPARAM command completed */ 2348*fcf3ce44SJohn Forte { 2349*fcf3ce44SJohn Forte if (mp) { 2350*fcf3ce44SJohn Forte bcopy((caddr_t)mp->virt, (caddr_t)& hba->sparam, 2351*fcf3ce44SJohn Forte sizeof (SERV_PARM)); 2352*fcf3ce44SJohn Forte 2353*fcf3ce44SJohn Forte bcopy((caddr_t)& hba->sparam.nodeName, 2354*fcf3ce44SJohn Forte (caddr_t)& hba->wwnn, 2355*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2356*fcf3ce44SJohn Forte 2357*fcf3ce44SJohn Forte bcopy((caddr_t)& hba->sparam.portName, 2358*fcf3ce44SJohn Forte (caddr_t)& hba->wwpn, 2359*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2360*fcf3ce44SJohn Forte 2361*fcf3ce44SJohn Forte /* Initialize the physical port */ 2362*fcf3ce44SJohn Forte bcopy((caddr_t)& hba->sparam, 2363*fcf3ce44SJohn Forte (caddr_t)& port->sparam, 2364*fcf3ce44SJohn Forte sizeof (SERV_PARM)); 2365*fcf3ce44SJohn Forte bcopy((caddr_t)& hba->wwpn, 2366*fcf3ce44SJohn Forte (caddr_t)& port->wwpn, sizeof (NAME_TYPE)); 2367*fcf3ce44SJohn Forte bcopy((caddr_t)& hba->wwnn, 2368*fcf3ce44SJohn Forte (caddr_t)& port->wwnn, sizeof (NAME_TYPE)); 2369*fcf3ce44SJohn Forte 2370*fcf3ce44SJohn Forte /* Initialize the virtual ports */ 2371*fcf3ce44SJohn Forte for (i = 1; i < MAX_VPORTS; i++) { 2372*fcf3ce44SJohn Forte vport = &VPORT(i); 2373*fcf3ce44SJohn Forte if (vport->flag & EMLXS_PORT_BOUND) { 2374*fcf3ce44SJohn Forte continue; 2375*fcf3ce44SJohn Forte } 2376*fcf3ce44SJohn Forte bcopy((caddr_t)& hba->sparam, 2377*fcf3ce44SJohn Forte (caddr_t)& vport->sparam, 2378*fcf3ce44SJohn Forte sizeof (SERV_PARM)); 2379*fcf3ce44SJohn Forte 2380*fcf3ce44SJohn Forte bcopy((caddr_t)& vport->wwnn, 2381*fcf3ce44SJohn Forte (caddr_t)& vport->sparam.nodeName, 2382*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2383*fcf3ce44SJohn Forte 2384*fcf3ce44SJohn Forte bcopy((caddr_t)& vport->wwpn, 2385*fcf3ce44SJohn Forte (caddr_t)& vport->sparam.portName, 2386*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2387*fcf3ce44SJohn Forte } 2388*fcf3ce44SJohn Forte 2389*fcf3ce44SJohn Forte } 2390*fcf3ce44SJohn Forte break; 2391*fcf3ce44SJohn Forte } 2392*fcf3ce44SJohn Forte 2393*fcf3ce44SJohn Forte 2394*fcf3ce44SJohn Forte case MBX_REG_LOGIN: 2395*fcf3ce44SJohn Forte case MBX_REG_LOGIN64: 2396*fcf3ce44SJohn Forte 2397*fcf3ce44SJohn Forte if (!mp) { 2398*fcf3ce44SJohn Forte break; 2399*fcf3ce44SJohn Forte } 2400*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 2401*fcf3ce44SJohn Forte ldata = mb->un.varWords[5]; 2402*fcf3ce44SJohn Forte lvpi = ldata & 0xffff; 2403*fcf3ce44SJohn Forte port = &VPORT(lvpi); 2404*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 2405*fcf3ce44SJohn Forte 2406*fcf3ce44SJohn Forte /* First copy command data */ 2407*fcf3ce44SJohn Forte ldata = mb->un.varWords[0]; /* get rpi */ 2408*fcf3ce44SJohn Forte lrpi = ldata & 0xffff; 2409*fcf3ce44SJohn Forte 2410*fcf3ce44SJohn Forte ldata = mb->un.varWords[1]; /* get did */ 2411*fcf3ce44SJohn Forte ldid = ldata & Mask_DID; 2412*fcf3ce44SJohn Forte 2413*fcf3ce44SJohn Forte sp = (volatile SERV_PARM *) mp->virt; 2414*fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, ldid); 2415*fcf3ce44SJohn Forte 2416*fcf3ce44SJohn Forte if (!ndlp) { 2417*fcf3ce44SJohn Forte /* Attempt to create a node */ 2418*fcf3ce44SJohn Forte if ((ndlp = (NODELIST *) emlxs_mem_get(hba, MEM_NLP))) { 2419*fcf3ce44SJohn Forte ndlp->nlp_Rpi = lrpi; 2420*fcf3ce44SJohn Forte ndlp->nlp_DID = ldid; 2421*fcf3ce44SJohn Forte 2422*fcf3ce44SJohn Forte bcopy((uint8_t *)sp, 2423*fcf3ce44SJohn Forte (uint8_t *)& ndlp->sparm, 2424*fcf3ce44SJohn Forte sizeof (SERV_PARM)); 2425*fcf3ce44SJohn Forte 2426*fcf3ce44SJohn Forte bcopy((uint8_t *)& sp->nodeName, 2427*fcf3ce44SJohn Forte (uint8_t *)& ndlp->nlp_nodename, 2428*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2429*fcf3ce44SJohn Forte 2430*fcf3ce44SJohn Forte bcopy((uint8_t *)& sp->portName, 2431*fcf3ce44SJohn Forte (uint8_t *)& ndlp->nlp_portname, 2432*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2433*fcf3ce44SJohn Forte 2434*fcf3ce44SJohn Forte ndlp->nlp_active = 1; 2435*fcf3ce44SJohn Forte ndlp->nlp_flag[FC_CT_RING] |= NLP_CLOSED; 2436*fcf3ce44SJohn Forte ndlp->nlp_flag[FC_ELS_RING] |= NLP_CLOSED; 2437*fcf3ce44SJohn Forte ndlp->nlp_flag[FC_FCP_RING] |= NLP_CLOSED; 2438*fcf3ce44SJohn Forte ndlp->nlp_flag[FC_IP_RING] |= NLP_CLOSED; 2439*fcf3ce44SJohn Forte 2440*fcf3ce44SJohn Forte /* Add the node */ 2441*fcf3ce44SJohn Forte emlxs_node_add(port, ndlp); 2442*fcf3ce44SJohn Forte 2443*fcf3ce44SJohn Forte /* Open the node */ 2444*fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, FC_CT_RING); 2445*fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, FC_ELS_RING); 2446*fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, FC_IP_RING); 2447*fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, FC_FCP_RING); 2448*fcf3ce44SJohn Forte } else { 2449*fcf3ce44SJohn Forte wwn = (uint8_t *)& sp->portName; 2450*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2451*fcf3ce44SJohn Forte &emlxs_node_create_failed_msg, 2452*fcf3ce44SJohn Forte "Unable to allocate node. did=%06x rpi=%x " 2453*fcf3ce44SJohn Forte "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x", 2454*fcf3ce44SJohn Forte ldid, lrpi, wwn[0], wwn[1], wwn[2], wwn[3], 2455*fcf3ce44SJohn Forte wwn[4], wwn[5], wwn[6], wwn[7]); 2456*fcf3ce44SJohn Forte 2457*fcf3ce44SJohn Forte break; 2458*fcf3ce44SJohn Forte } 2459*fcf3ce44SJohn Forte } else { 2460*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2461*fcf3ce44SJohn Forte 2462*fcf3ce44SJohn Forte ndlp->nlp_Rpi = lrpi; 2463*fcf3ce44SJohn Forte ndlp->nlp_DID = ldid; 2464*fcf3ce44SJohn Forte 2465*fcf3ce44SJohn Forte bcopy((uint8_t *)sp, 2466*fcf3ce44SJohn Forte (uint8_t *)& ndlp->sparm, 2467*fcf3ce44SJohn Forte sizeof (SERV_PARM)); 2468*fcf3ce44SJohn Forte 2469*fcf3ce44SJohn Forte bcopy((uint8_t *)& sp->nodeName, 2470*fcf3ce44SJohn Forte (uint8_t *)& ndlp->nlp_nodename, 2471*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2472*fcf3ce44SJohn Forte 2473*fcf3ce44SJohn Forte bcopy((uint8_t *)& sp->portName, 2474*fcf3ce44SJohn Forte (uint8_t *)& ndlp->nlp_portname, 2475*fcf3ce44SJohn Forte sizeof (NAME_TYPE)); 2476*fcf3ce44SJohn Forte 2477*fcf3ce44SJohn Forte wwn = (uint8_t *)& ndlp->nlp_portname; 2478*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_update_msg, 2479*fcf3ce44SJohn Forte "node=%p did=%06x rpi=%x wwpn=" 2480*fcf3ce44SJohn Forte "%02x%02x%02x%02x%02x%02x%02x%02x", 2481*fcf3ce44SJohn Forte ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0], wwn[1], 2482*fcf3ce44SJohn Forte wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]); 2483*fcf3ce44SJohn Forte 2484*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2485*fcf3ce44SJohn Forte 2486*fcf3ce44SJohn Forte /* Open the node */ 2487*fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, FC_CT_RING); 2488*fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, FC_ELS_RING); 2489*fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, FC_IP_RING); 2490*fcf3ce44SJohn Forte emlxs_node_open(port, ndlp, FC_FCP_RING); 2491*fcf3ce44SJohn Forte } 2492*fcf3ce44SJohn Forte 2493*fcf3ce44SJohn Forte /* If this was a fabric login */ 2494*fcf3ce44SJohn Forte if (ndlp->nlp_DID == Fabric_DID) { 2495*fcf3ce44SJohn Forte /* 2496*fcf3ce44SJohn Forte * If CLEAR_LA has been sent, then attempt to 2497*fcf3ce44SJohn Forte * register the vpi now 2498*fcf3ce44SJohn Forte */ 2499*fcf3ce44SJohn Forte if (hba->state == FC_READY) { 2500*fcf3ce44SJohn Forte (void) emlxs_mb_reg_vpi(port); 2501*fcf3ce44SJohn Forte } 2502*fcf3ce44SJohn Forte #ifdef SLI3_SUPPORT 2503*fcf3ce44SJohn Forte /* 2504*fcf3ce44SJohn Forte * If NPIV Fabric support has just been established 2505*fcf3ce44SJohn Forte * on the physical port, then notify the vports of 2506*fcf3ce44SJohn Forte * the link up 2507*fcf3ce44SJohn Forte */ 2508*fcf3ce44SJohn Forte if ((lvpi == 0) && 2509*fcf3ce44SJohn Forte (hba->flag & FC_NPIV_ENABLED) && 2510*fcf3ce44SJohn Forte (hba->flag & FC_NPIV_SUPPORTED)) { 2511*fcf3ce44SJohn Forte /* Skip the physical port */ 2512*fcf3ce44SJohn Forte for (i = 1; i < MAX_VPORTS; i++) { 2513*fcf3ce44SJohn Forte vport = &VPORT(i); 2514*fcf3ce44SJohn Forte 2515*fcf3ce44SJohn Forte if (!(vport->flag & EMLXS_PORT_BOUND) || 2516*fcf3ce44SJohn Forte !(vport->flag & 2517*fcf3ce44SJohn Forte EMLXS_PORT_ENABLE)) { 2518*fcf3ce44SJohn Forte continue; 2519*fcf3ce44SJohn Forte } 2520*fcf3ce44SJohn Forte emlxs_port_online(vport); 2521*fcf3ce44SJohn Forte } 2522*fcf3ce44SJohn Forte } 2523*fcf3ce44SJohn Forte #endif /* SLI3_SUPPORT */ 2524*fcf3ce44SJohn Forte 2525*fcf3ce44SJohn Forte } 2526*fcf3ce44SJohn Forte #ifdef NPIV_SUPPORT 2527*fcf3ce44SJohn Forte if (hba->mbox_iocbq == (uint8_t *)1) { 2528*fcf3ce44SJohn Forte hba->mbox_iocbq = NULL; 2529*fcf3ce44SJohn Forte (void) emlxs_mb_unreg_did(port, ldid, NULL, NULL, NULL); 2530*fcf3ce44SJohn Forte } 2531*fcf3ce44SJohn Forte #endif /* NPIV_SUPPORT */ 2532*fcf3ce44SJohn Forte 2533*fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 2534*fcf3ce44SJohn Forte if (hba->mbox_sbp || hba->mbox_ubp) { 2535*fcf3ce44SJohn Forte if (emlxs_dhc_auth_start(port, ndlp, hba->mbox_sbp, 2536*fcf3ce44SJohn Forte hba->mbox_ubp) == 0) { 2537*fcf3ce44SJohn Forte /* 2538*fcf3ce44SJohn Forte * Auth started - auth completion will handle 2539*fcf3ce44SJohn Forte * sbp and ubp now 2540*fcf3ce44SJohn Forte */ 2541*fcf3ce44SJohn Forte hba->mbox_sbp = NULL; 2542*fcf3ce44SJohn Forte hba->mbox_ubp = NULL; 2543*fcf3ce44SJohn Forte } 2544*fcf3ce44SJohn Forte } 2545*fcf3ce44SJohn Forte #endif /* DHCHAP_SUPPORT */ 2546*fcf3ce44SJohn Forte 2547*fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 2548*fcf3ce44SJohn Forte if (hba->mbox_sbp && ((emlxs_buf_t *)hba->mbox_sbp)->fct_cmd) { 2549*fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)hba->mbox_sbp; 2550*fcf3ce44SJohn Forte 2551*fcf3ce44SJohn Forte if (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING) { 2552*fcf3ce44SJohn Forte hba->mbox_sbp = NULL; 2553*fcf3ce44SJohn Forte 2554*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PKT_LOCK); 2555*fcf3ce44SJohn Forte cmd_sbp->node = ndlp; 2556*fcf3ce44SJohn Forte cmd_sbp->fct_state = EMLXS_FCT_REG_COMPLETE; 2557*fcf3ce44SJohn Forte cv_broadcast(&EMLXS_PKT_CV); 2558*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PKT_LOCK); 2559*fcf3ce44SJohn Forte } 2560*fcf3ce44SJohn Forte } 2561*fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 2562*fcf3ce44SJohn Forte 2563*fcf3ce44SJohn Forte break; 2564*fcf3ce44SJohn Forte 2565*fcf3ce44SJohn Forte case MBX_READ_LA: 2566*fcf3ce44SJohn Forte case MBX_READ_LA64: 2567*fcf3ce44SJohn Forte bcopy((uint32_t *)((char *)mb + sizeof (uint32_t)), 2568*fcf3ce44SJohn Forte (uint32_t *)& la, sizeof (READ_LA_VAR)); 2569*fcf3ce44SJohn Forte 2570*fcf3ce44SJohn Forte if (mp) { 2571*fcf3ce44SJohn Forte bcopy((caddr_t)mp->virt, 2572*fcf3ce44SJohn Forte (caddr_t)port->alpa_map, 128); 2573*fcf3ce44SJohn Forte } else { 2574*fcf3ce44SJohn Forte bzero((caddr_t)port->alpa_map, 128); 2575*fcf3ce44SJohn Forte } 2576*fcf3ce44SJohn Forte 2577*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_atten_msg, 2578*fcf3ce44SJohn Forte "type=%s tag=%d -> %d ALPA=%x", 2579*fcf3ce44SJohn Forte ((la.attType == AT_LINK_UP) ? 2580*fcf3ce44SJohn Forte "LinkUp" : "LinkDown"), 2581*fcf3ce44SJohn Forte (uint32_t)hba->link_event_tag, 2582*fcf3ce44SJohn Forte (uint32_t)la.eventTag, (uint32_t)la.granted_AL_PA); 2583*fcf3ce44SJohn Forte 2584*fcf3ce44SJohn Forte if (la.pb) { 2585*fcf3ce44SJohn Forte hba->flag |= FC_BYPASSED_MODE; 2586*fcf3ce44SJohn Forte } else { 2587*fcf3ce44SJohn Forte hba->flag &= ~FC_BYPASSED_MODE; 2588*fcf3ce44SJohn Forte } 2589*fcf3ce44SJohn Forte 2590*fcf3ce44SJohn Forte if (hba->link_event_tag == la.eventTag) { 2591*fcf3ce44SJohn Forte HBASTATS.LinkMultiEvent++; 2592*fcf3ce44SJohn Forte } else if (hba->link_event_tag + 1 < la.eventTag) { 2593*fcf3ce44SJohn Forte HBASTATS.LinkMultiEvent++; 2594*fcf3ce44SJohn Forte 2595*fcf3ce44SJohn Forte if (hba->state > FC_LINK_DOWN) { 2596*fcf3ce44SJohn Forte /* Declare link down here */ 2597*fcf3ce44SJohn Forte emlxs_linkdown(hba); 2598*fcf3ce44SJohn Forte } 2599*fcf3ce44SJohn Forte } 2600*fcf3ce44SJohn Forte hba->link_event_tag = la.eventTag; 2601*fcf3ce44SJohn Forte port->lip_type = 0; 2602*fcf3ce44SJohn Forte 2603*fcf3ce44SJohn Forte /* If link not already up then declare it up now */ 2604*fcf3ce44SJohn Forte if ((la.attType == AT_LINK_UP) && 2605*fcf3ce44SJohn Forte (hba->state < FC_LINK_UP)) { 2606*fcf3ce44SJohn Forte 2607*fcf3ce44SJohn Forte /* Save the linkspeed */ 2608*fcf3ce44SJohn Forte hba->linkspeed = la.UlnkSpeed; 2609*fcf3ce44SJohn Forte 2610*fcf3ce44SJohn Forte /* 2611*fcf3ce44SJohn Forte * Check for old model adapters that only 2612*fcf3ce44SJohn Forte * supported 1Gb 2613*fcf3ce44SJohn Forte */ 2614*fcf3ce44SJohn Forte if ((hba->linkspeed == 0) && 2615*fcf3ce44SJohn Forte (hba->model_info.chip & 2616*fcf3ce44SJohn Forte EMLXS_DRAGONFLY_CHIP)) { 2617*fcf3ce44SJohn Forte hba->linkspeed = LA_1GHZ_LINK; 2618*fcf3ce44SJohn Forte } 2619*fcf3ce44SJohn Forte if ((hba->topology = la.topology) == 2620*fcf3ce44SJohn Forte TOPOLOGY_LOOP) { 2621*fcf3ce44SJohn Forte port->did = la.granted_AL_PA; 2622*fcf3ce44SJohn Forte port->lip_type = la.lipType; 2623*fcf3ce44SJohn Forte 2624*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 2625*fcf3ce44SJohn Forte i = la.un.lilpBde64.tus.f. 2626*fcf3ce44SJohn Forte bdeSize; 2627*fcf3ce44SJohn Forte } else { 2628*fcf3ce44SJohn Forte i = la.un.lilpBde.bdeSize; 2629*fcf3ce44SJohn Forte } 2630*fcf3ce44SJohn Forte 2631*fcf3ce44SJohn Forte if (i == 0) { 2632*fcf3ce44SJohn Forte port->alpa_map[0] = 0; 2633*fcf3ce44SJohn Forte } else { 2634*fcf3ce44SJohn Forte uint8_t *alpa_map; 2635*fcf3ce44SJohn Forte uint32_t j; 2636*fcf3ce44SJohn Forte 2637*fcf3ce44SJohn Forte /* 2638*fcf3ce44SJohn Forte * Check number of devices in 2639*fcf3ce44SJohn Forte * map 2640*fcf3ce44SJohn Forte */ 2641*fcf3ce44SJohn Forte if (port->alpa_map[0] > 127) { 2642*fcf3ce44SJohn Forte port->alpa_map[0] = 127; 2643*fcf3ce44SJohn Forte } 2644*fcf3ce44SJohn Forte alpa_map = (uint8_t *)port->alpa_map; 2645*fcf3ce44SJohn Forte 2646*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2647*fcf3ce44SJohn Forte &emlxs_link_atten_msg, 2648*fcf3ce44SJohn Forte "alpa_map: %d device(s): %02x " 2649*fcf3ce44SJohn Forte "%02x %02x %02x %02x %02x %02x", 2650*fcf3ce44SJohn Forte alpa_map[0], alpa_map[1], 2651*fcf3ce44SJohn Forte alpa_map[2], alpa_map[3], 2652*fcf3ce44SJohn Forte alpa_map[4], alpa_map[5], 2653*fcf3ce44SJohn Forte alpa_map[6], alpa_map[7]); 2654*fcf3ce44SJohn Forte 2655*fcf3ce44SJohn Forte for (j = 8; j <= alpa_map[0]; j += 8) { 2656*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2657*fcf3ce44SJohn Forte &emlxs_link_atten_msg, 2658*fcf3ce44SJohn Forte "alpa_map: %02x %02x %02x " 2659*fcf3ce44SJohn Forte "%02x %02x %02x %02x %02x", 2660*fcf3ce44SJohn Forte alpa_map[j], 2661*fcf3ce44SJohn Forte alpa_map[j + 1], 2662*fcf3ce44SJohn Forte alpa_map[j + 2], 2663*fcf3ce44SJohn Forte alpa_map[j + 3], 2664*fcf3ce44SJohn Forte alpa_map[j + 4], 2665*fcf3ce44SJohn Forte alpa_map[j + 5], 2666*fcf3ce44SJohn Forte alpa_map[j + 6], 2667*fcf3ce44SJohn Forte alpa_map[j + 7]); 2668*fcf3ce44SJohn Forte } 2669*fcf3ce44SJohn Forte } 2670*fcf3ce44SJohn Forte } 2671*fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 2672*fcf3ce44SJohn Forte /* Check if Menlo maintenance mode is enabled */ 2673*fcf3ce44SJohn Forte if (hba->model_info.device_id == 2674*fcf3ce44SJohn Forte PCI_DEVICE_ID_LP21000_M) { 2675*fcf3ce44SJohn Forte if (la.mm == 1) { 2676*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2677*fcf3ce44SJohn Forte &emlxs_link_atten_msg, 2678*fcf3ce44SJohn Forte "Maintenance Mode enabled."); 2679*fcf3ce44SJohn Forte 2680*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2681*fcf3ce44SJohn Forte hba->flag |= FC_MENLO_MODE; 2682*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2683*fcf3ce44SJohn Forte 2684*fcf3ce44SJohn Forte mutex_enter(&EMLXS_LINKUP_LOCK); 2685*fcf3ce44SJohn Forte cv_broadcast(&EMLXS_LINKUP_CV); 2686*fcf3ce44SJohn Forte mutex_exit(&EMLXS_LINKUP_LOCK); 2687*fcf3ce44SJohn Forte } else { 2688*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2689*fcf3ce44SJohn Forte &emlxs_link_atten_msg, 2690*fcf3ce44SJohn Forte "Maintenance Mode disabled."); 2691*fcf3ce44SJohn Forte } 2692*fcf3ce44SJohn Forte 2693*fcf3ce44SJohn Forte /* Check FCoE attention bit */ 2694*fcf3ce44SJohn Forte if (la.fa == 1) { 2695*fcf3ce44SJohn Forte (void) thread_create(NULL, 0, 2696*fcf3ce44SJohn Forte emlxs_fcoe_attention_thread, 2697*fcf3ce44SJohn Forte (char *)hba, 0, 2698*fcf3ce44SJohn Forte &p0, TS_RUN, 2699*fcf3ce44SJohn Forte v.v_maxsyspri - 2); 2700*fcf3ce44SJohn Forte } 2701*fcf3ce44SJohn Forte } 2702*fcf3ce44SJohn Forte #endif /* MENLO_SUPPORT */ 2703*fcf3ce44SJohn Forte 2704*fcf3ce44SJohn Forte if ((mbox = (MAILBOXQ *) emlxs_mem_get(hba, 2705*fcf3ce44SJohn Forte MEM_MBOX | MEM_PRI))) { 2706*fcf3ce44SJohn Forte /* 2707*fcf3ce44SJohn Forte * This should turn on DELAYED ABTS 2708*fcf3ce44SJohn Forte * for ELS timeouts 2709*fcf3ce44SJohn Forte */ 2710*fcf3ce44SJohn Forte emlxs_mb_set_var(hba, (MAILBOX *) mbox, 2711*fcf3ce44SJohn Forte 0x00052198, 0x1); 2712*fcf3ce44SJohn Forte 2713*fcf3ce44SJohn Forte emlxs_mb_put(hba, mbox); 2714*fcf3ce44SJohn Forte } 2715*fcf3ce44SJohn Forte if ((mbox = (MAILBOXQ *) emlxs_mem_get(hba, 2716*fcf3ce44SJohn Forte MEM_MBOX | MEM_PRI))) { 2717*fcf3ce44SJohn Forte /* 2718*fcf3ce44SJohn Forte * If link not already down then 2719*fcf3ce44SJohn Forte * declare it down now 2720*fcf3ce44SJohn Forte */ 2721*fcf3ce44SJohn Forte if (emlxs_mb_read_sparam(hba, 2722*fcf3ce44SJohn Forte (MAILBOX *) mbox) == 0) { 2723*fcf3ce44SJohn Forte emlxs_mb_put(hba, mbox); 2724*fcf3ce44SJohn Forte } else { 2725*fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, 2726*fcf3ce44SJohn Forte (uint8_t *)mbox); 2727*fcf3ce44SJohn Forte } 2728*fcf3ce44SJohn Forte } 2729*fcf3ce44SJohn Forte if ((mbox = (MAILBOXQ *) emlxs_mem_get(hba, 2730*fcf3ce44SJohn Forte MEM_MBOX | MEM_PRI))) { 2731*fcf3ce44SJohn Forte emlxs_mb_config_link(hba, 2732*fcf3ce44SJohn Forte (MAILBOX *) mbox); 2733*fcf3ce44SJohn Forte 2734*fcf3ce44SJohn Forte emlxs_mb_put(hba, mbox); 2735*fcf3ce44SJohn Forte } 2736*fcf3ce44SJohn Forte /* Declare the linkup here */ 2737*fcf3ce44SJohn Forte emlxs_linkup(hba); 2738*fcf3ce44SJohn Forte } 2739*fcf3ce44SJohn Forte /* If link not already down then declare it down now */ 2740*fcf3ce44SJohn Forte else if ((la.attType == AT_LINK_DOWN) && 2741*fcf3ce44SJohn Forte (hba->state > FC_LINK_DOWN)) { 2742*fcf3ce44SJohn Forte /* Declare link down here */ 2743*fcf3ce44SJohn Forte emlxs_linkdown(hba); 2744*fcf3ce44SJohn Forte } 2745*fcf3ce44SJohn Forte /* Enable Link attention interrupt */ 2746*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2747*fcf3ce44SJohn Forte 2748*fcf3ce44SJohn Forte if (!(hba->hc_copy & HC_LAINT_ENA)) { 2749*fcf3ce44SJohn Forte /* 2750*fcf3ce44SJohn Forte * hba->hc_copy = READ_CSR_REG(hba, 2751*fcf3ce44SJohn Forte * FC_HC_REG(hba, hba->csr_addr)); 2752*fcf3ce44SJohn Forte */ 2753*fcf3ce44SJohn Forte hba->hc_copy |= HC_LAINT_ENA; 2754*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, FC_HC_REG(hba, 2755*fcf3ce44SJohn Forte hba->csr_addr), hba->hc_copy); 2756*fcf3ce44SJohn Forte } 2757*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2758*fcf3ce44SJohn Forte 2759*fcf3ce44SJohn Forte /* Log the link event */ 2760*fcf3ce44SJohn Forte emlxs_log_link_event(port); 2761*fcf3ce44SJohn Forte 2762*fcf3ce44SJohn Forte break; 2763*fcf3ce44SJohn Forte 2764*fcf3ce44SJohn Forte case MBX_CLEAR_LA: 2765*fcf3ce44SJohn Forte /* Enable on Link Attention interrupts */ 2766*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2767*fcf3ce44SJohn Forte 2768*fcf3ce44SJohn Forte if (!(hba->hc_copy & HC_LAINT_ENA)) { 2769*fcf3ce44SJohn Forte /* 2770*fcf3ce44SJohn Forte * hba->hc_copy = READ_CSR_REG(hba, FC_HC_REG(hba, 2771*fcf3ce44SJohn Forte * hba->csr_addr)); 2772*fcf3ce44SJohn Forte */ 2773*fcf3ce44SJohn Forte hba->hc_copy |= HC_LAINT_ENA; 2774*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, FC_HC_REG(hba, hba->csr_addr), 2775*fcf3ce44SJohn Forte hba->hc_copy); 2776*fcf3ce44SJohn Forte } 2777*fcf3ce44SJohn Forte if (hba->state >= FC_LINK_UP) { 2778*fcf3ce44SJohn Forte emlxs_ffstate_change_locked(hba, FC_READY); 2779*fcf3ce44SJohn Forte } 2780*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2781*fcf3ce44SJohn Forte 2782*fcf3ce44SJohn Forte /* Adapter is now ready for FCP traffic */ 2783*fcf3ce44SJohn Forte if (hba->state == FC_READY) { 2784*fcf3ce44SJohn Forte /* Register vpi's for all ports that have did's */ 2785*fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 2786*fcf3ce44SJohn Forte vport = &VPORT(i); 2787*fcf3ce44SJohn Forte 2788*fcf3ce44SJohn Forte if (!(vport->flag & EMLXS_PORT_BOUND) || 2789*fcf3ce44SJohn Forte !(vport->did)) { 2790*fcf3ce44SJohn Forte continue; 2791*fcf3ce44SJohn Forte } 2792*fcf3ce44SJohn Forte (void) emlxs_mb_reg_vpi(vport); 2793*fcf3ce44SJohn Forte } 2794*fcf3ce44SJohn Forte 2795*fcf3ce44SJohn Forte /* Attempt to send any pending IO */ 2796*fcf3ce44SJohn Forte emlxs_issue_iocb_cmd(hba, &hba->ring[FC_FCP_RING], 0); 2797*fcf3ce44SJohn Forte } 2798*fcf3ce44SJohn Forte break; 2799*fcf3ce44SJohn Forte 2800*fcf3ce44SJohn Forte default: 2801*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg, 2802*fcf3ce44SJohn Forte "Unknown mailbox cmd: 0x%x", mb->mbxCommand); 2803*fcf3ce44SJohn Forte HBASTATS.MboxInvalid++; 2804*fcf3ce44SJohn Forte break; 2805*fcf3ce44SJohn Forte } 2806*fcf3ce44SJohn Forte 2807*fcf3ce44SJohn Forte return (0); 2808*fcf3ce44SJohn Forte 2809*fcf3ce44SJohn Forte } /* emlxs_mb_handle_cmd() */ 2810*fcf3ce44SJohn Forte 2811*fcf3ce44SJohn Forte 2812*fcf3ce44SJohn Forte /* MBX_NOWAIT - returns MBX_BUSY or MBX_SUCCESS or MBX_HARDWARE_ERROR */ 2813*fcf3ce44SJohn Forte /* MBX_WAIT - returns MBX_TIMEOUT or mailbox_status */ 2814*fcf3ce44SJohn Forte /* MBX_SLEEP - returns MBX_TIMEOUT or mailbox_status */ 2815*fcf3ce44SJohn Forte /* MBX_POLL - returns MBX_TIMEOUT or mailbox_status */ 2816*fcf3ce44SJohn Forte 2817*fcf3ce44SJohn Forte extern uint32_t 2818*fcf3ce44SJohn Forte emlxs_mb_issue_cmd(emlxs_hba_t *hba, MAILBOX *mb, int32_t flag, uint32_t tmo) 2819*fcf3ce44SJohn Forte { 2820*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2821*fcf3ce44SJohn Forte MAILBOX *mbox; 2822*fcf3ce44SJohn Forte MAILBOXQ *mbq; 2823*fcf3ce44SJohn Forte volatile uint32_t word0; 2824*fcf3ce44SJohn Forte volatile uint32_t ldata; 2825*fcf3ce44SJohn Forte uint32_t ha_copy; 2826*fcf3ce44SJohn Forte off_t offset; 2827*fcf3ce44SJohn Forte MATCHMAP *mbox_bp; 2828*fcf3ce44SJohn Forte uint32_t tmo_local; 2829*fcf3ce44SJohn Forte MAILBOX *swpmb; 2830*fcf3ce44SJohn Forte 2831*fcf3ce44SJohn Forte mbq = (MAILBOXQ *) mb; 2832*fcf3ce44SJohn Forte swpmb = (MAILBOX *) & word0; 2833*fcf3ce44SJohn Forte 2834*fcf3ce44SJohn Forte mb->mbxStatus = MBX_SUCCESS; 2835*fcf3ce44SJohn Forte 2836*fcf3ce44SJohn Forte /* Check for minimum timeouts */ 2837*fcf3ce44SJohn Forte switch (mb->mbxCommand) { 2838*fcf3ce44SJohn Forte /* Mailbox commands that erase/write flash */ 2839*fcf3ce44SJohn Forte case MBX_DOWN_LOAD: 2840*fcf3ce44SJohn Forte case MBX_UPDATE_CFG: 2841*fcf3ce44SJohn Forte case MBX_LOAD_AREA: 2842*fcf3ce44SJohn Forte case MBX_LOAD_EXP_ROM: 2843*fcf3ce44SJohn Forte case MBX_WRITE_NV: 2844*fcf3ce44SJohn Forte case MBX_FLASH_WR_ULA: 2845*fcf3ce44SJohn Forte case MBX_DEL_LD_ENTRY: 2846*fcf3ce44SJohn Forte case MBX_LOAD_SM: 2847*fcf3ce44SJohn Forte if (tmo < 300) { 2848*fcf3ce44SJohn Forte tmo = 300; 2849*fcf3ce44SJohn Forte } 2850*fcf3ce44SJohn Forte break; 2851*fcf3ce44SJohn Forte 2852*fcf3ce44SJohn Forte default: 2853*fcf3ce44SJohn Forte if (tmo < 30) { 2854*fcf3ce44SJohn Forte tmo = 30; 2855*fcf3ce44SJohn Forte } 2856*fcf3ce44SJohn Forte break; 2857*fcf3ce44SJohn Forte } 2858*fcf3ce44SJohn Forte 2859*fcf3ce44SJohn Forte /* Adjust wait flag */ 2860*fcf3ce44SJohn Forte if (flag != MBX_NOWAIT) { 2861*fcf3ce44SJohn Forte /* If interrupt is enabled, use sleep, otherwise poll */ 2862*fcf3ce44SJohn Forte if (hba->hc_copy & HC_MBINT_ENA) { 2863*fcf3ce44SJohn Forte flag = MBX_SLEEP; 2864*fcf3ce44SJohn Forte } else { 2865*fcf3ce44SJohn Forte flag = MBX_POLL; 2866*fcf3ce44SJohn Forte } 2867*fcf3ce44SJohn Forte } 2868*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2869*fcf3ce44SJohn Forte 2870*fcf3ce44SJohn Forte /* Check for hardware error */ 2871*fcf3ce44SJohn Forte if (hba->flag & FC_HARDWARE_ERROR) { 2872*fcf3ce44SJohn Forte mb->mbxStatus = (hba->flag & FC_OVERTEMP_EVENT) ? 2873*fcf3ce44SJohn Forte MBX_OVERTEMP_ERROR : MBX_HARDWARE_ERROR; 2874*fcf3ce44SJohn Forte 2875*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2876*fcf3ce44SJohn Forte 2877*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2878*fcf3ce44SJohn Forte "Hardware error reported. %s failed. status=%x mb=%p", 2879*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb->mbxStatus, mb); 2880*fcf3ce44SJohn Forte 2881*fcf3ce44SJohn Forte return (MBX_HARDWARE_ERROR); 2882*fcf3ce44SJohn Forte } 2883*fcf3ce44SJohn Forte if (hba->mbox_queue_flag) { 2884*fcf3ce44SJohn Forte /* If we are not polling, then queue it for later */ 2885*fcf3ce44SJohn Forte if (flag == MBX_NOWAIT) { 2886*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2887*fcf3ce44SJohn Forte "Busy. %s: mb=%p NoWait.", 2888*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb); 2889*fcf3ce44SJohn Forte 2890*fcf3ce44SJohn Forte emlxs_mb_put(hba, mbq); 2891*fcf3ce44SJohn Forte 2892*fcf3ce44SJohn Forte HBASTATS.MboxBusy++; 2893*fcf3ce44SJohn Forte 2894*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2895*fcf3ce44SJohn Forte 2896*fcf3ce44SJohn Forte return (MBX_BUSY); 2897*fcf3ce44SJohn Forte } 2898*fcf3ce44SJohn Forte tmo_local = tmo * 20; /* Convert tmo seconds to 50 */ 2899*fcf3ce44SJohn Forte /* millisecond tics */ 2900*fcf3ce44SJohn Forte while (hba->mbox_queue_flag) { 2901*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2902*fcf3ce44SJohn Forte 2903*fcf3ce44SJohn Forte if (tmo_local-- == 0) { 2904*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg, 2905*fcf3ce44SJohn Forte "Timeout. %s: mb=%p tmo=%d Waiting.", 2906*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 2907*fcf3ce44SJohn Forte tmo); 2908*fcf3ce44SJohn Forte 2909*fcf3ce44SJohn Forte /* Non-lethalStatus mailbox timeout */ 2910*fcf3ce44SJohn Forte /* Does not indicate a hardware error */ 2911*fcf3ce44SJohn Forte mb->mbxStatus = MBX_TIMEOUT; 2912*fcf3ce44SJohn Forte return (MBX_TIMEOUT); 2913*fcf3ce44SJohn Forte } 2914*fcf3ce44SJohn Forte DELAYMS(50); 2915*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2916*fcf3ce44SJohn Forte } 2917*fcf3ce44SJohn Forte } 2918*fcf3ce44SJohn Forte /* Initialize mailbox area */ 2919*fcf3ce44SJohn Forte emlxs_mb_init(hba, mbq, flag, tmo); 2920*fcf3ce44SJohn Forte 2921*fcf3ce44SJohn Forte switch (flag) { 2922*fcf3ce44SJohn Forte case MBX_NOWAIT: 2923*fcf3ce44SJohn Forte 2924*fcf3ce44SJohn Forte if (mb->mbxCommand != MBX_HEARTBEAT) { 2925*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2926*fcf3ce44SJohn Forte "Sending. %s: mb=%p NoWait.", 2927*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb); 2928*fcf3ce44SJohn Forte } 2929*fcf3ce44SJohn Forte break; 2930*fcf3ce44SJohn Forte 2931*fcf3ce44SJohn Forte case MBX_SLEEP: 2932*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2933*fcf3ce44SJohn Forte "Sending. %s: mb=%p Sleep.", 2934*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb); 2935*fcf3ce44SJohn Forte 2936*fcf3ce44SJohn Forte break; 2937*fcf3ce44SJohn Forte 2938*fcf3ce44SJohn Forte case MBX_POLL: 2939*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2940*fcf3ce44SJohn Forte "Sending. %s: mb=%p Polled.", 2941*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb); 2942*fcf3ce44SJohn Forte break; 2943*fcf3ce44SJohn Forte } 2944*fcf3ce44SJohn Forte 2945*fcf3ce44SJohn Forte mb->mbxOwner = OWN_CHIP; 2946*fcf3ce44SJohn Forte 2947*fcf3ce44SJohn Forte /* Clear the attention bit */ 2948*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, FC_HA_REG(hba, hba->csr_addr), HA_MBATT); 2949*fcf3ce44SJohn Forte 2950*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 2951*fcf3ce44SJohn Forte /* First copy command data */ 2952*fcf3ce44SJohn Forte mbox = FC_SLIM2_MAILBOX(hba); 2953*fcf3ce44SJohn Forte offset = (off_t)((uint64_t)(unsigned long)mbox - 2954*fcf3ce44SJohn Forte (uint64_t)(unsigned long)hba->slim2.virt); 2955*fcf3ce44SJohn Forte 2956*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 2957*fcf3ce44SJohn Forte if (hba->mbox_ext) { 2958*fcf3ce44SJohn Forte uint32_t *mbox_ext = (uint32_t *)((uint8_t *)mbox + 2959*fcf3ce44SJohn Forte MBOX_EXTENSION_OFFSET); 2960*fcf3ce44SJohn Forte off_t offset_ext = offset + MBOX_EXTENSION_OFFSET; 2961*fcf3ce44SJohn Forte 2962*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)hba->mbox_ext, mbox_ext, 2963*fcf3ce44SJohn Forte hba->mbox_ext_size); 2964*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset_ext, 2965*fcf3ce44SJohn Forte hba->mbox_ext_size, DDI_DMA_SYNC_FORDEV); 2966*fcf3ce44SJohn Forte } 2967*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 2968*fcf3ce44SJohn Forte 2969*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)mb, (uint32_t *)mbox, 2970*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE); 2971*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset, 2972*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORDEV); 2973*fcf3ce44SJohn Forte } 2974*fcf3ce44SJohn Forte /* Check for config port command */ 2975*fcf3ce44SJohn Forte else if (mb->mbxCommand == MBX_CONFIG_PORT) { 2976*fcf3ce44SJohn Forte /* copy command data into host mbox for cmpl */ 2977*fcf3ce44SJohn Forte mbox = FC_SLIM2_MAILBOX(hba); 2978*fcf3ce44SJohn Forte offset = (off_t)((uint64_t)(unsigned long)mbox - 2979*fcf3ce44SJohn Forte (uint64_t)(unsigned long)hba->slim2.virt); 2980*fcf3ce44SJohn Forte 2981*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)mb, (uint32_t *)mbox, 2982*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE); 2983*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset, 2984*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORDEV); 2985*fcf3ce44SJohn Forte 2986*fcf3ce44SJohn Forte /* First copy command data */ 2987*fcf3ce44SJohn Forte mbox = FC_SLIM1_MAILBOX(hba); 2988*fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, &mb->un.varWords, &mbox->un.varWords, 2989*fcf3ce44SJohn Forte (MAILBOX_CMD_WSIZE - 1)); 2990*fcf3ce44SJohn Forte 2991*fcf3ce44SJohn Forte /* copy over last word, with mbxOwner set */ 2992*fcf3ce44SJohn Forte ldata = *((volatile uint32_t *) mb); 2993*fcf3ce44SJohn Forte WRITE_SLIM_ADDR(hba, ((volatile uint32_t *) mbox), ldata); 2994*fcf3ce44SJohn Forte 2995*fcf3ce44SJohn Forte /* switch over to host mailbox */ 2996*fcf3ce44SJohn Forte /* 2997*fcf3ce44SJohn Forte * hba->mbox_queueaddr = (uint32_t *)&((SLIM2 *) 2998*fcf3ce44SJohn Forte * hba->slim2.virt)->mbx; 2999*fcf3ce44SJohn Forte */ 3000*fcf3ce44SJohn Forte hba->flag |= FC_SLIM2_MODE; 3001*fcf3ce44SJohn Forte } else { /* SLIM 1 */ 3002*fcf3ce44SJohn Forte mbox = FC_SLIM1_MAILBOX(hba); 3003*fcf3ce44SJohn Forte 3004*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 3005*fcf3ce44SJohn Forte if (hba->mbox_ext) { 3006*fcf3ce44SJohn Forte uint32_t *mbox_ext = (uint32_t *)((uint8_t *)mbox + 3007*fcf3ce44SJohn Forte MBOX_EXTENSION_OFFSET); 3008*fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)hba->mbox_ext, 3009*fcf3ce44SJohn Forte mbox_ext, (hba->mbox_ext_size / 4)); 3010*fcf3ce44SJohn Forte } 3011*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 3012*fcf3ce44SJohn Forte 3013*fcf3ce44SJohn Forte /* First copy command data */ 3014*fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, &mb->un.varWords, &mbox->un.varWords, 3015*fcf3ce44SJohn Forte (MAILBOX_CMD_WSIZE - 1)); 3016*fcf3ce44SJohn Forte 3017*fcf3ce44SJohn Forte /* copy over last word, with mbxOwner set */ 3018*fcf3ce44SJohn Forte ldata = *((volatile uint32_t *) mb); 3019*fcf3ce44SJohn Forte WRITE_SLIM_ADDR(hba, ((volatile uint32_t *) mbox), ldata); 3020*fcf3ce44SJohn Forte } 3021*fcf3ce44SJohn Forte 3022*fcf3ce44SJohn Forte /* Interrupt board to do it right away */ 3023*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, FC_CA_REG(hba, hba->csr_addr), CA_MBATT); 3024*fcf3ce44SJohn Forte 3025*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3026*fcf3ce44SJohn Forte 3027*fcf3ce44SJohn Forte switch (flag) { 3028*fcf3ce44SJohn Forte case MBX_NOWAIT: 3029*fcf3ce44SJohn Forte return (MBX_SUCCESS); 3030*fcf3ce44SJohn Forte 3031*fcf3ce44SJohn Forte case MBX_SLEEP: 3032*fcf3ce44SJohn Forte 3033*fcf3ce44SJohn Forte /* Wait for completion */ 3034*fcf3ce44SJohn Forte /* The driver clock is timing the mailbox. */ 3035*fcf3ce44SJohn Forte /* emlxs_mb_fini() will be called externally. */ 3036*fcf3ce44SJohn Forte 3037*fcf3ce44SJohn Forte mutex_enter(&EMLXS_MBOX_LOCK); 3038*fcf3ce44SJohn Forte while (!(mbq->flag & MBQ_COMPLETED)) { 3039*fcf3ce44SJohn Forte cv_wait(&EMLXS_MBOX_CV, &EMLXS_MBOX_LOCK); 3040*fcf3ce44SJohn Forte } 3041*fcf3ce44SJohn Forte mutex_exit(&EMLXS_MBOX_LOCK); 3042*fcf3ce44SJohn Forte 3043*fcf3ce44SJohn Forte if (mb->mbxStatus == MBX_TIMEOUT) { 3044*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg, 3045*fcf3ce44SJohn Forte "Timeout. %s: mb=%p tmo=%d. Sleep.", 3046*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo); 3047*fcf3ce44SJohn Forte } else { 3048*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3049*fcf3ce44SJohn Forte "Completed. %s: mb=%p status=%x Sleep.", 3050*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 3051*fcf3ce44SJohn Forte mb->mbxStatus); 3052*fcf3ce44SJohn Forte } 3053*fcf3ce44SJohn Forte 3054*fcf3ce44SJohn Forte break; 3055*fcf3ce44SJohn Forte 3056*fcf3ce44SJohn Forte case MBX_POLL: 3057*fcf3ce44SJohn Forte 3058*fcf3ce44SJohn Forte tmo_local = tmo * 2000; /* Convert tmo seconds to 500 usec */ 3059*fcf3ce44SJohn Forte /* tics */ 3060*fcf3ce44SJohn Forte 3061*fcf3ce44SJohn Forte if (hba->state >= FC_INIT_START) { 3062*fcf3ce44SJohn Forte ha_copy = READ_CSR_REG(hba, FC_HA_REG(hba, 3063*fcf3ce44SJohn Forte hba->csr_addr)); 3064*fcf3ce44SJohn Forte 3065*fcf3ce44SJohn Forte /* Wait for command to complete */ 3066*fcf3ce44SJohn Forte while (!(ha_copy & HA_MBATT) && 3067*fcf3ce44SJohn Forte !(mbq->flag & MBQ_COMPLETED)) { 3068*fcf3ce44SJohn Forte if (!hba->timer_id && (tmo_local-- == 0)) { 3069*fcf3ce44SJohn Forte /* self time */ 3070*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3071*fcf3ce44SJohn Forte &emlxs_hardware_error_msg, 3072*fcf3ce44SJohn Forte "Mailbox Timeout: %s: mb=%p Polled", 3073*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 3074*fcf3ce44SJohn Forte mb); 3075*fcf3ce44SJohn Forte 3076*fcf3ce44SJohn Forte hba->flag |= FC_MBOX_TIMEOUT; 3077*fcf3ce44SJohn Forte emlxs_ffstate_change(hba, FC_ERROR); 3078*fcf3ce44SJohn Forte emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 3079*fcf3ce44SJohn Forte 3080*fcf3ce44SJohn Forte break; 3081*fcf3ce44SJohn Forte } 3082*fcf3ce44SJohn Forte DELAYUS(500); 3083*fcf3ce44SJohn Forte ha_copy = READ_CSR_REG(hba, 3084*fcf3ce44SJohn Forte FC_HA_REG(hba, hba->csr_addr)); 3085*fcf3ce44SJohn Forte } 3086*fcf3ce44SJohn Forte 3087*fcf3ce44SJohn Forte if (mb->mbxStatus == MBX_TIMEOUT) { 3088*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg, 3089*fcf3ce44SJohn Forte "Timeout. %s: mb=%p tmo=%d. Polled.", 3090*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 3091*fcf3ce44SJohn Forte tmo); 3092*fcf3ce44SJohn Forte 3093*fcf3ce44SJohn Forte break; 3094*fcf3ce44SJohn Forte } 3095*fcf3ce44SJohn Forte } 3096*fcf3ce44SJohn Forte /* Get first word of mailbox */ 3097*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 3098*fcf3ce44SJohn Forte mbox = FC_SLIM2_MAILBOX(hba); 3099*fcf3ce44SJohn Forte offset = (off_t)((uint64_t)(unsigned long)mbox - 3100*fcf3ce44SJohn Forte (uint64_t)(unsigned long)hba->slim2.virt); 3101*fcf3ce44SJohn Forte 3102*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset, 3103*fcf3ce44SJohn Forte sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL); 3104*fcf3ce44SJohn Forte word0 = *((volatile uint32_t *) mbox); 3105*fcf3ce44SJohn Forte word0 = PCIMEM_LONG(word0); 3106*fcf3ce44SJohn Forte } else { 3107*fcf3ce44SJohn Forte mbox = FC_SLIM1_MAILBOX(hba); 3108*fcf3ce44SJohn Forte word0 = READ_SLIM_ADDR(hba, 3109*fcf3ce44SJohn Forte ((volatile uint32_t *) mbox)); 3110*fcf3ce44SJohn Forte } 3111*fcf3ce44SJohn Forte 3112*fcf3ce44SJohn Forte /* Wait for command to complete */ 3113*fcf3ce44SJohn Forte while ((swpmb->mbxOwner == OWN_CHIP) && 3114*fcf3ce44SJohn Forte !(mbq->flag & MBQ_COMPLETED)) { 3115*fcf3ce44SJohn Forte if (!hba->timer_id && (tmo_local-- == 0)) { 3116*fcf3ce44SJohn Forte /* self time */ 3117*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3118*fcf3ce44SJohn Forte &emlxs_hardware_error_msg, 3119*fcf3ce44SJohn Forte "Mailbox Timeout: %s: mb=%p Polled.", 3120*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb); 3121*fcf3ce44SJohn Forte 3122*fcf3ce44SJohn Forte hba->flag |= FC_MBOX_TIMEOUT; 3123*fcf3ce44SJohn Forte emlxs_ffstate_change(hba, FC_ERROR); 3124*fcf3ce44SJohn Forte emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 3125*fcf3ce44SJohn Forte 3126*fcf3ce44SJohn Forte break; 3127*fcf3ce44SJohn Forte } 3128*fcf3ce44SJohn Forte DELAYUS(500); 3129*fcf3ce44SJohn Forte 3130*fcf3ce44SJohn Forte /* Get first word of mailbox */ 3131*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 3132*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset, 3133*fcf3ce44SJohn Forte sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL); 3134*fcf3ce44SJohn Forte word0 = *((volatile uint32_t *) mbox); 3135*fcf3ce44SJohn Forte word0 = PCIMEM_LONG(word0); 3136*fcf3ce44SJohn Forte } else { 3137*fcf3ce44SJohn Forte word0 = READ_SLIM_ADDR(hba, 3138*fcf3ce44SJohn Forte ((volatile uint32_t *) mbox)); 3139*fcf3ce44SJohn Forte } 3140*fcf3ce44SJohn Forte 3141*fcf3ce44SJohn Forte } /* while */ 3142*fcf3ce44SJohn Forte 3143*fcf3ce44SJohn Forte if (mb->mbxStatus == MBX_TIMEOUT) { 3144*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg, 3145*fcf3ce44SJohn Forte "Timeout. %s: mb=%p tmo=%d. Polled.", 3146*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo); 3147*fcf3ce44SJohn Forte 3148*fcf3ce44SJohn Forte break; 3149*fcf3ce44SJohn Forte } 3150*fcf3ce44SJohn Forte /* copy results back to user */ 3151*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 3152*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, offset, 3153*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL); 3154*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)mbox, (uint32_t *)mb, 3155*fcf3ce44SJohn Forte MAILBOX_CMD_BSIZE); 3156*fcf3ce44SJohn Forte } else { 3157*fcf3ce44SJohn Forte READ_SLIM_COPY(hba, (uint32_t *)mb, (uint32_t *)mbox, 3158*fcf3ce44SJohn Forte MAILBOX_CMD_WSIZE); 3159*fcf3ce44SJohn Forte } 3160*fcf3ce44SJohn Forte 3161*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 3162*fcf3ce44SJohn Forte if (hba->mbox_ext) { 3163*fcf3ce44SJohn Forte uint32_t *mbox_ext = (uint32_t *)((uint8_t *)mbox + 3164*fcf3ce44SJohn Forte MBOX_EXTENSION_OFFSET); 3165*fcf3ce44SJohn Forte off_t offset_ext = offset + MBOX_EXTENSION_OFFSET; 3166*fcf3ce44SJohn Forte 3167*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 3168*fcf3ce44SJohn Forte emlxs_mpdata_sync(hba->slim2.dma_handle, 3169*fcf3ce44SJohn Forte offset_ext, hba->mbox_ext_size, 3170*fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 3171*fcf3ce44SJohn Forte emlxs_pcimem_bcopy(mbox_ext, 3172*fcf3ce44SJohn Forte (uint32_t *)hba->mbox_ext, 3173*fcf3ce44SJohn Forte hba->mbox_ext_size); 3174*fcf3ce44SJohn Forte } else { 3175*fcf3ce44SJohn Forte READ_SLIM_COPY(hba, (uint32_t *)hba->mbox_ext, 3176*fcf3ce44SJohn Forte mbox_ext, (hba->mbox_ext_size / 4)); 3177*fcf3ce44SJohn Forte } 3178*fcf3ce44SJohn Forte } 3179*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 3180*fcf3ce44SJohn Forte 3181*fcf3ce44SJohn Forte /* Sync the memory buffer */ 3182*fcf3ce44SJohn Forte if (hba->mbox_bp) { 3183*fcf3ce44SJohn Forte mbox_bp = (MATCHMAP *) hba->mbox_bp; 3184*fcf3ce44SJohn Forte emlxs_mpdata_sync(mbox_bp->dma_handle, 0, mbox_bp->size, 3185*fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 3186*fcf3ce44SJohn Forte } 3187*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3188*fcf3ce44SJohn Forte "Completed. %s: mb=%p status=%x Polled.", 3189*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), mb, mb->mbxStatus); 3190*fcf3ce44SJohn Forte 3191*fcf3ce44SJohn Forte /* Process the result */ 3192*fcf3ce44SJohn Forte if (!(mbq->flag & MBQ_PASSTHRU)) { 3193*fcf3ce44SJohn Forte (void) emlxs_mb_handle_cmd(hba, mb); 3194*fcf3ce44SJohn Forte } 3195*fcf3ce44SJohn Forte /* Clear the attention bit */ 3196*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, FC_HA_REG(hba, hba->csr_addr), HA_MBATT); 3197*fcf3ce44SJohn Forte 3198*fcf3ce44SJohn Forte /* Clean up the mailbox area */ 3199*fcf3ce44SJohn Forte emlxs_mb_fini(hba, NULL, mb->mbxStatus); 3200*fcf3ce44SJohn Forte 3201*fcf3ce44SJohn Forte break; 3202*fcf3ce44SJohn Forte 3203*fcf3ce44SJohn Forte } /* switch (flag) */ 3204*fcf3ce44SJohn Forte 3205*fcf3ce44SJohn Forte return (mb->mbxStatus); 3206*fcf3ce44SJohn Forte 3207*fcf3ce44SJohn Forte } /* emlxs_mb_issue_cmd() */ 3208*fcf3ce44SJohn Forte 3209*fcf3ce44SJohn Forte 3210*fcf3ce44SJohn Forte 3211*fcf3ce44SJohn Forte extern char * 3212*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(uint8_t cmd) 3213*fcf3ce44SJohn Forte { 3214*fcf3ce44SJohn Forte static char buffer[32]; 3215*fcf3ce44SJohn Forte uint32_t i; 3216*fcf3ce44SJohn Forte uint32_t count; 3217*fcf3ce44SJohn Forte 3218*fcf3ce44SJohn Forte count = sizeof (emlxs_mb_cmd_table) / sizeof (emlxs_table_t); 3219*fcf3ce44SJohn Forte for (i = 0; i < count; i++) { 3220*fcf3ce44SJohn Forte if (cmd == emlxs_mb_cmd_table[i].code) { 3221*fcf3ce44SJohn Forte return (emlxs_mb_cmd_table[i].string); 3222*fcf3ce44SJohn Forte } 3223*fcf3ce44SJohn Forte } 3224*fcf3ce44SJohn Forte 3225*fcf3ce44SJohn Forte (void) sprintf(buffer, "Cmd=0x%x", cmd); 3226*fcf3ce44SJohn Forte return (buffer); 3227*fcf3ce44SJohn Forte 3228*fcf3ce44SJohn Forte } /* emlxs_mb_cmd_xlate() */ 3229