1*5ef51809SAlfredo Cardigliano /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2*5ef51809SAlfredo Cardigliano * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved. 3*5ef51809SAlfredo Cardigliano */ 4*5ef51809SAlfredo Cardigliano 5*5ef51809SAlfredo Cardigliano #include "ionic.h" 6*5ef51809SAlfredo Cardigliano 7*5ef51809SAlfredo Cardigliano static int 8*5ef51809SAlfredo Cardigliano ionic_dev_cmd_wait(struct ionic_dev *idev, unsigned long max_wait) 9*5ef51809SAlfredo Cardigliano { 10*5ef51809SAlfredo Cardigliano unsigned long step_msec = 100; 11*5ef51809SAlfredo Cardigliano unsigned int max_wait_msec = max_wait * 1000; 12*5ef51809SAlfredo Cardigliano unsigned long elapsed_msec = 0; 13*5ef51809SAlfredo Cardigliano int done; 14*5ef51809SAlfredo Cardigliano 15*5ef51809SAlfredo Cardigliano /* Wait for dev cmd to complete.. but no more than max_wait sec */ 16*5ef51809SAlfredo Cardigliano 17*5ef51809SAlfredo Cardigliano do { 18*5ef51809SAlfredo Cardigliano done = ionic_dev_cmd_done(idev); 19*5ef51809SAlfredo Cardigliano if (done) { 20*5ef51809SAlfredo Cardigliano IONIC_PRINT(DEBUG, "DEVCMD %d done took %ld msecs", 21*5ef51809SAlfredo Cardigliano idev->dev_cmd->cmd.cmd.opcode, 22*5ef51809SAlfredo Cardigliano elapsed_msec); 23*5ef51809SAlfredo Cardigliano return 0; 24*5ef51809SAlfredo Cardigliano } 25*5ef51809SAlfredo Cardigliano 26*5ef51809SAlfredo Cardigliano msec_delay(step_msec); 27*5ef51809SAlfredo Cardigliano 28*5ef51809SAlfredo Cardigliano elapsed_msec += step_msec; 29*5ef51809SAlfredo Cardigliano } while (elapsed_msec < max_wait_msec); 30*5ef51809SAlfredo Cardigliano 31*5ef51809SAlfredo Cardigliano IONIC_PRINT(DEBUG, "DEVCMD %d timeout after %ld msecs", 32*5ef51809SAlfredo Cardigliano idev->dev_cmd->cmd.cmd.opcode, 33*5ef51809SAlfredo Cardigliano elapsed_msec); 34*5ef51809SAlfredo Cardigliano 35*5ef51809SAlfredo Cardigliano return -ETIMEDOUT; 36*5ef51809SAlfredo Cardigliano } 37*5ef51809SAlfredo Cardigliano 38*5ef51809SAlfredo Cardigliano static int 39*5ef51809SAlfredo Cardigliano ionic_dev_cmd_check_error(struct ionic_dev *idev) 40*5ef51809SAlfredo Cardigliano { 41*5ef51809SAlfredo Cardigliano uint8_t status; 42*5ef51809SAlfredo Cardigliano 43*5ef51809SAlfredo Cardigliano status = ionic_dev_cmd_status(idev); 44*5ef51809SAlfredo Cardigliano if (status == 0) 45*5ef51809SAlfredo Cardigliano return 0; 46*5ef51809SAlfredo Cardigliano 47*5ef51809SAlfredo Cardigliano return -EIO; 48*5ef51809SAlfredo Cardigliano } 49*5ef51809SAlfredo Cardigliano 50*5ef51809SAlfredo Cardigliano int 51*5ef51809SAlfredo Cardigliano ionic_dev_cmd_wait_check(struct ionic_dev *idev, unsigned long max_wait) 52*5ef51809SAlfredo Cardigliano { 53*5ef51809SAlfredo Cardigliano int err; 54*5ef51809SAlfredo Cardigliano 55*5ef51809SAlfredo Cardigliano err = ionic_dev_cmd_wait(idev, max_wait); 56*5ef51809SAlfredo Cardigliano if (err) 57*5ef51809SAlfredo Cardigliano return err; 58*5ef51809SAlfredo Cardigliano 59*5ef51809SAlfredo Cardigliano return ionic_dev_cmd_check_error(idev); 60*5ef51809SAlfredo Cardigliano } 61*5ef51809SAlfredo Cardigliano 62*5ef51809SAlfredo Cardigliano int 63*5ef51809SAlfredo Cardigliano ionic_setup(struct ionic_adapter *adapter) 64*5ef51809SAlfredo Cardigliano { 65*5ef51809SAlfredo Cardigliano return ionic_dev_setup(adapter); 66*5ef51809SAlfredo Cardigliano } 67*5ef51809SAlfredo Cardigliano 68*5ef51809SAlfredo Cardigliano int 69*5ef51809SAlfredo Cardigliano ionic_identify(struct ionic_adapter *adapter) 70*5ef51809SAlfredo Cardigliano { 71*5ef51809SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 72*5ef51809SAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 73*5ef51809SAlfredo Cardigliano int err = 0; 74*5ef51809SAlfredo Cardigliano uint32_t i; 75*5ef51809SAlfredo Cardigliano unsigned int nwords; 76*5ef51809SAlfredo Cardigliano uint32_t drv_size = sizeof(ident->drv.words) / 77*5ef51809SAlfredo Cardigliano sizeof(ident->drv.words[0]); 78*5ef51809SAlfredo Cardigliano uint32_t cmd_size = sizeof(idev->dev_cmd->data) / 79*5ef51809SAlfredo Cardigliano sizeof(idev->dev_cmd->data[0]); 80*5ef51809SAlfredo Cardigliano uint32_t dev_size = sizeof(ident->dev.words) / 81*5ef51809SAlfredo Cardigliano sizeof(ident->dev.words[0]); 82*5ef51809SAlfredo Cardigliano 83*5ef51809SAlfredo Cardigliano memset(ident, 0, sizeof(*ident)); 84*5ef51809SAlfredo Cardigliano 85*5ef51809SAlfredo Cardigliano ident->drv.os_type = IONIC_OS_TYPE_LINUX; 86*5ef51809SAlfredo Cardigliano ident->drv.os_dist = 0; 87*5ef51809SAlfredo Cardigliano snprintf(ident->drv.os_dist_str, 88*5ef51809SAlfredo Cardigliano sizeof(ident->drv.os_dist_str), "Unknown"); 89*5ef51809SAlfredo Cardigliano ident->drv.kernel_ver = 0; 90*5ef51809SAlfredo Cardigliano snprintf(ident->drv.kernel_ver_str, 91*5ef51809SAlfredo Cardigliano sizeof(ident->drv.kernel_ver_str), "DPDK"); 92*5ef51809SAlfredo Cardigliano strncpy(ident->drv.driver_ver_str, IONIC_DRV_VERSION, 93*5ef51809SAlfredo Cardigliano sizeof(ident->drv.driver_ver_str) - 1); 94*5ef51809SAlfredo Cardigliano 95*5ef51809SAlfredo Cardigliano nwords = RTE_MIN(drv_size, cmd_size); 96*5ef51809SAlfredo Cardigliano for (i = 0; i < nwords; i++) 97*5ef51809SAlfredo Cardigliano iowrite32(ident->drv.words[i], &idev->dev_cmd->data[i]); 98*5ef51809SAlfredo Cardigliano 99*5ef51809SAlfredo Cardigliano ionic_dev_cmd_identify(idev, IONIC_IDENTITY_VERSION_1); 100*5ef51809SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 101*5ef51809SAlfredo Cardigliano if (!err) { 102*5ef51809SAlfredo Cardigliano nwords = RTE_MIN(dev_size, cmd_size); 103*5ef51809SAlfredo Cardigliano for (i = 0; i < nwords; i++) 104*5ef51809SAlfredo Cardigliano ident->dev.words[i] = ioread32(&idev->dev_cmd->data[i]); 105*5ef51809SAlfredo Cardigliano } 106*5ef51809SAlfredo Cardigliano 107*5ef51809SAlfredo Cardigliano return err; 108*5ef51809SAlfredo Cardigliano } 109*5ef51809SAlfredo Cardigliano 110*5ef51809SAlfredo Cardigliano int 111*5ef51809SAlfredo Cardigliano ionic_init(struct ionic_adapter *adapter) 112*5ef51809SAlfredo Cardigliano { 113*5ef51809SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 114*5ef51809SAlfredo Cardigliano int err; 115*5ef51809SAlfredo Cardigliano 116*5ef51809SAlfredo Cardigliano ionic_dev_cmd_init(idev); 117*5ef51809SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 118*5ef51809SAlfredo Cardigliano return err; 119*5ef51809SAlfredo Cardigliano } 120*5ef51809SAlfredo Cardigliano 121*5ef51809SAlfredo Cardigliano int 122*5ef51809SAlfredo Cardigliano ionic_reset(struct ionic_adapter *adapter) 123*5ef51809SAlfredo Cardigliano { 124*5ef51809SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 125*5ef51809SAlfredo Cardigliano int err; 126*5ef51809SAlfredo Cardigliano 127*5ef51809SAlfredo Cardigliano ionic_dev_cmd_reset(idev); 128*5ef51809SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 129*5ef51809SAlfredo Cardigliano return err; 130*5ef51809SAlfredo Cardigliano } 131