1*a677112dSAndrew Boyer /* SPDX-License-Identifier: BSD-3-Clause 2*a677112dSAndrew Boyer * Copyright 2021-2024 Advanced Micro Devices, Inc. 3*a677112dSAndrew Boyer */ 4*a677112dSAndrew Boyer 5*a677112dSAndrew Boyer #include <stdbool.h> 6*a677112dSAndrew Boyer 7*a677112dSAndrew Boyer #include <rte_malloc.h> 8*a677112dSAndrew Boyer #include <rte_memzone.h> 9*a677112dSAndrew Boyer 10*a677112dSAndrew Boyer #include "ionic_crypto.h" 11*a677112dSAndrew Boyer 12*a677112dSAndrew Boyer /* queuetype support level */ 13*a677112dSAndrew Boyer static const uint8_t iocpt_qtype_vers[IOCPT_QTYPE_MAX] = { 14*a677112dSAndrew Boyer [IOCPT_QTYPE_ADMINQ] = 0, /* 0 = Base version */ 15*a677112dSAndrew Boyer [IOCPT_QTYPE_NOTIFYQ] = 0, /* 0 = Base version */ 16*a677112dSAndrew Boyer [IOCPT_QTYPE_CRYPTOQ] = 0, /* 0 = Base version */ 17*a677112dSAndrew Boyer }; 18*a677112dSAndrew Boyer 19*a677112dSAndrew Boyer static const char * 20*a677112dSAndrew Boyer iocpt_opcode_to_str(enum iocpt_cmd_opcode opcode) 21*a677112dSAndrew Boyer { 22*a677112dSAndrew Boyer switch (opcode) { 23*a677112dSAndrew Boyer case IOCPT_CMD_NOP: 24*a677112dSAndrew Boyer return "IOCPT_CMD_NOP"; 25*a677112dSAndrew Boyer case IOCPT_CMD_IDENTIFY: 26*a677112dSAndrew Boyer return "IOCPT_CMD_IDENTIFY"; 27*a677112dSAndrew Boyer case IOCPT_CMD_RESET: 28*a677112dSAndrew Boyer return "IOCPT_CMD_RESET"; 29*a677112dSAndrew Boyer case IOCPT_CMD_LIF_IDENTIFY: 30*a677112dSAndrew Boyer return "IOCPT_CMD_LIF_IDENTIFY"; 31*a677112dSAndrew Boyer case IOCPT_CMD_LIF_INIT: 32*a677112dSAndrew Boyer return "IOCPT_CMD_LIF_INIT"; 33*a677112dSAndrew Boyer case IOCPT_CMD_LIF_RESET: 34*a677112dSAndrew Boyer return "IOCPT_CMD_LIF_RESET"; 35*a677112dSAndrew Boyer case IOCPT_CMD_LIF_GETATTR: 36*a677112dSAndrew Boyer return "IOCPT_CMD_LIF_GETATTR"; 37*a677112dSAndrew Boyer case IOCPT_CMD_LIF_SETATTR: 38*a677112dSAndrew Boyer return "IOCPT_CMD_LIF_SETATTR"; 39*a677112dSAndrew Boyer case IOCPT_CMD_Q_IDENTIFY: 40*a677112dSAndrew Boyer return "IOCPT_CMD_Q_IDENTIFY"; 41*a677112dSAndrew Boyer case IOCPT_CMD_Q_INIT: 42*a677112dSAndrew Boyer return "IOCPT_CMD_Q_INIT"; 43*a677112dSAndrew Boyer case IOCPT_CMD_Q_CONTROL: 44*a677112dSAndrew Boyer return "IOCPT_CMD_Q_CONTROL"; 45*a677112dSAndrew Boyer case IOCPT_CMD_SESS_CONTROL: 46*a677112dSAndrew Boyer return "IOCPT_CMD_SESS_CONTROL"; 47*a677112dSAndrew Boyer default: 48*a677112dSAndrew Boyer return "DEVCMD_UNKNOWN"; 49*a677112dSAndrew Boyer } 50*a677112dSAndrew Boyer } 51*a677112dSAndrew Boyer 52*a677112dSAndrew Boyer /* Dev_cmd Interface */ 53*a677112dSAndrew Boyer 54*a677112dSAndrew Boyer static void 55*a677112dSAndrew Boyer iocpt_dev_cmd_go(struct iocpt_dev *dev, union iocpt_dev_cmd *cmd) 56*a677112dSAndrew Boyer { 57*a677112dSAndrew Boyer uint32_t cmd_size = RTE_DIM(cmd->words); 58*a677112dSAndrew Boyer uint32_t i; 59*a677112dSAndrew Boyer 60*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, "Sending %s (%d) via dev_cmd", 61*a677112dSAndrew Boyer iocpt_opcode_to_str(cmd->cmd.opcode), cmd->cmd.opcode); 62*a677112dSAndrew Boyer 63*a677112dSAndrew Boyer for (i = 0; i < cmd_size; i++) 64*a677112dSAndrew Boyer iowrite32(cmd->words[i], &dev->dev_cmd->cmd.words[i]); 65*a677112dSAndrew Boyer 66*a677112dSAndrew Boyer iowrite32(0, &dev->dev_cmd->done); 67*a677112dSAndrew Boyer iowrite32(1, &dev->dev_cmd->doorbell); 68*a677112dSAndrew Boyer } 69*a677112dSAndrew Boyer 70*a677112dSAndrew Boyer static int 71*a677112dSAndrew Boyer iocpt_dev_cmd_wait(struct iocpt_dev *dev, unsigned long max_wait) 72*a677112dSAndrew Boyer { 73*a677112dSAndrew Boyer unsigned long step_usec = IONIC_DEVCMD_CHECK_PERIOD_US; 74*a677112dSAndrew Boyer unsigned long max_wait_usec = max_wait * 1000000L; 75*a677112dSAndrew Boyer unsigned long elapsed_usec = 0; 76*a677112dSAndrew Boyer int done; 77*a677112dSAndrew Boyer 78*a677112dSAndrew Boyer /* Wait for dev cmd to complete.. but no more than max_wait sec */ 79*a677112dSAndrew Boyer 80*a677112dSAndrew Boyer do { 81*a677112dSAndrew Boyer done = ioread32(&dev->dev_cmd->done) & IONIC_DEV_CMD_DONE; 82*a677112dSAndrew Boyer if (done != 0) { 83*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, "DEVCMD %d done took %lu usecs", 84*a677112dSAndrew Boyer ioread8(&dev->dev_cmd->cmd.cmd.opcode), 85*a677112dSAndrew Boyer elapsed_usec); 86*a677112dSAndrew Boyer return 0; 87*a677112dSAndrew Boyer } 88*a677112dSAndrew Boyer 89*a677112dSAndrew Boyer rte_delay_us_block(step_usec); 90*a677112dSAndrew Boyer 91*a677112dSAndrew Boyer elapsed_usec += step_usec; 92*a677112dSAndrew Boyer } while (elapsed_usec < max_wait_usec); 93*a677112dSAndrew Boyer 94*a677112dSAndrew Boyer IOCPT_PRINT(ERR, "DEVCMD %d timeout after %lu usecs", 95*a677112dSAndrew Boyer ioread8(&dev->dev_cmd->cmd.cmd.opcode), elapsed_usec); 96*a677112dSAndrew Boyer 97*a677112dSAndrew Boyer return -ETIMEDOUT; 98*a677112dSAndrew Boyer } 99*a677112dSAndrew Boyer 100*a677112dSAndrew Boyer static int 101*a677112dSAndrew Boyer iocpt_dev_cmd_wait_check(struct iocpt_dev *dev, unsigned long max_wait) 102*a677112dSAndrew Boyer { 103*a677112dSAndrew Boyer uint8_t status; 104*a677112dSAndrew Boyer int err; 105*a677112dSAndrew Boyer 106*a677112dSAndrew Boyer err = iocpt_dev_cmd_wait(dev, max_wait); 107*a677112dSAndrew Boyer if (err == 0) { 108*a677112dSAndrew Boyer status = ioread8(&dev->dev_cmd->comp.comp.status); 109*a677112dSAndrew Boyer if (status == IOCPT_RC_EAGAIN) 110*a677112dSAndrew Boyer err = -EAGAIN; 111*a677112dSAndrew Boyer else if (status != 0) 112*a677112dSAndrew Boyer err = -EIO; 113*a677112dSAndrew Boyer } 114*a677112dSAndrew Boyer 115*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, "dev_cmd returned %d", err); 116*a677112dSAndrew Boyer return err; 117*a677112dSAndrew Boyer } 118*a677112dSAndrew Boyer 119*a677112dSAndrew Boyer /* Dev_cmds */ 120*a677112dSAndrew Boyer 121*a677112dSAndrew Boyer static void 122*a677112dSAndrew Boyer iocpt_dev_cmd_reset(struct iocpt_dev *dev) 123*a677112dSAndrew Boyer { 124*a677112dSAndrew Boyer union iocpt_dev_cmd cmd = { 125*a677112dSAndrew Boyer .reset.opcode = IOCPT_CMD_RESET, 126*a677112dSAndrew Boyer }; 127*a677112dSAndrew Boyer 128*a677112dSAndrew Boyer iocpt_dev_cmd_go(dev, &cmd); 129*a677112dSAndrew Boyer } 130*a677112dSAndrew Boyer 131*a677112dSAndrew Boyer static void 132*a677112dSAndrew Boyer iocpt_dev_cmd_lif_identify(struct iocpt_dev *dev, uint8_t ver) 133*a677112dSAndrew Boyer { 134*a677112dSAndrew Boyer union iocpt_dev_cmd cmd = { 135*a677112dSAndrew Boyer .lif_identify.opcode = IOCPT_CMD_LIF_IDENTIFY, 136*a677112dSAndrew Boyer .lif_identify.type = IOCPT_LIF_TYPE_DEFAULT, 137*a677112dSAndrew Boyer .lif_identify.ver = ver, 138*a677112dSAndrew Boyer }; 139*a677112dSAndrew Boyer 140*a677112dSAndrew Boyer iocpt_dev_cmd_go(dev, &cmd); 141*a677112dSAndrew Boyer } 142*a677112dSAndrew Boyer 143*a677112dSAndrew Boyer static void 144*a677112dSAndrew Boyer iocpt_dev_cmd_lif_init(struct iocpt_dev *dev, rte_iova_t info_pa) 145*a677112dSAndrew Boyer { 146*a677112dSAndrew Boyer union iocpt_dev_cmd cmd = { 147*a677112dSAndrew Boyer .lif_init.opcode = IOCPT_CMD_LIF_INIT, 148*a677112dSAndrew Boyer .lif_init.type = IOCPT_LIF_TYPE_DEFAULT, 149*a677112dSAndrew Boyer .lif_init.info_pa = info_pa, 150*a677112dSAndrew Boyer }; 151*a677112dSAndrew Boyer 152*a677112dSAndrew Boyer iocpt_dev_cmd_go(dev, &cmd); 153*a677112dSAndrew Boyer } 154*a677112dSAndrew Boyer 155*a677112dSAndrew Boyer static void 156*a677112dSAndrew Boyer iocpt_dev_cmd_lif_reset(struct iocpt_dev *dev) 157*a677112dSAndrew Boyer { 158*a677112dSAndrew Boyer union iocpt_dev_cmd cmd = { 159*a677112dSAndrew Boyer .lif_reset.opcode = IOCPT_CMD_LIF_RESET, 160*a677112dSAndrew Boyer }; 161*a677112dSAndrew Boyer 162*a677112dSAndrew Boyer iocpt_dev_cmd_go(dev, &cmd); 163*a677112dSAndrew Boyer } 164*a677112dSAndrew Boyer 165*a677112dSAndrew Boyer static void 166*a677112dSAndrew Boyer iocpt_dev_cmd_queue_identify(struct iocpt_dev *dev, 167*a677112dSAndrew Boyer uint8_t qtype, uint8_t qver) 168*a677112dSAndrew Boyer { 169*a677112dSAndrew Boyer union iocpt_dev_cmd cmd = { 170*a677112dSAndrew Boyer .q_identify.opcode = IOCPT_CMD_Q_IDENTIFY, 171*a677112dSAndrew Boyer .q_identify.type = qtype, 172*a677112dSAndrew Boyer .q_identify.ver = qver, 173*a677112dSAndrew Boyer }; 174*a677112dSAndrew Boyer 175*a677112dSAndrew Boyer iocpt_dev_cmd_go(dev, &cmd); 176*a677112dSAndrew Boyer } 177*a677112dSAndrew Boyer 178*a677112dSAndrew Boyer /* Dev_cmd consumers */ 179*a677112dSAndrew Boyer 180*a677112dSAndrew Boyer static void 181*a677112dSAndrew Boyer iocpt_queue_identify(struct iocpt_dev *dev) 182*a677112dSAndrew Boyer { 183*a677112dSAndrew Boyer union iocpt_q_identity *q_ident = &dev->ident.q; 184*a677112dSAndrew Boyer uint32_t q_words = RTE_DIM(q_ident->words); 185*a677112dSAndrew Boyer uint32_t cmd_words = RTE_DIM(dev->dev_cmd->data); 186*a677112dSAndrew Boyer uint32_t i, nwords, qtype; 187*a677112dSAndrew Boyer int err; 188*a677112dSAndrew Boyer 189*a677112dSAndrew Boyer for (qtype = 0; qtype < RTE_DIM(iocpt_qtype_vers); qtype++) { 190*a677112dSAndrew Boyer struct iocpt_qtype_info *qti = &dev->qtype_info[qtype]; 191*a677112dSAndrew Boyer 192*a677112dSAndrew Boyer /* Filter out the types this driver knows about */ 193*a677112dSAndrew Boyer switch (qtype) { 194*a677112dSAndrew Boyer case IOCPT_QTYPE_ADMINQ: 195*a677112dSAndrew Boyer case IOCPT_QTYPE_NOTIFYQ: 196*a677112dSAndrew Boyer case IOCPT_QTYPE_CRYPTOQ: 197*a677112dSAndrew Boyer break; 198*a677112dSAndrew Boyer default: 199*a677112dSAndrew Boyer continue; 200*a677112dSAndrew Boyer } 201*a677112dSAndrew Boyer 202*a677112dSAndrew Boyer memset(qti, 0, sizeof(*qti)); 203*a677112dSAndrew Boyer 204*a677112dSAndrew Boyer if (iocpt_is_embedded()) { 205*a677112dSAndrew Boyer /* When embedded, FW will always match the driver */ 206*a677112dSAndrew Boyer qti->version = iocpt_qtype_vers[qtype]; 207*a677112dSAndrew Boyer continue; 208*a677112dSAndrew Boyer } 209*a677112dSAndrew Boyer 210*a677112dSAndrew Boyer /* On the host, query the FW for info */ 211*a677112dSAndrew Boyer iocpt_dev_cmd_queue_identify(dev, 212*a677112dSAndrew Boyer qtype, iocpt_qtype_vers[qtype]); 213*a677112dSAndrew Boyer err = iocpt_dev_cmd_wait_check(dev, IONIC_DEVCMD_TIMEOUT); 214*a677112dSAndrew Boyer if (err == -EINVAL) { 215*a677112dSAndrew Boyer IOCPT_PRINT(ERR, "qtype %d not supported", qtype); 216*a677112dSAndrew Boyer continue; 217*a677112dSAndrew Boyer } else if (err == -EIO) { 218*a677112dSAndrew Boyer IOCPT_PRINT(ERR, "q_ident failed, older FW"); 219*a677112dSAndrew Boyer return; 220*a677112dSAndrew Boyer } else if (err != 0) { 221*a677112dSAndrew Boyer IOCPT_PRINT(ERR, "q_ident failed, qtype %d: %d", 222*a677112dSAndrew Boyer qtype, err); 223*a677112dSAndrew Boyer return; 224*a677112dSAndrew Boyer } 225*a677112dSAndrew Boyer 226*a677112dSAndrew Boyer nwords = RTE_MIN(q_words, cmd_words); 227*a677112dSAndrew Boyer for (i = 0; i < nwords; i++) 228*a677112dSAndrew Boyer q_ident->words[i] = ioread32(&dev->dev_cmd->data[i]); 229*a677112dSAndrew Boyer 230*a677112dSAndrew Boyer qti->version = q_ident->version; 231*a677112dSAndrew Boyer qti->supported = q_ident->supported; 232*a677112dSAndrew Boyer qti->features = rte_le_to_cpu_64(q_ident->features); 233*a677112dSAndrew Boyer qti->desc_sz = rte_le_to_cpu_16(q_ident->desc_sz); 234*a677112dSAndrew Boyer qti->comp_sz = rte_le_to_cpu_16(q_ident->comp_sz); 235*a677112dSAndrew Boyer qti->sg_desc_sz = rte_le_to_cpu_16(q_ident->sg_desc_sz); 236*a677112dSAndrew Boyer qti->max_sg_elems = rte_le_to_cpu_16(q_ident->max_sg_elems); 237*a677112dSAndrew Boyer qti->sg_desc_stride = 238*a677112dSAndrew Boyer rte_le_to_cpu_16(q_ident->sg_desc_stride); 239*a677112dSAndrew Boyer 240*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, " qtype[%d].version = %d", 241*a677112dSAndrew Boyer qtype, qti->version); 242*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, " qtype[%d].supported = %#x", 243*a677112dSAndrew Boyer qtype, qti->supported); 244*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, " qtype[%d].features = %#jx", 245*a677112dSAndrew Boyer qtype, qti->features); 246*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, " qtype[%d].desc_sz = %d", 247*a677112dSAndrew Boyer qtype, qti->desc_sz); 248*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, " qtype[%d].comp_sz = %d", 249*a677112dSAndrew Boyer qtype, qti->comp_sz); 250*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, " qtype[%d].sg_desc_sz = %d", 251*a677112dSAndrew Boyer qtype, qti->sg_desc_sz); 252*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, " qtype[%d].max_sg_elems = %d", 253*a677112dSAndrew Boyer qtype, qti->max_sg_elems); 254*a677112dSAndrew Boyer IOCPT_PRINT(DEBUG, " qtype[%d].sg_desc_stride = %d", 255*a677112dSAndrew Boyer qtype, qti->sg_desc_stride); 256*a677112dSAndrew Boyer } 257*a677112dSAndrew Boyer } 258*a677112dSAndrew Boyer 259*a677112dSAndrew Boyer int 260*a677112dSAndrew Boyer iocpt_dev_identify(struct iocpt_dev *dev) 261*a677112dSAndrew Boyer { 262*a677112dSAndrew Boyer union iocpt_lif_identity *ident = &dev->ident.lif; 263*a677112dSAndrew Boyer union iocpt_lif_config *cfg = &ident->config; 264*a677112dSAndrew Boyer uint64_t features; 265*a677112dSAndrew Boyer uint32_t cmd_size = RTE_DIM(dev->dev_cmd->data); 266*a677112dSAndrew Boyer uint32_t dev_size = RTE_DIM(ident->words); 267*a677112dSAndrew Boyer uint32_t i, nwords; 268*a677112dSAndrew Boyer int err; 269*a677112dSAndrew Boyer 270*a677112dSAndrew Boyer memset(ident, 0, sizeof(*ident)); 271*a677112dSAndrew Boyer 272*a677112dSAndrew Boyer iocpt_dev_cmd_lif_identify(dev, IOCPT_IDENTITY_VERSION_1); 273*a677112dSAndrew Boyer err = iocpt_dev_cmd_wait_check(dev, IONIC_DEVCMD_TIMEOUT); 274*a677112dSAndrew Boyer if (err != 0) 275*a677112dSAndrew Boyer return err; 276*a677112dSAndrew Boyer 277*a677112dSAndrew Boyer nwords = RTE_MIN(dev_size, cmd_size); 278*a677112dSAndrew Boyer for (i = 0; i < nwords; i++) 279*a677112dSAndrew Boyer ident->words[i] = ioread32(&dev->dev_cmd->data[i]); 280*a677112dSAndrew Boyer 281*a677112dSAndrew Boyer dev->max_qps = 282*a677112dSAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IOCPT_QTYPE_CRYPTOQ]); 283*a677112dSAndrew Boyer dev->max_sessions = 284*a677112dSAndrew Boyer rte_le_to_cpu_32(ident->max_nb_sessions); 285*a677112dSAndrew Boyer 286*a677112dSAndrew Boyer features = rte_le_to_cpu_64(ident->features); 287*a677112dSAndrew Boyer dev->features = RTE_CRYPTODEV_FF_HW_ACCELERATED; 288*a677112dSAndrew Boyer if (features & IOCPT_HW_SYM) 289*a677112dSAndrew Boyer dev->features |= RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO; 290*a677112dSAndrew Boyer if (features & IOCPT_HW_ASYM) 291*a677112dSAndrew Boyer dev->features |= RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO; 292*a677112dSAndrew Boyer if (features & IOCPT_HW_CHAIN) 293*a677112dSAndrew Boyer dev->features |= RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING; 294*a677112dSAndrew Boyer if (features & IOCPT_HW_IP) 295*a677112dSAndrew Boyer dev->features |= RTE_CRYPTODEV_FF_IN_PLACE_SGL; 296*a677112dSAndrew Boyer if (features & IOCPT_HW_OOP) { 297*a677112dSAndrew Boyer dev->features |= RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT; 298*a677112dSAndrew Boyer dev->features |= RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT; 299*a677112dSAndrew Boyer dev->features |= RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT; 300*a677112dSAndrew Boyer dev->features |= RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT; 301*a677112dSAndrew Boyer } 302*a677112dSAndrew Boyer 303*a677112dSAndrew Boyer IOCPT_PRINT(INFO, "crypto.features %#jx", 304*a677112dSAndrew Boyer rte_le_to_cpu_64(ident->features)); 305*a677112dSAndrew Boyer IOCPT_PRINT(INFO, "crypto.features_active %#jx", 306*a677112dSAndrew Boyer rte_le_to_cpu_64(cfg->features)); 307*a677112dSAndrew Boyer IOCPT_PRINT(INFO, "crypto.queue_count[IOCPT_QTYPE_ADMINQ] %#x", 308*a677112dSAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IOCPT_QTYPE_ADMINQ])); 309*a677112dSAndrew Boyer IOCPT_PRINT(INFO, "crypto.queue_count[IOCPT_QTYPE_NOTIFYQ] %#x", 310*a677112dSAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IOCPT_QTYPE_NOTIFYQ])); 311*a677112dSAndrew Boyer IOCPT_PRINT(INFO, "crypto.queue_count[IOCPT_QTYPE_CRYPTOQ] %#x", 312*a677112dSAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IOCPT_QTYPE_CRYPTOQ])); 313*a677112dSAndrew Boyer IOCPT_PRINT(INFO, "crypto.max_sessions %u", 314*a677112dSAndrew Boyer rte_le_to_cpu_32(ident->max_nb_sessions)); 315*a677112dSAndrew Boyer 316*a677112dSAndrew Boyer iocpt_queue_identify(dev); 317*a677112dSAndrew Boyer 318*a677112dSAndrew Boyer return 0; 319*a677112dSAndrew Boyer } 320*a677112dSAndrew Boyer 321*a677112dSAndrew Boyer int 322*a677112dSAndrew Boyer iocpt_dev_init(struct iocpt_dev *dev, rte_iova_t info_pa) 323*a677112dSAndrew Boyer { 324*a677112dSAndrew Boyer uint32_t retries = 5; 325*a677112dSAndrew Boyer int err; 326*a677112dSAndrew Boyer 327*a677112dSAndrew Boyer retry_lif_init: 328*a677112dSAndrew Boyer iocpt_dev_cmd_lif_init(dev, info_pa); 329*a677112dSAndrew Boyer 330*a677112dSAndrew Boyer err = iocpt_dev_cmd_wait_check(dev, IONIC_DEVCMD_TIMEOUT); 331*a677112dSAndrew Boyer if (err == -EAGAIN && retries > 0) { 332*a677112dSAndrew Boyer retries--; 333*a677112dSAndrew Boyer rte_delay_us_block(IONIC_DEVCMD_RETRY_WAIT_US); 334*a677112dSAndrew Boyer goto retry_lif_init; 335*a677112dSAndrew Boyer } 336*a677112dSAndrew Boyer 337*a677112dSAndrew Boyer return err; 338*a677112dSAndrew Boyer } 339*a677112dSAndrew Boyer 340*a677112dSAndrew Boyer void 341*a677112dSAndrew Boyer iocpt_dev_reset(struct iocpt_dev *dev) 342*a677112dSAndrew Boyer { 343*a677112dSAndrew Boyer iocpt_dev_cmd_lif_reset(dev); 344*a677112dSAndrew Boyer (void)iocpt_dev_cmd_wait_check(dev, IONIC_DEVCMD_TIMEOUT); 345*a677112dSAndrew Boyer 346*a677112dSAndrew Boyer iocpt_dev_cmd_reset(dev); 347*a677112dSAndrew Boyer (void)iocpt_dev_cmd_wait_check(dev, IONIC_DEVCMD_TIMEOUT); 348*a677112dSAndrew Boyer } 349