1*d14abf15SRobert Mustacchi /* 2*d14abf15SRobert Mustacchi * CDDL HEADER START 3*d14abf15SRobert Mustacchi * 4*d14abf15SRobert Mustacchi * The contents of this file are subject to the terms of the 5*d14abf15SRobert Mustacchi * Common Development and Distribution License (the "License"). 6*d14abf15SRobert Mustacchi * You may not use this file except in compliance with the License. 7*d14abf15SRobert Mustacchi * 8*d14abf15SRobert Mustacchi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*d14abf15SRobert Mustacchi * or http://www.opensolaris.org/os/licensing. 10*d14abf15SRobert Mustacchi * See the License for the specific language governing permissions 11*d14abf15SRobert Mustacchi * and limitations under the License. 12*d14abf15SRobert Mustacchi * 13*d14abf15SRobert Mustacchi * When distributing Covered Code, include this CDDL HEADER in each 14*d14abf15SRobert Mustacchi * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*d14abf15SRobert Mustacchi * If applicable, add the following below this CDDL HEADER, with the 16*d14abf15SRobert Mustacchi * fields enclosed by brackets "[]" replaced with your own identifying 17*d14abf15SRobert Mustacchi * information: Portions Copyright [yyyy] [name of copyright owner] 18*d14abf15SRobert Mustacchi * 19*d14abf15SRobert Mustacchi * CDDL HEADER END 20*d14abf15SRobert Mustacchi */ 21*d14abf15SRobert Mustacchi 22*d14abf15SRobert Mustacchi /* 23*d14abf15SRobert Mustacchi * Copyright 2014 QLogic Corporation 24*d14abf15SRobert Mustacchi * The contents of this file are subject to the terms of the 25*d14abf15SRobert Mustacchi * QLogic End User License (the "License"). 26*d14abf15SRobert Mustacchi * You may not use this file except in compliance with the License. 27*d14abf15SRobert Mustacchi * 28*d14abf15SRobert Mustacchi * You can obtain a copy of the License at 29*d14abf15SRobert Mustacchi * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/ 30*d14abf15SRobert Mustacchi * QLogic_End_User_Software_License.txt 31*d14abf15SRobert Mustacchi * See the License for the specific language governing permissions 32*d14abf15SRobert Mustacchi * and limitations under the License. 33*d14abf15SRobert Mustacchi */ 34*d14abf15SRobert Mustacchi 35*d14abf15SRobert Mustacchi #include "bnxe.h" 36*d14abf15SRobert Mustacchi 37*d14abf15SRobert Mustacchi 38*d14abf15SRobert Mustacchi #define VERIFY_FCOE_BINDING(pUM) \ 39*d14abf15SRobert Mustacchi if (!BNXE_FCOE(pUM)) \ 40*d14abf15SRobert Mustacchi { \ 41*d14abf15SRobert Mustacchi BnxeLogWarn((pUM), "FCoE not supported on this device!"); \ 42*d14abf15SRobert Mustacchi return B_FALSE; \ 43*d14abf15SRobert Mustacchi } \ 44*d14abf15SRobert Mustacchi if (!(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE))) \ 45*d14abf15SRobert Mustacchi { \ 46*d14abf15SRobert Mustacchi BnxeLogWarn((pUM), "FCoE client not bound!"); \ 47*d14abf15SRobert Mustacchi return B_FALSE; \ 48*d14abf15SRobert Mustacchi } 49*d14abf15SRobert Mustacchi 50*d14abf15SRobert Mustacchi 51*d14abf15SRobert Mustacchi void BnxeFcoeFreeResc(um_device_t * pUM, 52*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState) 53*d14abf15SRobert Mustacchi { 54*d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_OFFLOAD(pUM); 55*d14abf15SRobert Mustacchi lm_fc_del_fcoe_state(&pUM->lm_dev, &pFcoeState->lm_fcoe); 56*d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_OFFLOAD(pUM); 57*d14abf15SRobert Mustacchi 58*d14abf15SRobert Mustacchi lm_fc_free_con_resc(&pUM->lm_dev, &pFcoeState->lm_fcoe); 59*d14abf15SRobert Mustacchi 60*d14abf15SRobert Mustacchi kmem_free(pFcoeState, sizeof(BnxeFcoeState)); 61*d14abf15SRobert Mustacchi } 62*d14abf15SRobert Mustacchi 63*d14abf15SRobert Mustacchi 64*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeCqeIndicate(um_device_t * pUM, 65*d14abf15SRobert Mustacchi void * pData, 66*d14abf15SRobert Mustacchi u32_t dataLen) 67*d14abf15SRobert Mustacchi { 68*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe = (struct fcoe_kcqe *)pData; 69*d14abf15SRobert Mustacchi 70*d14abf15SRobert Mustacchi if (dataLen != (sizeof(*kcqe))) 71*d14abf15SRobert Mustacchi { 72*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE CQE"); 73*d14abf15SRobert Mustacchi return B_FALSE; 74*d14abf15SRobert Mustacchi } 75*d14abf15SRobert Mustacchi 76*d14abf15SRobert Mustacchi /* XXX 77*d14abf15SRobert Mustacchi * Need to add a mutex or reference count to ensure that bnxef isn't 78*d14abf15SRobert Mustacchi * unloaded underneath this taskq dispatch routine. 79*d14abf15SRobert Mustacchi */ 80*d14abf15SRobert Mustacchi 81*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 82*d14abf15SRobert Mustacchi pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 83*d14abf15SRobert Mustacchi (void **)&kcqe, 1); 84*d14abf15SRobert Mustacchi 85*d14abf15SRobert Mustacchi /* XXX release mutex or decrement reference count */ 86*d14abf15SRobert Mustacchi 87*d14abf15SRobert Mustacchi return B_TRUE; 88*d14abf15SRobert Mustacchi } 89*d14abf15SRobert Mustacchi 90*d14abf15SRobert Mustacchi 91*d14abf15SRobert Mustacchi static void BnxeFcoeInitCqeWork(um_device_t * pUM, 92*d14abf15SRobert Mustacchi void * pData, 93*d14abf15SRobert Mustacchi u32_t dataLen) 94*d14abf15SRobert Mustacchi { 95*d14abf15SRobert Mustacchi if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen)) 96*d14abf15SRobert Mustacchi { 97*d14abf15SRobert Mustacchi pUM->fcoe.stats.initCqeRxErr++; 98*d14abf15SRobert Mustacchi } 99*d14abf15SRobert Mustacchi else 100*d14abf15SRobert Mustacchi { 101*d14abf15SRobert Mustacchi pUM->fcoe.stats.initCqeRx++; 102*d14abf15SRobert Mustacchi } 103*d14abf15SRobert Mustacchi } 104*d14abf15SRobert Mustacchi 105*d14abf15SRobert Mustacchi 106*d14abf15SRobert Mustacchi boolean_t BnxeFcoeInitCqe(um_device_t * pUM, 107*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe) 108*d14abf15SRobert Mustacchi { 109*d14abf15SRobert Mustacchi struct fcoe_kcqe tmp_kcqe = {0}; 110*d14abf15SRobert Mustacchi 111*d14abf15SRobert Mustacchi tmp_kcqe.op_code = FCOE_KCQE_OPCODE_INIT_FUNC; 112*d14abf15SRobert Mustacchi 113*d14abf15SRobert Mustacchi tmp_kcqe.flags |= 114*d14abf15SRobert Mustacchi (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 115*d14abf15SRobert Mustacchi 116*d14abf15SRobert Mustacchi tmp_kcqe.completion_status = 117*d14abf15SRobert Mustacchi mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ? 118*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_SUCCESS : 119*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 120*d14abf15SRobert Mustacchi 121*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeInitCqeWork, 122*d14abf15SRobert Mustacchi &tmp_kcqe, sizeof(tmp_kcqe)); 123*d14abf15SRobert Mustacchi } 124*d14abf15SRobert Mustacchi 125*d14abf15SRobert Mustacchi 126*d14abf15SRobert Mustacchi static void BnxeFcoeInitWqeWork(um_device_t * pUM, 127*d14abf15SRobert Mustacchi void * pData, 128*d14abf15SRobert Mustacchi u32_t dataLen) 129*d14abf15SRobert Mustacchi { 130*d14abf15SRobert Mustacchi union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData; 131*d14abf15SRobert Mustacchi struct fcoe_kcqe kcqe = {0}; 132*d14abf15SRobert Mustacchi 133*d14abf15SRobert Mustacchi if (dataLen != (3 * sizeof(*kwqe))) 134*d14abf15SRobert Mustacchi { 135*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Init WQE"); 136*d14abf15SRobert Mustacchi pUM->fcoe.stats.initWqeTxErr++; 137*d14abf15SRobert Mustacchi return; 138*d14abf15SRobert Mustacchi } 139*d14abf15SRobert Mustacchi 140*d14abf15SRobert Mustacchi if (kwqe[1].init2.hsi_major_version != FCOE_HSI_MAJOR_VERSION) 141*d14abf15SRobert Mustacchi { 142*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "ERROR: Invalid FCoE HSI major version (L5=%d vs FW=%d)", 143*d14abf15SRobert Mustacchi kwqe[1].init2.hsi_major_version, 144*d14abf15SRobert Mustacchi FCOE_HSI_MAJOR_VERSION); 145*d14abf15SRobert Mustacchi kcqe.completion_status = FCOE_KCQE_COMPLETION_STATUS_WRONG_HSI_VERSION; 146*d14abf15SRobert Mustacchi goto BnxeFcoeInitWqeWork_error; 147*d14abf15SRobert Mustacchi } 148*d14abf15SRobert Mustacchi 149*d14abf15SRobert Mustacchi if (lm_fc_init(&pUM->lm_dev, 150*d14abf15SRobert Mustacchi &kwqe[0].init1, 151*d14abf15SRobert Mustacchi &kwqe[1].init2, 152*d14abf15SRobert Mustacchi &kwqe[2].init3) != LM_STATUS_SUCCESS) 153*d14abf15SRobert Mustacchi { 154*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to post FCoE Init WQE"); 155*d14abf15SRobert Mustacchi kcqe.completion_status = FCOE_KCQE_COMPLETION_STATUS_ERROR; 156*d14abf15SRobert Mustacchi goto BnxeFcoeInitWqeWork_error; 157*d14abf15SRobert Mustacchi } 158*d14abf15SRobert Mustacchi 159*d14abf15SRobert Mustacchi pUM->fcoe.stats.initWqeTx++; 160*d14abf15SRobert Mustacchi 161*d14abf15SRobert Mustacchi return; 162*d14abf15SRobert Mustacchi 163*d14abf15SRobert Mustacchi BnxeFcoeInitWqeWork_error: 164*d14abf15SRobert Mustacchi 165*d14abf15SRobert Mustacchi pUM->fcoe.stats.initWqeTxErr++; 166*d14abf15SRobert Mustacchi 167*d14abf15SRobert Mustacchi kcqe.op_code = FCOE_KCQE_OPCODE_INIT_FUNC; 168*d14abf15SRobert Mustacchi kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 169*d14abf15SRobert Mustacchi kcqe.completion_status = mm_cpu_to_le32(kcqe.completion_status); 170*d14abf15SRobert Mustacchi kcqe.fcoe_conn_id = kwqe[1].conn_offload1.fcoe_conn_id; 171*d14abf15SRobert Mustacchi 172*d14abf15SRobert Mustacchi /* call here directly (for error case) */ 173*d14abf15SRobert Mustacchi 174*d14abf15SRobert Mustacchi /* XXX 175*d14abf15SRobert Mustacchi * Need to add a mutex or reference count to ensure that bnxef isn't 176*d14abf15SRobert Mustacchi * unloaded underneath this taskq dispatch routine. 177*d14abf15SRobert Mustacchi */ 178*d14abf15SRobert Mustacchi 179*d14abf15SRobert Mustacchi { 180*d14abf15SRobert Mustacchi struct fcoe_kcqe * pKcqe = &kcqe; 181*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 182*d14abf15SRobert Mustacchi pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 183*d14abf15SRobert Mustacchi (void **)&pKcqe, 1); 184*d14abf15SRobert Mustacchi } 185*d14abf15SRobert Mustacchi 186*d14abf15SRobert Mustacchi /* XXX release mutex or decrement reference count */ 187*d14abf15SRobert Mustacchi } 188*d14abf15SRobert Mustacchi 189*d14abf15SRobert Mustacchi 190*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeInitWqe(um_device_t * pUM, 191*d14abf15SRobert Mustacchi union fcoe_kwqe ** kwqes) 192*d14abf15SRobert Mustacchi { 193*d14abf15SRobert Mustacchi union fcoe_kwqe wqe[3]; 194*d14abf15SRobert Mustacchi 195*d14abf15SRobert Mustacchi wqe[0] =*(kwqes[0]); 196*d14abf15SRobert Mustacchi wqe[1] =*(kwqes[1]); 197*d14abf15SRobert Mustacchi wqe[2] =*(kwqes[2]); 198*d14abf15SRobert Mustacchi 199*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeInitWqeWork, wqe, sizeof(wqe)); 200*d14abf15SRobert Mustacchi } 201*d14abf15SRobert Mustacchi 202*d14abf15SRobert Mustacchi 203*d14abf15SRobert Mustacchi static void BnxeFcoeOffloadConnCqeWork(um_device_t * pUM, 204*d14abf15SRobert Mustacchi void * pData, 205*d14abf15SRobert Mustacchi u32_t dataLen) 206*d14abf15SRobert Mustacchi { 207*d14abf15SRobert Mustacchi if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen)) 208*d14abf15SRobert Mustacchi { 209*d14abf15SRobert Mustacchi pUM->fcoe.stats.offloadConnCqeRxErr++; 210*d14abf15SRobert Mustacchi } 211*d14abf15SRobert Mustacchi else 212*d14abf15SRobert Mustacchi { 213*d14abf15SRobert Mustacchi pUM->fcoe.stats.offloadConnCqeRx++; 214*d14abf15SRobert Mustacchi } 215*d14abf15SRobert Mustacchi } 216*d14abf15SRobert Mustacchi 217*d14abf15SRobert Mustacchi 218*d14abf15SRobert Mustacchi boolean_t BnxeFcoeOffloadConnCqe(um_device_t * pUM, 219*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState, 220*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe) 221*d14abf15SRobert Mustacchi { 222*d14abf15SRobert Mustacchi struct fcoe_kcqe tmp_kcqe = {0}; 223*d14abf15SRobert Mustacchi 224*d14abf15SRobert Mustacchi tmp_kcqe.op_code = FCOE_KCQE_OPCODE_OFFLOAD_CONN; 225*d14abf15SRobert Mustacchi 226*d14abf15SRobert Mustacchi tmp_kcqe.flags |= 227*d14abf15SRobert Mustacchi (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 228*d14abf15SRobert Mustacchi 229*d14abf15SRobert Mustacchi tmp_kcqe.fcoe_conn_context_id = kcqe->fcoe_conn_context_id; 230*d14abf15SRobert Mustacchi tmp_kcqe.fcoe_conn_id = kcqe->fcoe_conn_id; 231*d14abf15SRobert Mustacchi 232*d14abf15SRobert Mustacchi tmp_kcqe.completion_status = 233*d14abf15SRobert Mustacchi mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ? 234*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_SUCCESS : 235*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE); 236*d14abf15SRobert Mustacchi 237*d14abf15SRobert Mustacchi if (pFcoeState != NULL) 238*d14abf15SRobert Mustacchi { 239*d14abf15SRobert Mustacchi pFcoeState->lm_fcoe.hdr.status = 240*d14abf15SRobert Mustacchi (mm_le32_to_cpu(kcqe->completion_status) == 0) ? 241*d14abf15SRobert Mustacchi STATE_STATUS_NORMAL : 242*d14abf15SRobert Mustacchi STATE_STATUS_INIT_OFFLOAD_ERR; 243*d14abf15SRobert Mustacchi } 244*d14abf15SRobert Mustacchi 245*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeOffloadConnCqeWork, 246*d14abf15SRobert Mustacchi &tmp_kcqe, sizeof(tmp_kcqe)); 247*d14abf15SRobert Mustacchi } 248*d14abf15SRobert Mustacchi 249*d14abf15SRobert Mustacchi 250*d14abf15SRobert Mustacchi static void BnxeFcoeOffloadConnWqeWork(um_device_t * pUM, 251*d14abf15SRobert Mustacchi void * pData, 252*d14abf15SRobert Mustacchi u32_t dataLen) 253*d14abf15SRobert Mustacchi { 254*d14abf15SRobert Mustacchi union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData; 255*d14abf15SRobert Mustacchi struct fcoe_kcqe kcqe = {0}; 256*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState; 257*d14abf15SRobert Mustacchi lm_status_t rc; 258*d14abf15SRobert Mustacchi 259*d14abf15SRobert Mustacchi if (dataLen != (4 * sizeof(*kwqe))) 260*d14abf15SRobert Mustacchi { 261*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Offload Conn WQE"); 262*d14abf15SRobert Mustacchi pUM->fcoe.stats.offloadConnWqeTxErr++; 263*d14abf15SRobert Mustacchi return; 264*d14abf15SRobert Mustacchi } 265*d14abf15SRobert Mustacchi 266*d14abf15SRobert Mustacchi if ((pFcoeState = kmem_zalloc(sizeof(BnxeFcoeState), 267*d14abf15SRobert Mustacchi KM_NOSLEEP)) == NULL) 268*d14abf15SRobert Mustacchi { 269*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate memory for FCoE state"); 270*d14abf15SRobert Mustacchi goto BnxeFcoeOffloadConnWqeWork_error; 271*d14abf15SRobert Mustacchi } 272*d14abf15SRobert Mustacchi 273*d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_OFFLOAD(pUM); 274*d14abf15SRobert Mustacchi rc = lm_fc_init_fcoe_state(&pUM->lm_dev, 275*d14abf15SRobert Mustacchi &pUM->lm_dev.fcoe_info.run_time.state_blk, 276*d14abf15SRobert Mustacchi &pFcoeState->lm_fcoe); 277*d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_OFFLOAD(pUM); 278*d14abf15SRobert Mustacchi 279*d14abf15SRobert Mustacchi if (rc != LM_STATUS_SUCCESS) 280*d14abf15SRobert Mustacchi { 281*d14abf15SRobert Mustacchi kmem_free(pFcoeState, sizeof(BnxeFcoeState)); 282*d14abf15SRobert Mustacchi 283*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to initialize FCoE state"); 284*d14abf15SRobert Mustacchi goto BnxeFcoeOffloadConnWqeWork_error; 285*d14abf15SRobert Mustacchi } 286*d14abf15SRobert Mustacchi 287*d14abf15SRobert Mustacchi pFcoeState->lm_fcoe.ofld1 = kwqe[0].conn_offload1; 288*d14abf15SRobert Mustacchi pFcoeState->lm_fcoe.ofld2 = kwqe[1].conn_offload2; 289*d14abf15SRobert Mustacchi pFcoeState->lm_fcoe.ofld3 = kwqe[2].conn_offload3; 290*d14abf15SRobert Mustacchi pFcoeState->lm_fcoe.ofld4 = kwqe[3].conn_offload4; 291*d14abf15SRobert Mustacchi 292*d14abf15SRobert Mustacchi rc = lm_fc_alloc_con_resc(&pUM->lm_dev, &pFcoeState->lm_fcoe); 293*d14abf15SRobert Mustacchi 294*d14abf15SRobert Mustacchi if (rc == LM_STATUS_SUCCESS) 295*d14abf15SRobert Mustacchi { 296*d14abf15SRobert Mustacchi lm_fc_init_fcoe_context(&pUM->lm_dev, &pFcoeState->lm_fcoe); 297*d14abf15SRobert Mustacchi lm_fc_post_offload_ramrod(&pUM->lm_dev, &pFcoeState->lm_fcoe); 298*d14abf15SRobert Mustacchi } 299*d14abf15SRobert Mustacchi else if (rc == LM_STATUS_PENDING) 300*d14abf15SRobert Mustacchi { 301*d14abf15SRobert Mustacchi /* 302*d14abf15SRobert Mustacchi * the cid is pending - its too soon to initialize the context, it will 303*d14abf15SRobert Mustacchi * be initialized from the recycle cid callback and completed as well. 304*d14abf15SRobert Mustacchi */ 305*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "lm_fc_alloc_con_resc returned pending?"); 306*d14abf15SRobert Mustacchi } 307*d14abf15SRobert Mustacchi else 308*d14abf15SRobert Mustacchi { 309*d14abf15SRobert Mustacchi BnxeFcoeFreeResc(pUM, pFcoeState); 310*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "lm_fc_alloc_con_resc failed (%d)", rc); 311*d14abf15SRobert Mustacchi goto BnxeFcoeOffloadConnWqeWork_error; 312*d14abf15SRobert Mustacchi } 313*d14abf15SRobert Mustacchi 314*d14abf15SRobert Mustacchi pUM->fcoe.stats.offloadConnWqeTx++; 315*d14abf15SRobert Mustacchi 316*d14abf15SRobert Mustacchi return; 317*d14abf15SRobert Mustacchi 318*d14abf15SRobert Mustacchi BnxeFcoeOffloadConnWqeWork_error: 319*d14abf15SRobert Mustacchi 320*d14abf15SRobert Mustacchi pUM->fcoe.stats.offloadConnWqeTxErr++; 321*d14abf15SRobert Mustacchi 322*d14abf15SRobert Mustacchi kcqe.op_code = FCOE_KCQE_OPCODE_OFFLOAD_CONN; 323*d14abf15SRobert Mustacchi kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 324*d14abf15SRobert Mustacchi kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE); 325*d14abf15SRobert Mustacchi kcqe.fcoe_conn_id = kwqe[0].conn_offload1.fcoe_conn_id; 326*d14abf15SRobert Mustacchi 327*d14abf15SRobert Mustacchi /* call here directly (for error case) */ 328*d14abf15SRobert Mustacchi 329*d14abf15SRobert Mustacchi /* XXX 330*d14abf15SRobert Mustacchi * Need to add a mutex or reference count to ensure that bnxef isn't 331*d14abf15SRobert Mustacchi * unloaded underneath this taskq dispatch routine. 332*d14abf15SRobert Mustacchi */ 333*d14abf15SRobert Mustacchi 334*d14abf15SRobert Mustacchi { 335*d14abf15SRobert Mustacchi struct fcoe_kcqe * pKcqe = &kcqe; 336*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 337*d14abf15SRobert Mustacchi pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 338*d14abf15SRobert Mustacchi (void **)&pKcqe, 1); 339*d14abf15SRobert Mustacchi } 340*d14abf15SRobert Mustacchi 341*d14abf15SRobert Mustacchi /* XXX release mutex or decrement reference count */ 342*d14abf15SRobert Mustacchi } 343*d14abf15SRobert Mustacchi 344*d14abf15SRobert Mustacchi 345*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeOffloadConnWqe(um_device_t * pUM, 346*d14abf15SRobert Mustacchi union fcoe_kwqe ** kwqes) 347*d14abf15SRobert Mustacchi { 348*d14abf15SRobert Mustacchi union fcoe_kwqe wqe[4]; 349*d14abf15SRobert Mustacchi 350*d14abf15SRobert Mustacchi wqe[0] =*(kwqes[0]); 351*d14abf15SRobert Mustacchi wqe[1] =*(kwqes[1]); 352*d14abf15SRobert Mustacchi wqe[2] =*(kwqes[2]); 353*d14abf15SRobert Mustacchi wqe[3] =*(kwqes[3]); 354*d14abf15SRobert Mustacchi 355*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeOffloadConnWqeWork, 356*d14abf15SRobert Mustacchi wqe, sizeof(wqe)); 357*d14abf15SRobert Mustacchi } 358*d14abf15SRobert Mustacchi 359*d14abf15SRobert Mustacchi 360*d14abf15SRobert Mustacchi static void BnxeFcoeEnableConnCqeWork(um_device_t * pUM, 361*d14abf15SRobert Mustacchi void * pData, 362*d14abf15SRobert Mustacchi u32_t dataLen) 363*d14abf15SRobert Mustacchi { 364*d14abf15SRobert Mustacchi if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen)) 365*d14abf15SRobert Mustacchi { 366*d14abf15SRobert Mustacchi pUM->fcoe.stats.enableConnCqeRxErr++; 367*d14abf15SRobert Mustacchi } 368*d14abf15SRobert Mustacchi else 369*d14abf15SRobert Mustacchi { 370*d14abf15SRobert Mustacchi pUM->fcoe.stats.enableConnCqeRx++; 371*d14abf15SRobert Mustacchi } 372*d14abf15SRobert Mustacchi } 373*d14abf15SRobert Mustacchi 374*d14abf15SRobert Mustacchi 375*d14abf15SRobert Mustacchi boolean_t BnxeFcoeEnableConnCqe(um_device_t * pUM, 376*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState, 377*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe) 378*d14abf15SRobert Mustacchi { 379*d14abf15SRobert Mustacchi struct fcoe_kcqe tmp_kcqe = {0}; 380*d14abf15SRobert Mustacchi 381*d14abf15SRobert Mustacchi tmp_kcqe.op_code = FCOE_KCQE_OPCODE_ENABLE_CONN; 382*d14abf15SRobert Mustacchi 383*d14abf15SRobert Mustacchi tmp_kcqe.flags |= 384*d14abf15SRobert Mustacchi (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 385*d14abf15SRobert Mustacchi 386*d14abf15SRobert Mustacchi tmp_kcqe.fcoe_conn_context_id = kcqe->fcoe_conn_context_id; 387*d14abf15SRobert Mustacchi tmp_kcqe.fcoe_conn_id = kcqe->fcoe_conn_id; 388*d14abf15SRobert Mustacchi 389*d14abf15SRobert Mustacchi tmp_kcqe.completion_status = 390*d14abf15SRobert Mustacchi mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ? 391*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_SUCCESS : 392*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE); 393*d14abf15SRobert Mustacchi 394*d14abf15SRobert Mustacchi if (pFcoeState != NULL) 395*d14abf15SRobert Mustacchi { 396*d14abf15SRobert Mustacchi pFcoeState->lm_fcoe.hdr.status = 397*d14abf15SRobert Mustacchi (mm_le32_to_cpu(kcqe->completion_status) == 0) ? 398*d14abf15SRobert Mustacchi STATE_STATUS_NORMAL : 399*d14abf15SRobert Mustacchi STATE_STATUS_INIT_OFFLOAD_ERR; 400*d14abf15SRobert Mustacchi } 401*d14abf15SRobert Mustacchi 402*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeEnableConnCqeWork, 403*d14abf15SRobert Mustacchi &tmp_kcqe, sizeof(tmp_kcqe)); 404*d14abf15SRobert Mustacchi } 405*d14abf15SRobert Mustacchi 406*d14abf15SRobert Mustacchi 407*d14abf15SRobert Mustacchi static void BnxeFcoeEnableConnWqeWork(um_device_t * pUM, 408*d14abf15SRobert Mustacchi void * pData, 409*d14abf15SRobert Mustacchi u32_t dataLen) 410*d14abf15SRobert Mustacchi { 411*d14abf15SRobert Mustacchi union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData; 412*d14abf15SRobert Mustacchi struct fcoe_kcqe kcqe = {0}; 413*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState; 414*d14abf15SRobert Mustacchi 415*d14abf15SRobert Mustacchi if (dataLen != sizeof(*kwqe)) 416*d14abf15SRobert Mustacchi { 417*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Enable Conn WQE"); 418*d14abf15SRobert Mustacchi pUM->fcoe.stats.enableConnWqeTxErr++; 419*d14abf15SRobert Mustacchi return; 420*d14abf15SRobert Mustacchi } 421*d14abf15SRobert Mustacchi 422*d14abf15SRobert Mustacchi pFcoeState = 423*d14abf15SRobert Mustacchi lm_cid_cookie(&pUM->lm_dev, 424*d14abf15SRobert Mustacchi FCOE_CONNECTION_TYPE, 425*d14abf15SRobert Mustacchi SW_CID(mm_le32_to_cpu(kwqe->conn_enable_disable.context_id))); 426*d14abf15SRobert Mustacchi 427*d14abf15SRobert Mustacchi if (pFcoeState == NULL) 428*d14abf15SRobert Mustacchi { 429*d14abf15SRobert Mustacchi goto BnxeFcoeEnableConnWqeWork_error; 430*d14abf15SRobert Mustacchi } 431*d14abf15SRobert Mustacchi 432*d14abf15SRobert Mustacchi if (lm_fc_post_enable_ramrod(&pUM->lm_dev, 433*d14abf15SRobert Mustacchi &pFcoeState->lm_fcoe, 434*d14abf15SRobert Mustacchi &kwqe->conn_enable_disable) != 435*d14abf15SRobert Mustacchi LM_STATUS_SUCCESS) 436*d14abf15SRobert Mustacchi { 437*d14abf15SRobert Mustacchi goto BnxeFcoeEnableConnWqeWork_error; 438*d14abf15SRobert Mustacchi } 439*d14abf15SRobert Mustacchi 440*d14abf15SRobert Mustacchi pUM->fcoe.stats.enableConnWqeTx++; 441*d14abf15SRobert Mustacchi 442*d14abf15SRobert Mustacchi return; 443*d14abf15SRobert Mustacchi 444*d14abf15SRobert Mustacchi BnxeFcoeEnableConnWqeWork_error: 445*d14abf15SRobert Mustacchi 446*d14abf15SRobert Mustacchi pUM->fcoe.stats.enableConnWqeTxErr++; 447*d14abf15SRobert Mustacchi 448*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to post FCoE Enable Conn WQE"); 449*d14abf15SRobert Mustacchi 450*d14abf15SRobert Mustacchi kcqe.op_code = FCOE_KCQE_OPCODE_ENABLE_CONN; 451*d14abf15SRobert Mustacchi kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 452*d14abf15SRobert Mustacchi kcqe.fcoe_conn_context_id = kwqe->conn_enable_disable.context_id; 453*d14abf15SRobert Mustacchi kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 454*d14abf15SRobert Mustacchi 455*d14abf15SRobert Mustacchi /* call here directly (for error case) */ 456*d14abf15SRobert Mustacchi 457*d14abf15SRobert Mustacchi /* XXX 458*d14abf15SRobert Mustacchi * Need to add a mutex or reference count to ensure that bnxef isn't 459*d14abf15SRobert Mustacchi * unloaded underneath this taskq dispatch routine. 460*d14abf15SRobert Mustacchi */ 461*d14abf15SRobert Mustacchi 462*d14abf15SRobert Mustacchi { 463*d14abf15SRobert Mustacchi struct fcoe_kcqe * pKcqe = &kcqe; 464*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 465*d14abf15SRobert Mustacchi pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 466*d14abf15SRobert Mustacchi (void **)&pKcqe, 1); 467*d14abf15SRobert Mustacchi } 468*d14abf15SRobert Mustacchi 469*d14abf15SRobert Mustacchi /* XXX release mutex or decrement reference count */ 470*d14abf15SRobert Mustacchi } 471*d14abf15SRobert Mustacchi 472*d14abf15SRobert Mustacchi 473*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeEnableConnWqe(um_device_t * pUM, 474*d14abf15SRobert Mustacchi union fcoe_kwqe ** kwqes) 475*d14abf15SRobert Mustacchi { 476*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeEnableConnWqeWork, 477*d14abf15SRobert Mustacchi kwqes[0], sizeof(*(kwqes[0]))); 478*d14abf15SRobert Mustacchi } 479*d14abf15SRobert Mustacchi 480*d14abf15SRobert Mustacchi 481*d14abf15SRobert Mustacchi static void BnxeFcoeDisableConnCqeWork(um_device_t * pUM, 482*d14abf15SRobert Mustacchi void * pData, 483*d14abf15SRobert Mustacchi u32_t dataLen) 484*d14abf15SRobert Mustacchi { 485*d14abf15SRobert Mustacchi if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen)) 486*d14abf15SRobert Mustacchi { 487*d14abf15SRobert Mustacchi pUM->fcoe.stats.disableConnCqeRxErr++; 488*d14abf15SRobert Mustacchi } 489*d14abf15SRobert Mustacchi else 490*d14abf15SRobert Mustacchi { 491*d14abf15SRobert Mustacchi pUM->fcoe.stats.disableConnCqeRx++; 492*d14abf15SRobert Mustacchi } 493*d14abf15SRobert Mustacchi } 494*d14abf15SRobert Mustacchi 495*d14abf15SRobert Mustacchi 496*d14abf15SRobert Mustacchi boolean_t BnxeFcoeDisableConnCqe(um_device_t * pUM, 497*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState, 498*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe) 499*d14abf15SRobert Mustacchi { 500*d14abf15SRobert Mustacchi struct fcoe_kcqe tmp_kcqe = {0}; 501*d14abf15SRobert Mustacchi 502*d14abf15SRobert Mustacchi tmp_kcqe.op_code = FCOE_KCQE_OPCODE_DISABLE_CONN; 503*d14abf15SRobert Mustacchi 504*d14abf15SRobert Mustacchi tmp_kcqe.flags |= 505*d14abf15SRobert Mustacchi (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 506*d14abf15SRobert Mustacchi 507*d14abf15SRobert Mustacchi tmp_kcqe.fcoe_conn_context_id = kcqe->fcoe_conn_context_id; 508*d14abf15SRobert Mustacchi tmp_kcqe.fcoe_conn_id = kcqe->fcoe_conn_id; 509*d14abf15SRobert Mustacchi 510*d14abf15SRobert Mustacchi tmp_kcqe.completion_status = 511*d14abf15SRobert Mustacchi mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ? 512*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_SUCCESS : 513*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 514*d14abf15SRobert Mustacchi 515*d14abf15SRobert Mustacchi if (pFcoeState != NULL) 516*d14abf15SRobert Mustacchi { 517*d14abf15SRobert Mustacchi pFcoeState->lm_fcoe.hdr.status = 518*d14abf15SRobert Mustacchi (mm_le32_to_cpu(kcqe->completion_status) == 0) ? 519*d14abf15SRobert Mustacchi STATE_STATUS_NORMAL : 520*d14abf15SRobert Mustacchi STATE_STATUS_INIT_OFFLOAD_ERR; 521*d14abf15SRobert Mustacchi } 522*d14abf15SRobert Mustacchi 523*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeDisableConnCqeWork, 524*d14abf15SRobert Mustacchi &tmp_kcqe, sizeof(tmp_kcqe)); 525*d14abf15SRobert Mustacchi } 526*d14abf15SRobert Mustacchi 527*d14abf15SRobert Mustacchi 528*d14abf15SRobert Mustacchi static void BnxeFcoeDisableConnWqeWork(um_device_t * pUM, 529*d14abf15SRobert Mustacchi void * pData, 530*d14abf15SRobert Mustacchi u32_t dataLen) 531*d14abf15SRobert Mustacchi { 532*d14abf15SRobert Mustacchi union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData; 533*d14abf15SRobert Mustacchi struct fcoe_kcqe kcqe = {0}; 534*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState; 535*d14abf15SRobert Mustacchi 536*d14abf15SRobert Mustacchi if (dataLen != sizeof(*kwqe)) 537*d14abf15SRobert Mustacchi { 538*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Disable Conn WQE"); 539*d14abf15SRobert Mustacchi pUM->fcoe.stats.disableConnWqeTxErr++; 540*d14abf15SRobert Mustacchi return; 541*d14abf15SRobert Mustacchi } 542*d14abf15SRobert Mustacchi 543*d14abf15SRobert Mustacchi pFcoeState = 544*d14abf15SRobert Mustacchi lm_cid_cookie(&pUM->lm_dev, 545*d14abf15SRobert Mustacchi FCOE_CONNECTION_TYPE, 546*d14abf15SRobert Mustacchi SW_CID(mm_le32_to_cpu(kwqe->conn_enable_disable.context_id))); 547*d14abf15SRobert Mustacchi 548*d14abf15SRobert Mustacchi if (pFcoeState == NULL) 549*d14abf15SRobert Mustacchi { 550*d14abf15SRobert Mustacchi goto BnxeFcoeDisableConnWqeWork_error; 551*d14abf15SRobert Mustacchi } 552*d14abf15SRobert Mustacchi 553*d14abf15SRobert Mustacchi if (lm_fc_post_disable_ramrod(&pUM->lm_dev, 554*d14abf15SRobert Mustacchi &pFcoeState->lm_fcoe, 555*d14abf15SRobert Mustacchi &kwqe->conn_enable_disable) != 556*d14abf15SRobert Mustacchi LM_STATUS_SUCCESS) 557*d14abf15SRobert Mustacchi { 558*d14abf15SRobert Mustacchi goto BnxeFcoeDisableConnWqeWork_error; 559*d14abf15SRobert Mustacchi } 560*d14abf15SRobert Mustacchi 561*d14abf15SRobert Mustacchi pUM->fcoe.stats.disableConnWqeTx++; 562*d14abf15SRobert Mustacchi 563*d14abf15SRobert Mustacchi return; 564*d14abf15SRobert Mustacchi 565*d14abf15SRobert Mustacchi BnxeFcoeDisableConnWqeWork_error: 566*d14abf15SRobert Mustacchi 567*d14abf15SRobert Mustacchi pUM->fcoe.stats.disableConnWqeTxErr++; 568*d14abf15SRobert Mustacchi 569*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to post FCoE Disable Conn WQE"); 570*d14abf15SRobert Mustacchi 571*d14abf15SRobert Mustacchi kcqe.op_code = FCOE_KCQE_OPCODE_DISABLE_CONN; 572*d14abf15SRobert Mustacchi kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 573*d14abf15SRobert Mustacchi kcqe.fcoe_conn_context_id = kwqe->conn_enable_disable.context_id; 574*d14abf15SRobert Mustacchi kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 575*d14abf15SRobert Mustacchi 576*d14abf15SRobert Mustacchi /* call here directly (for error case) */ 577*d14abf15SRobert Mustacchi 578*d14abf15SRobert Mustacchi /* XXX 579*d14abf15SRobert Mustacchi * Need to add a mutex or reference count to ensure that bnxef isn't 580*d14abf15SRobert Mustacchi * unloaded underneath this taskq dispatch routine. 581*d14abf15SRobert Mustacchi */ 582*d14abf15SRobert Mustacchi 583*d14abf15SRobert Mustacchi { 584*d14abf15SRobert Mustacchi struct fcoe_kcqe * pKcqe = &kcqe; 585*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 586*d14abf15SRobert Mustacchi pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 587*d14abf15SRobert Mustacchi (void **)&pKcqe, 1); 588*d14abf15SRobert Mustacchi } 589*d14abf15SRobert Mustacchi 590*d14abf15SRobert Mustacchi /* XXX release mutex or decrement reference count */ 591*d14abf15SRobert Mustacchi } 592*d14abf15SRobert Mustacchi 593*d14abf15SRobert Mustacchi 594*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeDisableConnWqe(um_device_t * pUM, 595*d14abf15SRobert Mustacchi union fcoe_kwqe ** kwqes) 596*d14abf15SRobert Mustacchi { 597*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeDisableConnWqeWork, 598*d14abf15SRobert Mustacchi kwqes[0], sizeof(*(kwqes[0]))); 599*d14abf15SRobert Mustacchi } 600*d14abf15SRobert Mustacchi 601*d14abf15SRobert Mustacchi 602*d14abf15SRobert Mustacchi static void BnxeFcoeDestroyConnCqeWork(um_device_t * pUM, 603*d14abf15SRobert Mustacchi void * pData, 604*d14abf15SRobert Mustacchi u32_t dataLen) 605*d14abf15SRobert Mustacchi { 606*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe = (struct fcoe_kcqe *)pData; 607*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState; 608*d14abf15SRobert Mustacchi 609*d14abf15SRobert Mustacchi if (dataLen != (sizeof(*kcqe))) 610*d14abf15SRobert Mustacchi { 611*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Destroy Conn CQE"); 612*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyConnCqeRxErr++; 613*d14abf15SRobert Mustacchi return; 614*d14abf15SRobert Mustacchi } 615*d14abf15SRobert Mustacchi 616*d14abf15SRobert Mustacchi pFcoeState = 617*d14abf15SRobert Mustacchi lm_cid_cookie(&pUM->lm_dev, 618*d14abf15SRobert Mustacchi FCOE_CONNECTION_TYPE, 619*d14abf15SRobert Mustacchi SW_CID(mm_le32_to_cpu(kcqe->fcoe_conn_context_id))); 620*d14abf15SRobert Mustacchi 621*d14abf15SRobert Mustacchi BnxeFcoeFreeResc(pUM, pFcoeState); 622*d14abf15SRobert Mustacchi 623*d14abf15SRobert Mustacchi if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen)) 624*d14abf15SRobert Mustacchi { 625*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyConnCqeRxErr++; 626*d14abf15SRobert Mustacchi } 627*d14abf15SRobert Mustacchi else 628*d14abf15SRobert Mustacchi { 629*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyConnCqeRx++; 630*d14abf15SRobert Mustacchi } 631*d14abf15SRobert Mustacchi } 632*d14abf15SRobert Mustacchi 633*d14abf15SRobert Mustacchi 634*d14abf15SRobert Mustacchi boolean_t BnxeFcoeDestroyConnCqe(um_device_t * pUM, 635*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState, 636*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe) 637*d14abf15SRobert Mustacchi { 638*d14abf15SRobert Mustacchi struct fcoe_kcqe tmp_kcqe = {0}; 639*d14abf15SRobert Mustacchi 640*d14abf15SRobert Mustacchi tmp_kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_CONN; 641*d14abf15SRobert Mustacchi 642*d14abf15SRobert Mustacchi tmp_kcqe.flags |= 643*d14abf15SRobert Mustacchi (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 644*d14abf15SRobert Mustacchi 645*d14abf15SRobert Mustacchi tmp_kcqe.fcoe_conn_context_id = kcqe->fcoe_conn_context_id; 646*d14abf15SRobert Mustacchi tmp_kcqe.fcoe_conn_id = kcqe->fcoe_conn_id; 647*d14abf15SRobert Mustacchi 648*d14abf15SRobert Mustacchi tmp_kcqe.completion_status = 649*d14abf15SRobert Mustacchi mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ? 650*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_SUCCESS : 651*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 652*d14abf15SRobert Mustacchi 653*d14abf15SRobert Mustacchi if (pFcoeState != NULL) 654*d14abf15SRobert Mustacchi { 655*d14abf15SRobert Mustacchi pFcoeState->lm_fcoe.hdr.status = 656*d14abf15SRobert Mustacchi (mm_le32_to_cpu(kcqe->completion_status) == 0) ? 657*d14abf15SRobert Mustacchi STATE_STATUS_NORMAL : 658*d14abf15SRobert Mustacchi STATE_STATUS_INIT_OFFLOAD_ERR; 659*d14abf15SRobert Mustacchi } 660*d14abf15SRobert Mustacchi 661*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeDestroyConnCqeWork, 662*d14abf15SRobert Mustacchi &tmp_kcqe, sizeof(tmp_kcqe)); 663*d14abf15SRobert Mustacchi } 664*d14abf15SRobert Mustacchi 665*d14abf15SRobert Mustacchi 666*d14abf15SRobert Mustacchi static void BnxeFcoeDestroyConnWqeWork(um_device_t * pUM, 667*d14abf15SRobert Mustacchi void * pData, 668*d14abf15SRobert Mustacchi u32_t dataLen) 669*d14abf15SRobert Mustacchi { 670*d14abf15SRobert Mustacchi union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData; 671*d14abf15SRobert Mustacchi struct fcoe_kcqe kcqe = {0}; 672*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState; 673*d14abf15SRobert Mustacchi 674*d14abf15SRobert Mustacchi if (dataLen != sizeof(*kwqe)) 675*d14abf15SRobert Mustacchi { 676*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Destroy Conn WQE"); 677*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyConnWqeTxErr++; 678*d14abf15SRobert Mustacchi return; 679*d14abf15SRobert Mustacchi } 680*d14abf15SRobert Mustacchi 681*d14abf15SRobert Mustacchi pFcoeState = 682*d14abf15SRobert Mustacchi lm_cid_cookie(&pUM->lm_dev, 683*d14abf15SRobert Mustacchi FCOE_CONNECTION_TYPE, 684*d14abf15SRobert Mustacchi SW_CID(mm_le32_to_cpu(kwqe->conn_destroy.context_id))); 685*d14abf15SRobert Mustacchi 686*d14abf15SRobert Mustacchi if (pFcoeState == NULL) 687*d14abf15SRobert Mustacchi { 688*d14abf15SRobert Mustacchi goto BnxeFcoeDestroyConnWqeWork_error; 689*d14abf15SRobert Mustacchi } 690*d14abf15SRobert Mustacchi 691*d14abf15SRobert Mustacchi if (lm_fc_post_terminate_ramrod(&pUM->lm_dev, 692*d14abf15SRobert Mustacchi &pFcoeState->lm_fcoe) != 693*d14abf15SRobert Mustacchi LM_STATUS_SUCCESS) 694*d14abf15SRobert Mustacchi { 695*d14abf15SRobert Mustacchi goto BnxeFcoeDestroyConnWqeWork_error; 696*d14abf15SRobert Mustacchi } 697*d14abf15SRobert Mustacchi 698*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyConnWqeTx++; 699*d14abf15SRobert Mustacchi 700*d14abf15SRobert Mustacchi return; 701*d14abf15SRobert Mustacchi 702*d14abf15SRobert Mustacchi BnxeFcoeDestroyConnWqeWork_error: 703*d14abf15SRobert Mustacchi 704*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyConnWqeTxErr++; 705*d14abf15SRobert Mustacchi 706*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to post FCoE Destroy Conn WQE"); 707*d14abf15SRobert Mustacchi 708*d14abf15SRobert Mustacchi kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_CONN; 709*d14abf15SRobert Mustacchi kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 710*d14abf15SRobert Mustacchi kcqe.fcoe_conn_context_id = kwqe->conn_destroy.context_id; 711*d14abf15SRobert Mustacchi kcqe.fcoe_conn_id = kwqe->conn_destroy.conn_id; 712*d14abf15SRobert Mustacchi kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 713*d14abf15SRobert Mustacchi 714*d14abf15SRobert Mustacchi /* call here directly (for error case) */ 715*d14abf15SRobert Mustacchi 716*d14abf15SRobert Mustacchi /* XXX 717*d14abf15SRobert Mustacchi * Need to add a mutex or reference count to ensure that bnxef isn't 718*d14abf15SRobert Mustacchi * unloaded underneath this taskq dispatch routine. 719*d14abf15SRobert Mustacchi */ 720*d14abf15SRobert Mustacchi 721*d14abf15SRobert Mustacchi { 722*d14abf15SRobert Mustacchi struct fcoe_kcqe * pKcqe = &kcqe; 723*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 724*d14abf15SRobert Mustacchi pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 725*d14abf15SRobert Mustacchi (void **)&pKcqe, 1); 726*d14abf15SRobert Mustacchi } 727*d14abf15SRobert Mustacchi 728*d14abf15SRobert Mustacchi /* XXX release mutex or decrement reference count */ 729*d14abf15SRobert Mustacchi } 730*d14abf15SRobert Mustacchi 731*d14abf15SRobert Mustacchi 732*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeDestroyConnWqe(um_device_t * pUM, 733*d14abf15SRobert Mustacchi union fcoe_kwqe ** kwqes) 734*d14abf15SRobert Mustacchi { 735*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeDestroyConnWqeWork, 736*d14abf15SRobert Mustacchi kwqes[0], sizeof(*(kwqes[0]))); 737*d14abf15SRobert Mustacchi } 738*d14abf15SRobert Mustacchi 739*d14abf15SRobert Mustacchi 740*d14abf15SRobert Mustacchi static void BnxeFcoeDestroyCqeWork(um_device_t * pUM, 741*d14abf15SRobert Mustacchi void * pData, 742*d14abf15SRobert Mustacchi u32_t dataLen) 743*d14abf15SRobert Mustacchi { 744*d14abf15SRobert Mustacchi if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen)) 745*d14abf15SRobert Mustacchi { 746*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyCqeRxErr++; 747*d14abf15SRobert Mustacchi } 748*d14abf15SRobert Mustacchi else 749*d14abf15SRobert Mustacchi { 750*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyCqeRx++; 751*d14abf15SRobert Mustacchi } 752*d14abf15SRobert Mustacchi } 753*d14abf15SRobert Mustacchi 754*d14abf15SRobert Mustacchi 755*d14abf15SRobert Mustacchi boolean_t BnxeFcoeDestroyCqe(um_device_t * pUM, 756*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe) 757*d14abf15SRobert Mustacchi { 758*d14abf15SRobert Mustacchi struct fcoe_kcqe tmp_kcqe = {0}; 759*d14abf15SRobert Mustacchi 760*d14abf15SRobert Mustacchi tmp_kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_FUNC; 761*d14abf15SRobert Mustacchi 762*d14abf15SRobert Mustacchi tmp_kcqe.flags |= 763*d14abf15SRobert Mustacchi (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 764*d14abf15SRobert Mustacchi 765*d14abf15SRobert Mustacchi tmp_kcqe.completion_status = 766*d14abf15SRobert Mustacchi mm_le32_to_cpu((mm_le32_to_cpu(kcqe->completion_status) == 0) ? 767*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_SUCCESS : 768*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 769*d14abf15SRobert Mustacchi 770*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeDestroyCqeWork, 771*d14abf15SRobert Mustacchi &tmp_kcqe, sizeof(tmp_kcqe)); 772*d14abf15SRobert Mustacchi } 773*d14abf15SRobert Mustacchi 774*d14abf15SRobert Mustacchi 775*d14abf15SRobert Mustacchi static void BnxeFcoeDestroyWqeWork(um_device_t * pUM, 776*d14abf15SRobert Mustacchi void * pData, 777*d14abf15SRobert Mustacchi u32_t dataLen) 778*d14abf15SRobert Mustacchi { 779*d14abf15SRobert Mustacchi union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData; 780*d14abf15SRobert Mustacchi struct fcoe_kcqe kcqe = {0}; 781*d14abf15SRobert Mustacchi BnxeFcoeState * pFcoeState; 782*d14abf15SRobert Mustacchi 783*d14abf15SRobert Mustacchi if (dataLen != sizeof(*kwqe)) 784*d14abf15SRobert Mustacchi { 785*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Destroy WQE"); 786*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyWqeTxErr++; 787*d14abf15SRobert Mustacchi return; 788*d14abf15SRobert Mustacchi } 789*d14abf15SRobert Mustacchi 790*d14abf15SRobert Mustacchi if (lm_fc_post_destroy_ramrod(&pUM->lm_dev) == LM_STATUS_SUCCESS) 791*d14abf15SRobert Mustacchi { 792*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyWqeTx++; 793*d14abf15SRobert Mustacchi return; 794*d14abf15SRobert Mustacchi } 795*d14abf15SRobert Mustacchi 796*d14abf15SRobert Mustacchi pUM->fcoe.stats.destroyWqeTxErr++; 797*d14abf15SRobert Mustacchi 798*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to post FCoE Destroy WQE"); 799*d14abf15SRobert Mustacchi 800*d14abf15SRobert Mustacchi kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_FUNC; 801*d14abf15SRobert Mustacchi kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 802*d14abf15SRobert Mustacchi kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 803*d14abf15SRobert Mustacchi 804*d14abf15SRobert Mustacchi /* call here directly (for error case) */ 805*d14abf15SRobert Mustacchi 806*d14abf15SRobert Mustacchi /* XXX 807*d14abf15SRobert Mustacchi * Need to add a mutex or reference count to ensure that bnxef isn't 808*d14abf15SRobert Mustacchi * unloaded underneath this taskq dispatch routine. 809*d14abf15SRobert Mustacchi */ 810*d14abf15SRobert Mustacchi 811*d14abf15SRobert Mustacchi { 812*d14abf15SRobert Mustacchi struct fcoe_kcqe * pKcqe = &kcqe; 813*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 814*d14abf15SRobert Mustacchi pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 815*d14abf15SRobert Mustacchi (void **)&pKcqe, 1); 816*d14abf15SRobert Mustacchi } 817*d14abf15SRobert Mustacchi 818*d14abf15SRobert Mustacchi /* XXX release mutex or decrement reference count */ 819*d14abf15SRobert Mustacchi } 820*d14abf15SRobert Mustacchi 821*d14abf15SRobert Mustacchi 822*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeDestroyWqe(um_device_t * pUM, 823*d14abf15SRobert Mustacchi union fcoe_kwqe ** kwqes) 824*d14abf15SRobert Mustacchi { 825*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeDestroyWqeWork, 826*d14abf15SRobert Mustacchi kwqes[0], sizeof(*(kwqes[0]))); 827*d14abf15SRobert Mustacchi } 828*d14abf15SRobert Mustacchi 829*d14abf15SRobert Mustacchi 830*d14abf15SRobert Mustacchi static void BnxeFcoeStatCqeWork(um_device_t * pUM, 831*d14abf15SRobert Mustacchi void * pData, 832*d14abf15SRobert Mustacchi u32_t dataLen) 833*d14abf15SRobert Mustacchi { 834*d14abf15SRobert Mustacchi if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen)) 835*d14abf15SRobert Mustacchi { 836*d14abf15SRobert Mustacchi pUM->fcoe.stats.statCqeRxErr++; 837*d14abf15SRobert Mustacchi } 838*d14abf15SRobert Mustacchi else 839*d14abf15SRobert Mustacchi { 840*d14abf15SRobert Mustacchi pUM->fcoe.stats.statCqeRx++; 841*d14abf15SRobert Mustacchi } 842*d14abf15SRobert Mustacchi } 843*d14abf15SRobert Mustacchi 844*d14abf15SRobert Mustacchi 845*d14abf15SRobert Mustacchi boolean_t BnxeFcoeStatCqe(um_device_t * pUM, 846*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe) 847*d14abf15SRobert Mustacchi { 848*d14abf15SRobert Mustacchi struct fcoe_kcqe tmp_kcqe = {0}; 849*d14abf15SRobert Mustacchi 850*d14abf15SRobert Mustacchi tmp_kcqe.op_code = FCOE_KCQE_OPCODE_STAT_FUNC; 851*d14abf15SRobert Mustacchi 852*d14abf15SRobert Mustacchi tmp_kcqe.flags |= 853*d14abf15SRobert Mustacchi (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 854*d14abf15SRobert Mustacchi 855*d14abf15SRobert Mustacchi tmp_kcqe.completion_status = 856*d14abf15SRobert Mustacchi mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ? 857*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_SUCCESS : 858*d14abf15SRobert Mustacchi FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 859*d14abf15SRobert Mustacchi 860*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeStatCqeWork, 861*d14abf15SRobert Mustacchi &tmp_kcqe, sizeof(tmp_kcqe)); 862*d14abf15SRobert Mustacchi } 863*d14abf15SRobert Mustacchi 864*d14abf15SRobert Mustacchi 865*d14abf15SRobert Mustacchi static void BnxeFcoeStatWqeWork(um_device_t * pUM, 866*d14abf15SRobert Mustacchi void * pData, 867*d14abf15SRobert Mustacchi u32_t dataLen) 868*d14abf15SRobert Mustacchi { 869*d14abf15SRobert Mustacchi union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData; 870*d14abf15SRobert Mustacchi struct fcoe_kcqe kcqe = {0}; 871*d14abf15SRobert Mustacchi 872*d14abf15SRobert Mustacchi if (dataLen != sizeof(*kwqe)) 873*d14abf15SRobert Mustacchi { 874*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Stat WQE"); 875*d14abf15SRobert Mustacchi pUM->fcoe.stats.statWqeTxErr++; 876*d14abf15SRobert Mustacchi return; 877*d14abf15SRobert Mustacchi } 878*d14abf15SRobert Mustacchi 879*d14abf15SRobert Mustacchi if (lm_fc_post_stat_ramrod(&pUM->lm_dev, 880*d14abf15SRobert Mustacchi &kwqe->statistics) == LM_STATUS_SUCCESS) 881*d14abf15SRobert Mustacchi { 882*d14abf15SRobert Mustacchi pUM->fcoe.stats.statWqeTx++; 883*d14abf15SRobert Mustacchi return; 884*d14abf15SRobert Mustacchi } 885*d14abf15SRobert Mustacchi 886*d14abf15SRobert Mustacchi pUM->fcoe.stats.statWqeTxErr++; 887*d14abf15SRobert Mustacchi 888*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to post FCoE Stat WQE"); 889*d14abf15SRobert Mustacchi 890*d14abf15SRobert Mustacchi kcqe.op_code = FCOE_KCQE_OPCODE_STAT_FUNC; 891*d14abf15SRobert Mustacchi kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); 892*d14abf15SRobert Mustacchi kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR); 893*d14abf15SRobert Mustacchi 894*d14abf15SRobert Mustacchi /* call here directly (for error case) */ 895*d14abf15SRobert Mustacchi 896*d14abf15SRobert Mustacchi /* XXX 897*d14abf15SRobert Mustacchi * Need to add a mutex or reference count to ensure that bnxef isn't 898*d14abf15SRobert Mustacchi * unloaded underneath this taskq dispatch routine. 899*d14abf15SRobert Mustacchi */ 900*d14abf15SRobert Mustacchi 901*d14abf15SRobert Mustacchi { 902*d14abf15SRobert Mustacchi struct fcoe_kcqe * pKcqe = &kcqe; 903*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 904*d14abf15SRobert Mustacchi pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 905*d14abf15SRobert Mustacchi (void **)&pKcqe, 1); 906*d14abf15SRobert Mustacchi } 907*d14abf15SRobert Mustacchi 908*d14abf15SRobert Mustacchi /* XXX release mutex or decrement reference count */ 909*d14abf15SRobert Mustacchi } 910*d14abf15SRobert Mustacchi 911*d14abf15SRobert Mustacchi 912*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeStatWqe(um_device_t * pUM, 913*d14abf15SRobert Mustacchi union fcoe_kwqe ** kwqes) 914*d14abf15SRobert Mustacchi { 915*d14abf15SRobert Mustacchi return BnxeWorkQueueAdd(pUM, BnxeFcoeStatWqeWork, 916*d14abf15SRobert Mustacchi kwqes[0], sizeof(*(kwqes[0]))); 917*d14abf15SRobert Mustacchi } 918*d14abf15SRobert Mustacchi 919*d14abf15SRobert Mustacchi 920*d14abf15SRobert Mustacchi #define KCQE_LIMIT 64 921*d14abf15SRobert Mustacchi 922*d14abf15SRobert Mustacchi static void BnxeFcoeCompRequestCqeWork(um_device_t * pUM, 923*d14abf15SRobert Mustacchi void * pData, 924*d14abf15SRobert Mustacchi u32_t dataLen) 925*d14abf15SRobert Mustacchi { 926*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqe_arr = (struct fcoe_kcqe *)pData; 927*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqes[KCQE_LIMIT]; 928*d14abf15SRobert Mustacchi u32_t num_kcqes; 929*d14abf15SRobert Mustacchi int i; 930*d14abf15SRobert Mustacchi 931*d14abf15SRobert Mustacchi if ((dataLen % (sizeof(*kcqe_arr))) != 0) 932*d14abf15SRobert Mustacchi { 933*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid FCoE Comp Request CQE array"); 934*d14abf15SRobert Mustacchi pUM->fcoe.stats.compRequestCqeRxErr++; 935*d14abf15SRobert Mustacchi return; 936*d14abf15SRobert Mustacchi } 937*d14abf15SRobert Mustacchi 938*d14abf15SRobert Mustacchi num_kcqes = (dataLen / (sizeof(*kcqe_arr))); 939*d14abf15SRobert Mustacchi 940*d14abf15SRobert Mustacchi /* init the kcqe pointer array */ 941*d14abf15SRobert Mustacchi 942*d14abf15SRobert Mustacchi for (i = 0; i < num_kcqes; i++) 943*d14abf15SRobert Mustacchi { 944*d14abf15SRobert Mustacchi kcqes[i] = &kcqe_arr[i]; 945*d14abf15SRobert Mustacchi } 946*d14abf15SRobert Mustacchi 947*d14abf15SRobert Mustacchi ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)); 948*d14abf15SRobert Mustacchi 949*d14abf15SRobert Mustacchi if (!pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev, 950*d14abf15SRobert Mustacchi (void **)kcqes, 951*d14abf15SRobert Mustacchi num_kcqes)) 952*d14abf15SRobert Mustacchi { 953*d14abf15SRobert Mustacchi pUM->fcoe.stats.compRequestCqeRxErr++; 954*d14abf15SRobert Mustacchi } 955*d14abf15SRobert Mustacchi else 956*d14abf15SRobert Mustacchi { 957*d14abf15SRobert Mustacchi pUM->fcoe.stats.compRequestCqeRx += num_kcqes; 958*d14abf15SRobert Mustacchi } 959*d14abf15SRobert Mustacchi } 960*d14abf15SRobert Mustacchi 961*d14abf15SRobert Mustacchi 962*d14abf15SRobert Mustacchi boolean_t BnxeFcoeCompRequestCqe(um_device_t * pUM, 963*d14abf15SRobert Mustacchi struct fcoe_kcqe * kcqes, 964*d14abf15SRobert Mustacchi u32_t num_kcqes) 965*d14abf15SRobert Mustacchi { 966*d14abf15SRobert Mustacchi u32_t kcqesIdx = 0; 967*d14abf15SRobert Mustacchi u32_t kcqesLimit = 0; 968*d14abf15SRobert Mustacchi u32_t numUp; 969*d14abf15SRobert Mustacchi 970*d14abf15SRobert Mustacchi /* Send up KCQE_LIMIT kcqes at a time... */ 971*d14abf15SRobert Mustacchi 972*d14abf15SRobert Mustacchi while (kcqesIdx < num_kcqes) 973*d14abf15SRobert Mustacchi { 974*d14abf15SRobert Mustacchi if (num_kcqes - kcqesIdx > KCQE_LIMIT) 975*d14abf15SRobert Mustacchi { 976*d14abf15SRobert Mustacchi kcqesLimit += KCQE_LIMIT; 977*d14abf15SRobert Mustacchi } 978*d14abf15SRobert Mustacchi else 979*d14abf15SRobert Mustacchi { 980*d14abf15SRobert Mustacchi kcqesLimit = num_kcqes; 981*d14abf15SRobert Mustacchi } 982*d14abf15SRobert Mustacchi 983*d14abf15SRobert Mustacchi numUp = (kcqesLimit % KCQE_LIMIT == 0) ? KCQE_LIMIT : 984*d14abf15SRobert Mustacchi (kcqesLimit % KCQE_LIMIT); 985*d14abf15SRobert Mustacchi 986*d14abf15SRobert Mustacchi #if 0 987*d14abf15SRobert Mustacchi if (!BnxeWorkQueueAdd(pUM, BnxeFcoeCompRequestCqeWork, 988*d14abf15SRobert Mustacchi kcqes + kcqesIdx, 989*d14abf15SRobert Mustacchi (sizeof(struct fcoe_kcqe) * numUp))) 990*d14abf15SRobert Mustacchi { 991*d14abf15SRobert Mustacchi return B_FALSE; 992*d14abf15SRobert Mustacchi } 993*d14abf15SRobert Mustacchi #else 994*d14abf15SRobert Mustacchi BnxeFcoeCompRequestCqeWork(pUM, 995*d14abf15SRobert Mustacchi kcqes + kcqesIdx, 996*d14abf15SRobert Mustacchi (sizeof(struct fcoe_kcqe) * numUp)); 997*d14abf15SRobert Mustacchi #endif 998*d14abf15SRobert Mustacchi 999*d14abf15SRobert Mustacchi kcqesIdx += (kcqesLimit - kcqesIdx); 1000*d14abf15SRobert Mustacchi } 1001*d14abf15SRobert Mustacchi 1002*d14abf15SRobert Mustacchi return B_TRUE; 1003*d14abf15SRobert Mustacchi } 1004*d14abf15SRobert Mustacchi 1005*d14abf15SRobert Mustacchi 1006*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvCtl(dev_info_t * pDev, 1007*d14abf15SRobert Mustacchi int cmd, 1008*d14abf15SRobert Mustacchi void * pData, 1009*d14abf15SRobert Mustacchi int dataLen) 1010*d14abf15SRobert Mustacchi { 1011*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev); 1012*d14abf15SRobert Mustacchi BnxeFcoeInfo * pFcoeInfo; 1013*d14abf15SRobert Mustacchi int rc, i; 1014*d14abf15SRobert Mustacchi 1015*d14abf15SRobert Mustacchi /* sanity check */ 1016*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev) 1017*d14abf15SRobert Mustacchi { 1018*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__); 1019*d14abf15SRobert Mustacchi return B_FALSE; 1020*d14abf15SRobert Mustacchi } 1021*d14abf15SRobert Mustacchi 1022*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s ***", __func__); 1023*d14abf15SRobert Mustacchi 1024*d14abf15SRobert Mustacchi VERIFY_FCOE_BINDING(pUM); 1025*d14abf15SRobert Mustacchi 1026*d14abf15SRobert Mustacchi switch (cmd) 1027*d14abf15SRobert Mustacchi { 1028*d14abf15SRobert Mustacchi case PRV_CTL_GET_MAC_ADDR: 1029*d14abf15SRobert Mustacchi 1030*d14abf15SRobert Mustacchi if (dataLen < ETHERNET_ADDRESS_SIZE) 1031*d14abf15SRobert Mustacchi { 1032*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid MAC Address buffer length for get (%d)", 1033*d14abf15SRobert Mustacchi dataLen); 1034*d14abf15SRobert Mustacchi return B_FALSE; 1035*d14abf15SRobert Mustacchi } 1036*d14abf15SRobert Mustacchi 1037*d14abf15SRobert Mustacchi if (!pData) 1038*d14abf15SRobert Mustacchi { 1039*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "NULL MAC Address buffer for get"); 1040*d14abf15SRobert Mustacchi return B_FALSE; 1041*d14abf15SRobert Mustacchi } 1042*d14abf15SRobert Mustacchi 1043*d14abf15SRobert Mustacchi COPY_ETH_ADDRESS(pUM->lm_dev.hw_info.fcoe_mac_addr, pData); 1044*d14abf15SRobert Mustacchi 1045*d14abf15SRobert Mustacchi return B_TRUE; 1046*d14abf15SRobert Mustacchi 1047*d14abf15SRobert Mustacchi case PRV_CTL_SET_MAC_ADDR: 1048*d14abf15SRobert Mustacchi 1049*d14abf15SRobert Mustacchi if (dataLen < ETHERNET_ADDRESS_SIZE) 1050*d14abf15SRobert Mustacchi { 1051*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid MAC Address length for set (%d)", 1052*d14abf15SRobert Mustacchi dataLen); 1053*d14abf15SRobert Mustacchi return B_FALSE; 1054*d14abf15SRobert Mustacchi } 1055*d14abf15SRobert Mustacchi 1056*d14abf15SRobert Mustacchi if (!pData) 1057*d14abf15SRobert Mustacchi { 1058*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "NULL MAC Address buffer for set"); 1059*d14abf15SRobert Mustacchi return B_FALSE; 1060*d14abf15SRobert Mustacchi } 1061*d14abf15SRobert Mustacchi 1062*d14abf15SRobert Mustacchi /* Validate MAC address */ 1063*d14abf15SRobert Mustacchi if (IS_ETH_MULTICAST(pData)) 1064*d14abf15SRobert Mustacchi { 1065*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as an MAC Address."); 1066*d14abf15SRobert Mustacchi return B_FALSE; 1067*d14abf15SRobert Mustacchi } 1068*d14abf15SRobert Mustacchi 1069*d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_HWINIT(pUM); 1070*d14abf15SRobert Mustacchi 1071*d14abf15SRobert Mustacchi /* XXX wrong? (overwriting fcoe hw programmed address!) */ 1072*d14abf15SRobert Mustacchi COPY_ETH_ADDRESS(pData, pUM->lm_dev.hw_info.fcoe_mac_addr); 1073*d14abf15SRobert Mustacchi 1074*d14abf15SRobert Mustacchi rc = BnxeMacAddress(pUM, LM_CLI_IDX_FCOE, B_TRUE, 1075*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.fcoe_mac_addr); 1076*d14abf15SRobert Mustacchi 1077*d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_HWINIT(pUM); 1078*d14abf15SRobert Mustacchi 1079*d14abf15SRobert Mustacchi return (rc < 0) ? B_FALSE : B_TRUE; 1080*d14abf15SRobert Mustacchi 1081*d14abf15SRobert Mustacchi case PRV_CTL_QUERY_PARAMS: 1082*d14abf15SRobert Mustacchi 1083*d14abf15SRobert Mustacchi if (dataLen != sizeof(BnxeFcoeInfo)) 1084*d14abf15SRobert Mustacchi { 1085*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid query buffer for FCoE (%d)", 1086*d14abf15SRobert Mustacchi dataLen); 1087*d14abf15SRobert Mustacchi return B_FALSE; 1088*d14abf15SRobert Mustacchi } 1089*d14abf15SRobert Mustacchi 1090*d14abf15SRobert Mustacchi if (!pData) 1091*d14abf15SRobert Mustacchi { 1092*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid query buffer for FCoE"); 1093*d14abf15SRobert Mustacchi return B_FALSE; 1094*d14abf15SRobert Mustacchi } 1095*d14abf15SRobert Mustacchi 1096*d14abf15SRobert Mustacchi pFcoeInfo = (BnxeFcoeInfo *)pData; 1097*d14abf15SRobert Mustacchi 1098*d14abf15SRobert Mustacchi pFcoeInfo->flags = 0; 1099*d14abf15SRobert Mustacchi 1100*d14abf15SRobert Mustacchi /* 1101*d14abf15SRobert Mustacchi * Always set the FORCE_LOAD flags which tells bnxef to perform any 1102*d14abf15SRobert Mustacchi * necessary delays needed when bringing up targets. This allows ample 1103*d14abf15SRobert Mustacchi * time for bnxef to come up and finish for FCoE boot. If we don't 1104*d14abf15SRobert Mustacchi * force a delay then there is a race condition and the kernel won't 1105*d14abf15SRobert Mustacchi * find the root disk. 1106*d14abf15SRobert Mustacchi */ 1107*d14abf15SRobert Mustacchi pFcoeInfo->flags |= FCOE_INFO_FLAG_FORCE_LOAD; 1108*d14abf15SRobert Mustacchi 1109*d14abf15SRobert Mustacchi switch (pUM->lm_dev.params.mf_mode) 1110*d14abf15SRobert Mustacchi { 1111*d14abf15SRobert Mustacchi case SINGLE_FUNCTION: 1112*d14abf15SRobert Mustacchi pFcoeInfo->flags |= FCOE_INFO_FLAG_MF_MODE_SF; 1113*d14abf15SRobert Mustacchi break; 1114*d14abf15SRobert Mustacchi case MULTI_FUNCTION_SD: 1115*d14abf15SRobert Mustacchi pFcoeInfo->flags |= FCOE_INFO_FLAG_MF_MODE_SD; 1116*d14abf15SRobert Mustacchi break; 1117*d14abf15SRobert Mustacchi case MULTI_FUNCTION_SI: 1118*d14abf15SRobert Mustacchi pFcoeInfo->flags |= FCOE_INFO_FLAG_MF_MODE_SI; 1119*d14abf15SRobert Mustacchi break; 1120*d14abf15SRobert Mustacchi case MULTI_FUNCTION_AFEX: 1121*d14abf15SRobert Mustacchi pFcoeInfo->flags |= FCOE_INFO_FLAG_MF_MODE_AFEX; 1122*d14abf15SRobert Mustacchi break; 1123*d14abf15SRobert Mustacchi default: 1124*d14abf15SRobert Mustacchi break; 1125*d14abf15SRobert Mustacchi } 1126*d14abf15SRobert Mustacchi 1127*d14abf15SRobert Mustacchi pFcoeInfo->max_fcoe_conn = pUM->lm_dev.params.max_func_fcoe_cons; 1128*d14abf15SRobert Mustacchi pFcoeInfo->max_fcoe_exchanges = pUM->lm_dev.params.max_fcoe_task; 1129*d14abf15SRobert Mustacchi 1130*d14abf15SRobert Mustacchi memcpy(&pFcoeInfo->wwn, &pUM->fcoe.wwn, sizeof(BnxeWwnInfo)); 1131*d14abf15SRobert Mustacchi 1132*d14abf15SRobert Mustacchi return B_TRUE; 1133*d14abf15SRobert Mustacchi 1134*d14abf15SRobert Mustacchi case PRV_CTL_DISABLE_INTR: 1135*d14abf15SRobert Mustacchi 1136*d14abf15SRobert Mustacchi BnxeIntrIguSbDisable(pUM, FCOE_CID(&pUM->lm_dev), B_FALSE); 1137*d14abf15SRobert Mustacchi return B_TRUE; 1138*d14abf15SRobert Mustacchi 1139*d14abf15SRobert Mustacchi case PRV_CTL_ENABLE_INTR: 1140*d14abf15SRobert Mustacchi 1141*d14abf15SRobert Mustacchi BnxeIntrIguSbEnable(pUM, FCOE_CID(&pUM->lm_dev), B_FALSE); 1142*d14abf15SRobert Mustacchi return B_TRUE; 1143*d14abf15SRobert Mustacchi 1144*d14abf15SRobert Mustacchi case PRV_CTL_MBA_BOOT: 1145*d14abf15SRobert Mustacchi 1146*d14abf15SRobert Mustacchi if (dataLen != sizeof(boolean_t)) 1147*d14abf15SRobert Mustacchi { 1148*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid MBA boot check buffer for FCoE (%d)", 1149*d14abf15SRobert Mustacchi dataLen); 1150*d14abf15SRobert Mustacchi return B_FALSE; 1151*d14abf15SRobert Mustacchi } 1152*d14abf15SRobert Mustacchi 1153*d14abf15SRobert Mustacchi if (!pData) 1154*d14abf15SRobert Mustacchi { 1155*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid MBA boot check buffer for FCoE"); 1156*d14abf15SRobert Mustacchi return B_FALSE; 1157*d14abf15SRobert Mustacchi } 1158*d14abf15SRobert Mustacchi 1159*d14abf15SRobert Mustacchi *((boolean_t *)pData) = 1160*d14abf15SRobert Mustacchi (pUM->iscsiInfo.signature != 0) ? B_TRUE : B_FALSE; 1161*d14abf15SRobert Mustacchi 1162*d14abf15SRobert Mustacchi return B_TRUE; 1163*d14abf15SRobert Mustacchi 1164*d14abf15SRobert Mustacchi case PRV_CTL_LINK_STATE: 1165*d14abf15SRobert Mustacchi 1166*d14abf15SRobert Mustacchi if (dataLen != sizeof(boolean_t)) 1167*d14abf15SRobert Mustacchi { 1168*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid link state buffer for FCoE (%d)", 1169*d14abf15SRobert Mustacchi dataLen); 1170*d14abf15SRobert Mustacchi return B_FALSE; 1171*d14abf15SRobert Mustacchi } 1172*d14abf15SRobert Mustacchi 1173*d14abf15SRobert Mustacchi if (!pData) 1174*d14abf15SRobert Mustacchi { 1175*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid link state buffer for FCoE"); 1176*d14abf15SRobert Mustacchi return B_FALSE; 1177*d14abf15SRobert Mustacchi } 1178*d14abf15SRobert Mustacchi 1179*d14abf15SRobert Mustacchi *((boolean_t *)pData) = 1180*d14abf15SRobert Mustacchi (pUM->devParams.lastIndLink == LM_STATUS_LINK_ACTIVE) ? 1181*d14abf15SRobert Mustacchi B_TRUE : B_FALSE; 1182*d14abf15SRobert Mustacchi 1183*d14abf15SRobert Mustacchi return B_TRUE; 1184*d14abf15SRobert Mustacchi 1185*d14abf15SRobert Mustacchi case PRV_CTL_BOARD_TYPE: 1186*d14abf15SRobert Mustacchi 1187*d14abf15SRobert Mustacchi if (!pData || (dataLen <= 0)) 1188*d14abf15SRobert Mustacchi { 1189*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid board type buffer for FCoE"); 1190*d14abf15SRobert Mustacchi return B_FALSE; 1191*d14abf15SRobert Mustacchi } 1192*d14abf15SRobert Mustacchi 1193*d14abf15SRobert Mustacchi snprintf((char *)pData, dataLen, "%s", pUM->chipName); 1194*d14abf15SRobert Mustacchi 1195*d14abf15SRobert Mustacchi return B_TRUE; 1196*d14abf15SRobert Mustacchi 1197*d14abf15SRobert Mustacchi case PRV_CTL_BOARD_SERNUM: 1198*d14abf15SRobert Mustacchi 1199*d14abf15SRobert Mustacchi if (!pData || (dataLen <= 0)) 1200*d14abf15SRobert Mustacchi { 1201*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid board serial number buffer for FCoE"); 1202*d14abf15SRobert Mustacchi return B_FALSE; 1203*d14abf15SRobert Mustacchi } 1204*d14abf15SRobert Mustacchi 1205*d14abf15SRobert Mustacchi snprintf((char *)pData, dataLen, 1206*d14abf15SRobert Mustacchi "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 1207*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[0], 1208*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[1], 1209*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[2], 1210*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[3], 1211*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[4], 1212*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[5], 1213*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[6], 1214*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[7], 1215*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[8], 1216*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[9], 1217*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[10], 1218*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[11], 1219*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[12], 1220*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[13], 1221*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[14], 1222*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.board_num[15]); 1223*d14abf15SRobert Mustacchi 1224*d14abf15SRobert Mustacchi return B_TRUE; 1225*d14abf15SRobert Mustacchi 1226*d14abf15SRobert Mustacchi case PRV_CTL_BOOTCODE_VERSION: 1227*d14abf15SRobert Mustacchi 1228*d14abf15SRobert Mustacchi if (!pData || (dataLen <= 0)) 1229*d14abf15SRobert Mustacchi { 1230*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid boot code version buffer for FCoE"); 1231*d14abf15SRobert Mustacchi return B_FALSE; 1232*d14abf15SRobert Mustacchi } 1233*d14abf15SRobert Mustacchi 1234*d14abf15SRobert Mustacchi snprintf((char *)pData, dataLen, "%s", pUM->versionBC); 1235*d14abf15SRobert Mustacchi 1236*d14abf15SRobert Mustacchi return B_TRUE; 1237*d14abf15SRobert Mustacchi 1238*d14abf15SRobert Mustacchi case PRV_CTL_REPORT_FCOE_STATS: 1239*d14abf15SRobert Mustacchi 1240*d14abf15SRobert Mustacchi if (!pData || 1241*d14abf15SRobert Mustacchi (dataLen != 1242*d14abf15SRobert Mustacchi sizeof(pUM->lm_dev.vars.stats.stats_mirror. 1243*d14abf15SRobert Mustacchi stats_drv.drv_info_to_mfw.fcoe_stats))) 1244*d14abf15SRobert Mustacchi { 1245*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid stats reporting buffer for FCoE"); 1246*d14abf15SRobert Mustacchi return B_FALSE; 1247*d14abf15SRobert Mustacchi } 1248*d14abf15SRobert Mustacchi 1249*d14abf15SRobert Mustacchi memcpy(&pUM->lm_dev.vars.stats.stats_mirror. 1250*d14abf15SRobert Mustacchi stats_drv.drv_info_to_mfw.fcoe_stats, 1251*d14abf15SRobert Mustacchi (fcoe_stats_info_t *)pData, 1252*d14abf15SRobert Mustacchi sizeof(fcoe_stats_info_t)); 1253*d14abf15SRobert Mustacchi 1254*d14abf15SRobert Mustacchi return B_TRUE; 1255*d14abf15SRobert Mustacchi 1256*d14abf15SRobert Mustacchi case PRV_CTL_SET_CAPS: 1257*d14abf15SRobert Mustacchi 1258*d14abf15SRobert Mustacchi if (!pData || (dataLen != sizeof(struct fcoe_capabilities))) 1259*d14abf15SRobert Mustacchi { 1260*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid capabilities buffer for FCoE"); 1261*d14abf15SRobert Mustacchi return B_FALSE; 1262*d14abf15SRobert Mustacchi } 1263*d14abf15SRobert Mustacchi 1264*d14abf15SRobert Mustacchi memcpy(&pUM->lm_dev.vars.stats.stats_mirror.stats_drv. 1265*d14abf15SRobert Mustacchi drv_info_to_shmem.fcoe_capabilities, 1266*d14abf15SRobert Mustacchi pData, 1267*d14abf15SRobert Mustacchi sizeof(pUM->lm_dev.vars.stats.stats_mirror.stats_drv. 1268*d14abf15SRobert Mustacchi drv_info_to_shmem.fcoe_capabilities)); 1269*d14abf15SRobert Mustacchi 1270*d14abf15SRobert Mustacchi lm_ncsi_fcoe_cap_to_scratchpad(&pUM->lm_dev); 1271*d14abf15SRobert Mustacchi 1272*d14abf15SRobert Mustacchi return B_TRUE; 1273*d14abf15SRobert Mustacchi 1274*d14abf15SRobert Mustacchi default: 1275*d14abf15SRobert Mustacchi 1276*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Unknown provider command %d", cmd); 1277*d14abf15SRobert Mustacchi return B_FALSE; 1278*d14abf15SRobert Mustacchi } 1279*d14abf15SRobert Mustacchi } 1280*d14abf15SRobert Mustacchi 1281*d14abf15SRobert Mustacchi 1282*d14abf15SRobert Mustacchi mblk_t * BnxeFcoePrvTx(dev_info_t * pDev, 1283*d14abf15SRobert Mustacchi mblk_t * pMblk, 1284*d14abf15SRobert Mustacchi u32_t flags, 1285*d14abf15SRobert Mustacchi u16_t vlan_tag) 1286*d14abf15SRobert Mustacchi { 1287*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev); 1288*d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev; 1289*d14abf15SRobert Mustacchi mblk_t * pNextMblk = NULL; 1290*d14abf15SRobert Mustacchi int txCount = 0; 1291*d14abf15SRobert Mustacchi int rc; 1292*d14abf15SRobert Mustacchi 1293*d14abf15SRobert Mustacchi /* sanity check */ 1294*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev) 1295*d14abf15SRobert Mustacchi { 1296*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__); 1297*d14abf15SRobert Mustacchi return pMblk; 1298*d14abf15SRobert Mustacchi } 1299*d14abf15SRobert Mustacchi 1300*d14abf15SRobert Mustacchi VERIFY_FCOE_BINDING(pUM); 1301*d14abf15SRobert Mustacchi 1302*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s ***", __func__); 1303*d14abf15SRobert Mustacchi 1304*d14abf15SRobert Mustacchi while (pMblk) 1305*d14abf15SRobert Mustacchi { 1306*d14abf15SRobert Mustacchi txCount++; 1307*d14abf15SRobert Mustacchi 1308*d14abf15SRobert Mustacchi pNextMblk = pMblk->b_next; 1309*d14abf15SRobert Mustacchi pMblk->b_next = NULL; 1310*d14abf15SRobert Mustacchi 1311*d14abf15SRobert Mustacchi rc = BnxeTxSendMblk(pUM, FCOE_CID(pLM), pMblk, flags, vlan_tag); 1312*d14abf15SRobert Mustacchi 1313*d14abf15SRobert Mustacchi if (rc == BNXE_TX_GOODXMIT) 1314*d14abf15SRobert Mustacchi { 1315*d14abf15SRobert Mustacchi pMblk = pNextMblk; 1316*d14abf15SRobert Mustacchi continue; 1317*d14abf15SRobert Mustacchi } 1318*d14abf15SRobert Mustacchi else if (rc == BNXE_TX_DEFERPKT) 1319*d14abf15SRobert Mustacchi { 1320*d14abf15SRobert Mustacchi pMblk = pNextMblk; 1321*d14abf15SRobert Mustacchi } 1322*d14abf15SRobert Mustacchi else 1323*d14abf15SRobert Mustacchi { 1324*d14abf15SRobert Mustacchi pMblk->b_next = pNextMblk; 1325*d14abf15SRobert Mustacchi } 1326*d14abf15SRobert Mustacchi 1327*d14abf15SRobert Mustacchi break; 1328*d14abf15SRobert Mustacchi } 1329*d14abf15SRobert Mustacchi 1330*d14abf15SRobert Mustacchi return pMblk; 1331*d14abf15SRobert Mustacchi } 1332*d14abf15SRobert Mustacchi 1333*d14abf15SRobert Mustacchi 1334*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvPoll(dev_info_t * pDev) 1335*d14abf15SRobert Mustacchi { 1336*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev); 1337*d14abf15SRobert Mustacchi RxQueue * pRxQ = &pUM->rxq[FCOE_CID(&pUM->lm_dev)]; 1338*d14abf15SRobert Mustacchi u32_t idx = pRxQ->idx; 1339*d14abf15SRobert Mustacchi 1340*d14abf15SRobert Mustacchi /* sanity check */ 1341*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev) 1342*d14abf15SRobert Mustacchi { 1343*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__); 1344*d14abf15SRobert Mustacchi return B_FALSE; 1345*d14abf15SRobert Mustacchi } 1346*d14abf15SRobert Mustacchi 1347*d14abf15SRobert Mustacchi VERIFY_FCOE_BINDING(pUM); 1348*d14abf15SRobert Mustacchi 1349*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s ***", __func__); 1350*d14abf15SRobert Mustacchi 1351*d14abf15SRobert Mustacchi if (pRxQ->inPollMode == B_FALSE) 1352*d14abf15SRobert Mustacchi { 1353*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Polling on FCoE ring %d when NOT in poll mode!", idx); 1354*d14abf15SRobert Mustacchi return NULL; 1355*d14abf15SRobert Mustacchi } 1356*d14abf15SRobert Mustacchi 1357*d14abf15SRobert Mustacchi pRxQ->pollCnt++; 1358*d14abf15SRobert Mustacchi 1359*d14abf15SRobert Mustacchi BnxePollRxRingFCOE(pUM); 1360*d14abf15SRobert Mustacchi 1361*d14abf15SRobert Mustacchi return B_TRUE; 1362*d14abf15SRobert Mustacchi } 1363*d14abf15SRobert Mustacchi 1364*d14abf15SRobert Mustacchi 1365*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvSendWqes(dev_info_t * pDev, 1366*d14abf15SRobert Mustacchi void * wqes[], 1367*d14abf15SRobert Mustacchi int wqeCnt) 1368*d14abf15SRobert Mustacchi { 1369*d14abf15SRobert Mustacchi union fcoe_kwqe ** kwqes = (union fcoe_kwqe **)wqes; 1370*d14abf15SRobert Mustacchi int kwqeCnt = 0; 1371*d14abf15SRobert Mustacchi 1372*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev); 1373*d14abf15SRobert Mustacchi 1374*d14abf15SRobert Mustacchi /* sanity check */ 1375*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev) 1376*d14abf15SRobert Mustacchi { 1377*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__); 1378*d14abf15SRobert Mustacchi return B_FALSE; 1379*d14abf15SRobert Mustacchi } 1380*d14abf15SRobert Mustacchi 1381*d14abf15SRobert Mustacchi VERIFY_FCOE_BINDING(pUM); 1382*d14abf15SRobert Mustacchi 1383*d14abf15SRobert Mustacchi if ((kwqes == NULL) || (kwqes[0] == NULL)) 1384*d14abf15SRobert Mustacchi { 1385*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid WQE array"); 1386*d14abf15SRobert Mustacchi return B_FALSE; 1387*d14abf15SRobert Mustacchi } 1388*d14abf15SRobert Mustacchi 1389*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s ***", __func__); 1390*d14abf15SRobert Mustacchi 1391*d14abf15SRobert Mustacchi while (kwqeCnt < wqeCnt) 1392*d14abf15SRobert Mustacchi { 1393*d14abf15SRobert Mustacchi switch (kwqes[kwqeCnt]->init1.hdr.op_code) 1394*d14abf15SRobert Mustacchi { 1395*d14abf15SRobert Mustacchi case FCOE_KWQE_OPCODE_INIT1: 1396*d14abf15SRobert Mustacchi 1397*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_INIT", __func__); 1398*d14abf15SRobert Mustacchi 1399*d14abf15SRobert Mustacchi if ((wqeCnt <= kwqeCnt + 2) || 1400*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 1] == NULL) || 1401*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 2] == NULL) || 1402*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 1]->init2.hdr.op_code != FCOE_KWQE_OPCODE_INIT2) || 1403*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 2]->init3.hdr.op_code != FCOE_KWQE_OPCODE_INIT3)) 1404*d14abf15SRobert Mustacchi { 1405*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE Init kwqes error"); 1406*d14abf15SRobert Mustacchi pUM->fcoe.stats.initWqeTxErr++; 1407*d14abf15SRobert Mustacchi return B_FALSE; 1408*d14abf15SRobert Mustacchi } 1409*d14abf15SRobert Mustacchi 1410*d14abf15SRobert Mustacchi if (!BnxeFcoeInitWqe(pUM, &kwqes[kwqeCnt])) 1411*d14abf15SRobert Mustacchi { 1412*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to init FCoE Init WQE work"); 1413*d14abf15SRobert Mustacchi return B_FALSE; 1414*d14abf15SRobert Mustacchi } 1415*d14abf15SRobert Mustacchi 1416*d14abf15SRobert Mustacchi kwqeCnt += 3; 1417*d14abf15SRobert Mustacchi 1418*d14abf15SRobert Mustacchi break; 1419*d14abf15SRobert Mustacchi 1420*d14abf15SRobert Mustacchi case FCOE_KWQE_OPCODE_OFFLOAD_CONN1: 1421*d14abf15SRobert Mustacchi 1422*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_OFFLOAD_CONN1", __func__); 1423*d14abf15SRobert Mustacchi 1424*d14abf15SRobert Mustacchi if ((wqeCnt <= kwqeCnt + 3) || 1425*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 1] == NULL) || 1426*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 2] == NULL) || 1427*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 3] == NULL) || 1428*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 1]->conn_offload2.hdr.op_code != FCOE_KWQE_OPCODE_OFFLOAD_CONN2) || 1429*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 2]->conn_offload3.hdr.op_code != FCOE_KWQE_OPCODE_OFFLOAD_CONN3) || 1430*d14abf15SRobert Mustacchi (kwqes[kwqeCnt + 3]->conn_offload4.hdr.op_code != FCOE_KWQE_OPCODE_OFFLOAD_CONN4)) 1431*d14abf15SRobert Mustacchi { 1432*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE Offload Conn kwqes error"); 1433*d14abf15SRobert Mustacchi pUM->fcoe.stats.offloadConnWqeTxErr++; 1434*d14abf15SRobert Mustacchi return B_FALSE; 1435*d14abf15SRobert Mustacchi } 1436*d14abf15SRobert Mustacchi 1437*d14abf15SRobert Mustacchi if (!BnxeFcoeOffloadConnWqe(pUM, &kwqes[kwqeCnt])) 1438*d14abf15SRobert Mustacchi { 1439*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to init FCoE Offload Conn WQE work"); 1440*d14abf15SRobert Mustacchi return B_FALSE; 1441*d14abf15SRobert Mustacchi } 1442*d14abf15SRobert Mustacchi 1443*d14abf15SRobert Mustacchi kwqeCnt += 4; 1444*d14abf15SRobert Mustacchi 1445*d14abf15SRobert Mustacchi break; 1446*d14abf15SRobert Mustacchi 1447*d14abf15SRobert Mustacchi case FCOE_KWQE_OPCODE_ENABLE_CONN: 1448*d14abf15SRobert Mustacchi 1449*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_ENABLE_CONN", __func__); 1450*d14abf15SRobert Mustacchi 1451*d14abf15SRobert Mustacchi if (!BnxeFcoeEnableConnWqe(pUM, &kwqes[kwqeCnt])) 1452*d14abf15SRobert Mustacchi { 1453*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to init FCoE Enable Conn WQE work"); 1454*d14abf15SRobert Mustacchi return B_FALSE; 1455*d14abf15SRobert Mustacchi } 1456*d14abf15SRobert Mustacchi 1457*d14abf15SRobert Mustacchi kwqeCnt += 1; 1458*d14abf15SRobert Mustacchi 1459*d14abf15SRobert Mustacchi break; 1460*d14abf15SRobert Mustacchi 1461*d14abf15SRobert Mustacchi case FCOE_KWQE_OPCODE_DISABLE_CONN: 1462*d14abf15SRobert Mustacchi 1463*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_DISABLE_CONN", __func__); 1464*d14abf15SRobert Mustacchi 1465*d14abf15SRobert Mustacchi if (!BnxeFcoeDisableConnWqe(pUM, &kwqes[kwqeCnt])) 1466*d14abf15SRobert Mustacchi { 1467*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to init FCoE Disable Conn WQE work"); 1468*d14abf15SRobert Mustacchi return B_FALSE; 1469*d14abf15SRobert Mustacchi } 1470*d14abf15SRobert Mustacchi 1471*d14abf15SRobert Mustacchi kwqeCnt += 1; 1472*d14abf15SRobert Mustacchi 1473*d14abf15SRobert Mustacchi break; 1474*d14abf15SRobert Mustacchi 1475*d14abf15SRobert Mustacchi case FCOE_KWQE_OPCODE_DESTROY_CONN: 1476*d14abf15SRobert Mustacchi 1477*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_DESTROY_CONN", __func__); 1478*d14abf15SRobert Mustacchi 1479*d14abf15SRobert Mustacchi if (!BnxeFcoeDestroyConnWqe(pUM, &kwqes[kwqeCnt])) 1480*d14abf15SRobert Mustacchi { 1481*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to init FCoE Destroy Conn WQE work"); 1482*d14abf15SRobert Mustacchi return B_FALSE; 1483*d14abf15SRobert Mustacchi } 1484*d14abf15SRobert Mustacchi 1485*d14abf15SRobert Mustacchi kwqeCnt += 1; 1486*d14abf15SRobert Mustacchi 1487*d14abf15SRobert Mustacchi break; 1488*d14abf15SRobert Mustacchi 1489*d14abf15SRobert Mustacchi case FCOE_KWQE_OPCODE_DESTROY: 1490*d14abf15SRobert Mustacchi 1491*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_DESTROY", __func__); 1492*d14abf15SRobert Mustacchi 1493*d14abf15SRobert Mustacchi if (!BnxeFcoeDestroyWqe(pUM, &kwqes[kwqeCnt])) 1494*d14abf15SRobert Mustacchi { 1495*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to init FCoE Destroy WQE work"); 1496*d14abf15SRobert Mustacchi return B_FALSE; 1497*d14abf15SRobert Mustacchi } 1498*d14abf15SRobert Mustacchi 1499*d14abf15SRobert Mustacchi kwqeCnt += 1; 1500*d14abf15SRobert Mustacchi 1501*d14abf15SRobert Mustacchi break; 1502*d14abf15SRobert Mustacchi 1503*d14abf15SRobert Mustacchi case FCOE_KWQE_OPCODE_STAT: 1504*d14abf15SRobert Mustacchi 1505*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_STAT", __func__); 1506*d14abf15SRobert Mustacchi 1507*d14abf15SRobert Mustacchi if (!BnxeFcoeStatWqe(pUM, &kwqes[kwqeCnt])) 1508*d14abf15SRobert Mustacchi { 1509*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to init FCoE Stat WQE work"); 1510*d14abf15SRobert Mustacchi return B_FALSE; 1511*d14abf15SRobert Mustacchi } 1512*d14abf15SRobert Mustacchi 1513*d14abf15SRobert Mustacchi kwqeCnt += 1; 1514*d14abf15SRobert Mustacchi 1515*d14abf15SRobert Mustacchi break; 1516*d14abf15SRobert Mustacchi 1517*d14abf15SRobert Mustacchi default: 1518*d14abf15SRobert Mustacchi 1519*d14abf15SRobert Mustacchi BnxeDbgBreakMsg(pUM, "Invalid KWQE opcode"); 1520*d14abf15SRobert Mustacchi return B_FALSE; 1521*d14abf15SRobert Mustacchi } 1522*d14abf15SRobert Mustacchi } 1523*d14abf15SRobert Mustacchi 1524*d14abf15SRobert Mustacchi return B_TRUE; 1525*d14abf15SRobert Mustacchi } 1526*d14abf15SRobert Mustacchi 1527*d14abf15SRobert Mustacchi 1528*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvMapMailboxq(dev_info_t * pDev, 1529*d14abf15SRobert Mustacchi u32_t cid, 1530*d14abf15SRobert Mustacchi void ** ppMap, 1531*d14abf15SRobert Mustacchi ddi_acc_handle_t * pAccHandle) 1532*d14abf15SRobert Mustacchi { 1533*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev); 1534*d14abf15SRobert Mustacchi 1535*d14abf15SRobert Mustacchi /* sanity check */ 1536*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev) 1537*d14abf15SRobert Mustacchi { 1538*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__); 1539*d14abf15SRobert Mustacchi return B_FALSE; 1540*d14abf15SRobert Mustacchi } 1541*d14abf15SRobert Mustacchi 1542*d14abf15SRobert Mustacchi VERIFY_FCOE_BINDING(pUM); 1543*d14abf15SRobert Mustacchi 1544*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s ***", __func__); 1545*d14abf15SRobert Mustacchi 1546*d14abf15SRobert Mustacchi /* get the right offset from the mapped bar */ 1547*d14abf15SRobert Mustacchi 1548*d14abf15SRobert Mustacchi *ppMap = (void *)((u8_t *)pUM->lm_dev.context_info->array[SW_CID(cid)].cid_resc.mapped_cid_bar_addr + DPM_TRIGER_TYPE); 1549*d14abf15SRobert Mustacchi *pAccHandle = pUM->lm_dev.context_info->array[SW_CID(cid)].cid_resc.reg_handle; 1550*d14abf15SRobert Mustacchi 1551*d14abf15SRobert Mustacchi if (!(*ppMap) || !(*pAccHandle)) 1552*d14abf15SRobert Mustacchi { 1553*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Cannot map mailboxq base address for FCoE"); 1554*d14abf15SRobert Mustacchi return B_FALSE; 1555*d14abf15SRobert Mustacchi } 1556*d14abf15SRobert Mustacchi 1557*d14abf15SRobert Mustacchi return B_TRUE; 1558*d14abf15SRobert Mustacchi } 1559*d14abf15SRobert Mustacchi 1560*d14abf15SRobert Mustacchi 1561*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvUnmapMailboxq(dev_info_t * pDev, 1562*d14abf15SRobert Mustacchi u32_t cid, 1563*d14abf15SRobert Mustacchi void * pMap, 1564*d14abf15SRobert Mustacchi ddi_acc_handle_t accHandle) 1565*d14abf15SRobert Mustacchi { 1566*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev); 1567*d14abf15SRobert Mustacchi void * pTmp; 1568*d14abf15SRobert Mustacchi ddi_acc_handle_t tmpAcc; 1569*d14abf15SRobert Mustacchi 1570*d14abf15SRobert Mustacchi /* sanity check */ 1571*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev) 1572*d14abf15SRobert Mustacchi { 1573*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__); 1574*d14abf15SRobert Mustacchi return B_FALSE; 1575*d14abf15SRobert Mustacchi } 1576*d14abf15SRobert Mustacchi 1577*d14abf15SRobert Mustacchi VERIFY_FCOE_BINDING(pUM); 1578*d14abf15SRobert Mustacchi 1579*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "*** %s ***", __func__); 1580*d14abf15SRobert Mustacchi 1581*d14abf15SRobert Mustacchi /* verify the mapped bar address */ 1582*d14abf15SRobert Mustacchi pTmp = (void *)((u8_t *)pUM->lm_dev.context_info->array[SW_CID(cid)].cid_resc.mapped_cid_bar_addr + DPM_TRIGER_TYPE); 1583*d14abf15SRobert Mustacchi tmpAcc = pUM->lm_dev.context_info->array[SW_CID(cid)].cid_resc.reg_handle; 1584*d14abf15SRobert Mustacchi 1585*d14abf15SRobert Mustacchi if ((pMap != pTmp) || (accHandle != tmpAcc)) 1586*d14abf15SRobert Mustacchi { 1587*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Invalid map info for FCoE (%p)", pMap); 1588*d14abf15SRobert Mustacchi return B_FALSE; 1589*d14abf15SRobert Mustacchi } 1590*d14abf15SRobert Mustacchi 1591*d14abf15SRobert Mustacchi return B_TRUE; 1592*d14abf15SRobert Mustacchi } 1593*d14abf15SRobert Mustacchi 1594*d14abf15SRobert Mustacchi 1595*d14abf15SRobert Mustacchi int BnxeFcoeInit(um_device_t * pUM) 1596*d14abf15SRobert Mustacchi { 1597*d14abf15SRobert Mustacchi char * pCompat[2] = { BNXEF_NAME, NULL }; 1598*d14abf15SRobert Mustacchi char name[256]; 1599*d14abf15SRobert Mustacchi int rc; 1600*d14abf15SRobert Mustacchi 1601*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Starting FCoE"); 1602*d14abf15SRobert Mustacchi 1603*d14abf15SRobert Mustacchi if (!BNXE_FCOE(pUM)) 1604*d14abf15SRobert Mustacchi { 1605*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE not supported on this device"); 1606*d14abf15SRobert Mustacchi return ENOTSUP; 1607*d14abf15SRobert Mustacchi } 1608*d14abf15SRobert Mustacchi 1609*d14abf15SRobert Mustacchi //if (CLIENT_DEVI(pUM, LM_CLI_IDX_FCOE)) 1610*d14abf15SRobert Mustacchi if (pUM->fcoe.pDev) 1611*d14abf15SRobert Mustacchi { 1612*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE child node already initialized"); 1613*d14abf15SRobert Mustacchi return EEXIST; 1614*d14abf15SRobert Mustacchi } 1615*d14abf15SRobert Mustacchi 1616*d14abf15SRobert Mustacchi if (ndi_devi_alloc(pUM->pDev, 1617*d14abf15SRobert Mustacchi BNXEF_NAME, 1618*d14abf15SRobert Mustacchi DEVI_PSEUDO_NODEID, 1619*d14abf15SRobert Mustacchi &pUM->fcoe.pDev) != NDI_SUCCESS) 1620*d14abf15SRobert Mustacchi { 1621*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate a child node for FCoE"); 1622*d14abf15SRobert Mustacchi pUM->fcoe.pDev = NULL; 1623*d14abf15SRobert Mustacchi return ENOMEM; 1624*d14abf15SRobert Mustacchi } 1625*d14abf15SRobert Mustacchi 1626*d14abf15SRobert Mustacchi if (ndi_prop_update_string_array(DDI_DEV_T_NONE, 1627*d14abf15SRobert Mustacchi pUM->fcoe.pDev, 1628*d14abf15SRobert Mustacchi "name", 1629*d14abf15SRobert Mustacchi pCompat, 1630*d14abf15SRobert Mustacchi 1) != DDI_PROP_SUCCESS) 1631*d14abf15SRobert Mustacchi { 1632*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to set the name string for FCoE"); 1633*d14abf15SRobert Mustacchi /* XXX see other call to ndi_devi_free below */ 1634*d14abf15SRobert Mustacchi //ndi_devi_free(pUM->fcoe.pDev); 1635*d14abf15SRobert Mustacchi pUM->fcoe.pDev = NULL; 1636*d14abf15SRobert Mustacchi return ENOENT; 1637*d14abf15SRobert Mustacchi } 1638*d14abf15SRobert Mustacchi 1639*d14abf15SRobert Mustacchi CLIENT_DEVI_SET(pUM, LM_CLI_IDX_FCOE); 1640*d14abf15SRobert Mustacchi 1641*d14abf15SRobert Mustacchi /* 1642*d14abf15SRobert Mustacchi * XXX If/when supporting custom wwn's then prime them 1643*d14abf15SRobert Mustacchi * here in so they will be passed to bnxef during BINDING. 1644*d14abf15SRobert Mustacchi * Ideally custom wwn's will be set via the driver .conf 1645*d14abf15SRobert Mustacchi * file and via a private driver property. 1646*d14abf15SRobert Mustacchi */ 1647*d14abf15SRobert Mustacchi memset(&pUM->fcoe.wwn, 0, sizeof(BnxeWwnInfo)); 1648*d14abf15SRobert Mustacchi pUM->fcoe.wwn.fcp_pwwn_provided = B_TRUE; 1649*d14abf15SRobert Mustacchi memcpy(pUM->fcoe.wwn.fcp_pwwn, pUM->lm_dev.hw_info.fcoe_wwn_port_name, 1650*d14abf15SRobert Mustacchi BNXE_FCOE_WWN_SIZE); 1651*d14abf15SRobert Mustacchi pUM->fcoe.wwn.fcp_nwwn_provided = B_TRUE; 1652*d14abf15SRobert Mustacchi memcpy(pUM->fcoe.wwn.fcp_nwwn, pUM->lm_dev.hw_info.fcoe_wwn_node_name, 1653*d14abf15SRobert Mustacchi BNXE_FCOE_WWN_SIZE); 1654*d14abf15SRobert Mustacchi 1655*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Created the FCoE child node %s@%s", 1656*d14abf15SRobert Mustacchi BNXEF_NAME, ddi_get_name_addr(pUM->pDev)); 1657*d14abf15SRobert Mustacchi 1658*d14abf15SRobert Mustacchi if ((rc = ndi_devi_online(pUM->fcoe.pDev, NDI_ONLINE_ATTACH)) != 1659*d14abf15SRobert Mustacchi NDI_SUCCESS) 1660*d14abf15SRobert Mustacchi { 1661*d14abf15SRobert Mustacchi /* XXX 1662*d14abf15SRobert Mustacchi * ndi_devi_free will cause a panic. Don't know why and we've 1663*d14abf15SRobert Mustacchi * verified that Sun's FCoE driver does not free it either. 1664*d14abf15SRobert Mustacchi */ 1665*d14abf15SRobert Mustacchi //ndi_devi_free(pUM->fcoe.pDev); 1666*d14abf15SRobert Mustacchi CLIENT_DEVI_RESET(pUM, LM_CLI_IDX_FCOE); 1667*d14abf15SRobert Mustacchi pUM->fcoe.pDev = NULL; 1668*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Unable to bind the QLogic FCoE driver (%d)", rc); 1669*d14abf15SRobert Mustacchi return ECHILD; 1670*d14abf15SRobert Mustacchi } 1671*d14abf15SRobert Mustacchi 1672*d14abf15SRobert Mustacchi #if 0 1673*d14abf15SRobert Mustacchi /* bring bnxef online and attach it */ 1674*d14abf15SRobert Mustacchi if (ndi_devi_bind_driver(pUM->fcoe.pDev, 0) != NDI_SUCCESS) 1675*d14abf15SRobert Mustacchi { 1676*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Unable to bind the QLogic FCoE driver"); 1677*d14abf15SRobert Mustacchi } 1678*d14abf15SRobert Mustacchi #endif 1679*d14abf15SRobert Mustacchi 1680*d14abf15SRobert Mustacchi return 0; 1681*d14abf15SRobert Mustacchi } 1682*d14abf15SRobert Mustacchi 1683*d14abf15SRobert Mustacchi 1684*d14abf15SRobert Mustacchi int BnxeFcoeFini(um_device_t * pUM) 1685*d14abf15SRobert Mustacchi { 1686*d14abf15SRobert Mustacchi int rc = 0; 1687*d14abf15SRobert Mustacchi int nullDev = B_FALSE; /* false = wait for bnxef UNBIND */ 1688*d14abf15SRobert Mustacchi 1689*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Stopping FCoE"); 1690*d14abf15SRobert Mustacchi 1691*d14abf15SRobert Mustacchi if (!BNXE_FCOE(pUM)) 1692*d14abf15SRobert Mustacchi { 1693*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE not supported on this device"); 1694*d14abf15SRobert Mustacchi return ENOTSUP; 1695*d14abf15SRobert Mustacchi } 1696*d14abf15SRobert Mustacchi 1697*d14abf15SRobert Mustacchi if (CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)) 1698*d14abf15SRobert Mustacchi { 1699*d14abf15SRobert Mustacchi if (pUM->fcoe.pDev == NULL) 1700*d14abf15SRobert Mustacchi { 1701*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE Client bound and pDev is NULL, FINI failed! %s@%s", 1702*d14abf15SRobert Mustacchi BNXEF_NAME, ddi_get_name_addr(pUM->pDev)); 1703*d14abf15SRobert Mustacchi return ENOENT; 1704*d14abf15SRobert Mustacchi } 1705*d14abf15SRobert Mustacchi else if (pUM->fcoe.bind.cliCtl == NULL) 1706*d14abf15SRobert Mustacchi { 1707*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE Client bound and cliCtl is NULL, FINI failed! %s@%s", 1708*d14abf15SRobert Mustacchi BNXEF_NAME, ddi_get_name_addr(pUM->pDev)); 1709*d14abf15SRobert Mustacchi return ENOENT; 1710*d14abf15SRobert Mustacchi } 1711*d14abf15SRobert Mustacchi else if (pUM->fcoe.bind.cliCtl(pUM->fcoe.pDev, 1712*d14abf15SRobert Mustacchi CLI_CTL_UNLOAD, 1713*d14abf15SRobert Mustacchi NULL, 1714*d14abf15SRobert Mustacchi 0) == B_FALSE) 1715*d14abf15SRobert Mustacchi { 1716*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE Client bound and UNLOAD failed! %s@%s", 1717*d14abf15SRobert Mustacchi BNXEF_NAME, ddi_get_name_addr(pUM->pDev)); 1718*d14abf15SRobert Mustacchi return ENOMSG; /* no graceful unload with bnxef */ 1719*d14abf15SRobert Mustacchi } 1720*d14abf15SRobert Mustacchi } 1721*d14abf15SRobert Mustacchi else 1722*d14abf15SRobert Mustacchi { 1723*d14abf15SRobert Mustacchi rc = ENODEV; 1724*d14abf15SRobert Mustacchi nullDev = B_TRUE; 1725*d14abf15SRobert Mustacchi } 1726*d14abf15SRobert Mustacchi 1727*d14abf15SRobert Mustacchi /* 1728*d14abf15SRobert Mustacchi * There are times when delete-port doesn't fully work and bnxef is unable 1729*d14abf15SRobert Mustacchi * to detach and never calls UNBIND. So here we'll just make sure that 1730*d14abf15SRobert Mustacchi * the child dev node is not NULL which semi-gaurantees the UNBIND hasn't 1731*d14abf15SRobert Mustacchi * been called yet. Multiple offline calls will hopefully kick bnxef... 1732*d14abf15SRobert Mustacchi */ 1733*d14abf15SRobert Mustacchi //if (CLIENT_DEVI(pUM, LM_CLI_IDX_FCOE)) 1734*d14abf15SRobert Mustacchi if (pUM->fcoe.pDev) 1735*d14abf15SRobert Mustacchi { 1736*d14abf15SRobert Mustacchi CLIENT_DEVI_RESET(pUM, LM_CLI_IDX_FCOE); 1737*d14abf15SRobert Mustacchi 1738*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Bringing down QLogic FCoE driver %s@%s", 1739*d14abf15SRobert Mustacchi BNXEF_NAME, ddi_get_name_addr(pUM->pDev)); 1740*d14abf15SRobert Mustacchi 1741*d14abf15SRobert Mustacchi #if 1 1742*d14abf15SRobert Mustacchi if (ndi_devi_offline(pUM->fcoe.pDev, NDI_DEVI_REMOVE) != NDI_SUCCESS) 1743*d14abf15SRobert Mustacchi { 1744*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to bring the QLogic FCoE driver offline %s@%s", 1745*d14abf15SRobert Mustacchi BNXEF_NAME, ddi_get_name_addr(pUM->pDev)); 1746*d14abf15SRobert Mustacchi return EBUSY; 1747*d14abf15SRobert Mustacchi } 1748*d14abf15SRobert Mustacchi #else 1749*d14abf15SRobert Mustacchi ndi_devi_offline(pUM->fcoe.pDev, NDI_DEVI_REMOVE); 1750*d14abf15SRobert Mustacchi if (nullDev) pUM->fcoe.pDev = NULL; 1751*d14abf15SRobert Mustacchi #endif 1752*d14abf15SRobert Mustacchi 1753*d14abf15SRobert Mustacchi memset(&pUM->fcoe.wwn, 0, sizeof(BnxeWwnInfo)); 1754*d14abf15SRobert Mustacchi 1755*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Destroyed the FCoE child node %s@%s", 1756*d14abf15SRobert Mustacchi BNXEF_NAME, ddi_get_name_addr(pUM->pDev)); 1757*d14abf15SRobert Mustacchi } 1758*d14abf15SRobert Mustacchi 1759*d14abf15SRobert Mustacchi return rc; 1760*d14abf15SRobert Mustacchi } 1761*d14abf15SRobert Mustacchi 1762*d14abf15SRobert Mustacchi 1763*d14abf15SRobert Mustacchi void BnxeFcoeStartStop(um_device_t * pUM) 1764*d14abf15SRobert Mustacchi { 1765*d14abf15SRobert Mustacchi int rc; 1766*d14abf15SRobert Mustacchi 1767*d14abf15SRobert Mustacchi if (!BNXE_FCOE(pUM)) 1768*d14abf15SRobert Mustacchi { 1769*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE is not supported on this device"); 1770*d14abf15SRobert Mustacchi return; 1771*d14abf15SRobert Mustacchi } 1772*d14abf15SRobert Mustacchi 1773*d14abf15SRobert Mustacchi if (pUM->devParams.fcoeEnable) 1774*d14abf15SRobert Mustacchi { 1775*d14abf15SRobert Mustacchi BnxeFcoeInit(pUM); 1776*d14abf15SRobert Mustacchi } 1777*d14abf15SRobert Mustacchi else 1778*d14abf15SRobert Mustacchi { 1779*d14abf15SRobert Mustacchi BnxeFcoeFini(pUM); 1780*d14abf15SRobert Mustacchi } 1781*d14abf15SRobert Mustacchi } 1782*d14abf15SRobert Mustacchi 1783