17c125393SAlfredo Cardigliano /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 27c125393SAlfredo Cardigliano * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved. 37c125393SAlfredo Cardigliano */ 47c125393SAlfredo Cardigliano 55ef51809SAlfredo Cardigliano #include <rte_pci.h> 65ef51809SAlfredo Cardigliano #include <rte_bus_pci.h> 75ef51809SAlfredo Cardigliano #include <rte_ethdev.h> 85ef51809SAlfredo Cardigliano #include <rte_ethdev_driver.h> 95ef51809SAlfredo Cardigliano #include <rte_malloc.h> 10669c8de6SAlfredo Cardigliano #include <rte_ethdev_pci.h> 115ef51809SAlfredo Cardigliano 127c125393SAlfredo Cardigliano #include "ionic_logs.h" 135ef51809SAlfredo Cardigliano #include "ionic.h" 145ef51809SAlfredo Cardigliano #include "ionic_dev.h" 155ef51809SAlfredo Cardigliano #include "ionic_mac_api.h" 16669c8de6SAlfredo Cardigliano #include "ionic_lif.h" 17669c8de6SAlfredo Cardigliano #include "ionic_ethdev.h" 18669c8de6SAlfredo Cardigliano 19669c8de6SAlfredo Cardigliano static int eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params); 20669c8de6SAlfredo Cardigliano static int eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev); 21*598f6726SAlfredo Cardigliano static int ionic_dev_info_get(struct rte_eth_dev *eth_dev, 22*598f6726SAlfredo Cardigliano struct rte_eth_dev_info *dev_info); 23*598f6726SAlfredo Cardigliano static int ionic_dev_configure(struct rte_eth_dev *dev); 24*598f6726SAlfredo Cardigliano static int ionic_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); 25*598f6726SAlfredo Cardigliano static int ionic_dev_start(struct rte_eth_dev *dev); 26*598f6726SAlfredo Cardigliano static void ionic_dev_stop(struct rte_eth_dev *dev); 27*598f6726SAlfredo Cardigliano static void ionic_dev_close(struct rte_eth_dev *dev); 28*598f6726SAlfredo Cardigliano static int ionic_dev_set_link_up(struct rte_eth_dev *dev); 29*598f6726SAlfredo Cardigliano static int ionic_dev_set_link_down(struct rte_eth_dev *dev); 30*598f6726SAlfredo Cardigliano static int ionic_dev_link_update(struct rte_eth_dev *eth_dev, 31*598f6726SAlfredo Cardigliano int wait_to_complete); 327c125393SAlfredo Cardigliano 337c125393SAlfredo Cardigliano int ionic_logtype; 347c125393SAlfredo Cardigliano 355ef51809SAlfredo Cardigliano static const struct rte_pci_id pci_id_ionic_map[] = { 365ef51809SAlfredo Cardigliano { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_PF) }, 375ef51809SAlfredo Cardigliano { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_VF) }, 385ef51809SAlfredo Cardigliano { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_MGMT) }, 395ef51809SAlfredo Cardigliano { .vendor_id = 0, /* sentinel */ }, 405ef51809SAlfredo Cardigliano }; 415ef51809SAlfredo Cardigliano 42669c8de6SAlfredo Cardigliano static const struct eth_dev_ops ionic_eth_dev_ops = { 43*598f6726SAlfredo Cardigliano .dev_infos_get = ionic_dev_info_get, 44*598f6726SAlfredo Cardigliano .dev_configure = ionic_dev_configure, 45*598f6726SAlfredo Cardigliano .mtu_set = ionic_dev_mtu_set, 46*598f6726SAlfredo Cardigliano .dev_start = ionic_dev_start, 47*598f6726SAlfredo Cardigliano .dev_stop = ionic_dev_stop, 48*598f6726SAlfredo Cardigliano .dev_close = ionic_dev_close, 49*598f6726SAlfredo Cardigliano .link_update = ionic_dev_link_update, 50*598f6726SAlfredo Cardigliano .dev_set_link_up = ionic_dev_set_link_up, 51*598f6726SAlfredo Cardigliano .dev_set_link_down = ionic_dev_set_link_down, 52669c8de6SAlfredo Cardigliano }; 53669c8de6SAlfredo Cardigliano 54*598f6726SAlfredo Cardigliano /* 55*598f6726SAlfredo Cardigliano * Set device link up, enable tx. 56*598f6726SAlfredo Cardigliano */ 57*598f6726SAlfredo Cardigliano static int 58*598f6726SAlfredo Cardigliano ionic_dev_set_link_up(struct rte_eth_dev *eth_dev) 59*598f6726SAlfredo Cardigliano { 60*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 61*598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 62*598f6726SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 63*598f6726SAlfredo Cardigliano int err; 64*598f6726SAlfredo Cardigliano 65*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 66*598f6726SAlfredo Cardigliano 67*598f6726SAlfredo Cardigliano ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP); 68*598f6726SAlfredo Cardigliano 69*598f6726SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 70*598f6726SAlfredo Cardigliano if (err) { 71*598f6726SAlfredo Cardigliano IONIC_PRINT(WARNING, "Failed to bring port UP"); 72*598f6726SAlfredo Cardigliano return err; 73*598f6726SAlfredo Cardigliano } 74*598f6726SAlfredo Cardigliano 75*598f6726SAlfredo Cardigliano return 0; 76*598f6726SAlfredo Cardigliano } 77*598f6726SAlfredo Cardigliano 78*598f6726SAlfredo Cardigliano /* 79*598f6726SAlfredo Cardigliano * Set device link down, disable tx. 80*598f6726SAlfredo Cardigliano */ 81*598f6726SAlfredo Cardigliano static int 82*598f6726SAlfredo Cardigliano ionic_dev_set_link_down(struct rte_eth_dev *eth_dev) 83*598f6726SAlfredo Cardigliano { 84*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 85*598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 86*598f6726SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 87*598f6726SAlfredo Cardigliano int err; 88*598f6726SAlfredo Cardigliano 89*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 90*598f6726SAlfredo Cardigliano 91*598f6726SAlfredo Cardigliano ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_DOWN); 92*598f6726SAlfredo Cardigliano 93*598f6726SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 94*598f6726SAlfredo Cardigliano if (err) { 95*598f6726SAlfredo Cardigliano IONIC_PRINT(WARNING, "Failed to bring port DOWN"); 96*598f6726SAlfredo Cardigliano return err; 97*598f6726SAlfredo Cardigliano } 98*598f6726SAlfredo Cardigliano 99*598f6726SAlfredo Cardigliano return 0; 100*598f6726SAlfredo Cardigliano } 101*598f6726SAlfredo Cardigliano 102*598f6726SAlfredo Cardigliano static int 103*598f6726SAlfredo Cardigliano ionic_dev_link_update(struct rte_eth_dev *eth_dev, 104*598f6726SAlfredo Cardigliano int wait_to_complete __rte_unused) 105*598f6726SAlfredo Cardigliano { 106*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 107*598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 108*598f6726SAlfredo Cardigliano struct rte_eth_link link; 109*598f6726SAlfredo Cardigliano 110*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 111*598f6726SAlfredo Cardigliano 112*598f6726SAlfredo Cardigliano /* Initialize */ 113*598f6726SAlfredo Cardigliano memset(&link, 0, sizeof(link)); 114*598f6726SAlfredo Cardigliano link.link_autoneg = ETH_LINK_AUTONEG; 115*598f6726SAlfredo Cardigliano 116*598f6726SAlfredo Cardigliano if (!adapter->link_up) { 117*598f6726SAlfredo Cardigliano /* Interface is down */ 118*598f6726SAlfredo Cardigliano link.link_status = ETH_LINK_DOWN; 119*598f6726SAlfredo Cardigliano link.link_duplex = ETH_LINK_HALF_DUPLEX; 120*598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_NONE; 121*598f6726SAlfredo Cardigliano } else { 122*598f6726SAlfredo Cardigliano /* Interface is up */ 123*598f6726SAlfredo Cardigliano link.link_status = ETH_LINK_UP; 124*598f6726SAlfredo Cardigliano link.link_duplex = ETH_LINK_FULL_DUPLEX; 125*598f6726SAlfredo Cardigliano switch (adapter->link_speed) { 126*598f6726SAlfredo Cardigliano case 10000: 127*598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_10G; 128*598f6726SAlfredo Cardigliano break; 129*598f6726SAlfredo Cardigliano case 25000: 130*598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_25G; 131*598f6726SAlfredo Cardigliano break; 132*598f6726SAlfredo Cardigliano case 40000: 133*598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_40G; 134*598f6726SAlfredo Cardigliano break; 135*598f6726SAlfredo Cardigliano case 50000: 136*598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_50G; 137*598f6726SAlfredo Cardigliano break; 138*598f6726SAlfredo Cardigliano case 100000: 139*598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_100G; 140*598f6726SAlfredo Cardigliano break; 141*598f6726SAlfredo Cardigliano default: 142*598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_NONE; 143*598f6726SAlfredo Cardigliano break; 144*598f6726SAlfredo Cardigliano } 145*598f6726SAlfredo Cardigliano } 146*598f6726SAlfredo Cardigliano 147*598f6726SAlfredo Cardigliano return rte_eth_linkstatus_set(eth_dev, &link); 148*598f6726SAlfredo Cardigliano } 149*598f6726SAlfredo Cardigliano 15027b942c8SAlfredo Cardigliano /** 15127b942c8SAlfredo Cardigliano * Interrupt handler triggered by NIC for handling 15227b942c8SAlfredo Cardigliano * specific interrupt. 15327b942c8SAlfredo Cardigliano * 15427b942c8SAlfredo Cardigliano * @param param 15527b942c8SAlfredo Cardigliano * The address of parameter registered before. 15627b942c8SAlfredo Cardigliano * 15727b942c8SAlfredo Cardigliano * @return 15827b942c8SAlfredo Cardigliano * void 15927b942c8SAlfredo Cardigliano */ 16027b942c8SAlfredo Cardigliano static void 16127b942c8SAlfredo Cardigliano ionic_dev_interrupt_handler(void *param) 16227b942c8SAlfredo Cardigliano { 16327b942c8SAlfredo Cardigliano struct ionic_adapter *adapter = (struct ionic_adapter *)param; 16427b942c8SAlfredo Cardigliano uint32_t i; 16527b942c8SAlfredo Cardigliano 16627b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "->"); 16727b942c8SAlfredo Cardigliano 16827b942c8SAlfredo Cardigliano for (i = 0; i < adapter->nlifs; i++) { 16927b942c8SAlfredo Cardigliano if (adapter->lifs[i]) 17027b942c8SAlfredo Cardigliano ionic_notifyq_handler(adapter->lifs[i], -1); 17127b942c8SAlfredo Cardigliano } 17227b942c8SAlfredo Cardigliano } 17327b942c8SAlfredo Cardigliano 174669c8de6SAlfredo Cardigliano static int 175*598f6726SAlfredo Cardigliano ionic_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) 176*598f6726SAlfredo Cardigliano { 177*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 178*598f6726SAlfredo Cardigliano uint32_t max_frame_size; 179*598f6726SAlfredo Cardigliano int err; 180*598f6726SAlfredo Cardigliano 181*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 182*598f6726SAlfredo Cardigliano 183*598f6726SAlfredo Cardigliano /* 184*598f6726SAlfredo Cardigliano * Note: mtu check against IONIC_MIN_MTU, IONIC_MAX_MTU 185*598f6726SAlfredo Cardigliano * is done by the the API. 186*598f6726SAlfredo Cardigliano */ 187*598f6726SAlfredo Cardigliano 188*598f6726SAlfredo Cardigliano /* 189*598f6726SAlfredo Cardigliano * Max frame size is MTU + Ethernet header + VLAN + QinQ 190*598f6726SAlfredo Cardigliano * (plus ETHER_CRC_LEN if the adapter is able to keep CRC) 191*598f6726SAlfredo Cardigliano */ 192*598f6726SAlfredo Cardigliano max_frame_size = mtu + RTE_ETHER_HDR_LEN + 4 + 4; 193*598f6726SAlfredo Cardigliano 194*598f6726SAlfredo Cardigliano if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len < max_frame_size) 195*598f6726SAlfredo Cardigliano return -EINVAL; 196*598f6726SAlfredo Cardigliano 197*598f6726SAlfredo Cardigliano err = ionic_lif_change_mtu(lif, mtu); 198*598f6726SAlfredo Cardigliano if (err) 199*598f6726SAlfredo Cardigliano return err; 200*598f6726SAlfredo Cardigliano 201*598f6726SAlfredo Cardigliano return 0; 202*598f6726SAlfredo Cardigliano } 203*598f6726SAlfredo Cardigliano 204*598f6726SAlfredo Cardigliano static int 205*598f6726SAlfredo Cardigliano ionic_dev_info_get(struct rte_eth_dev *eth_dev, 206*598f6726SAlfredo Cardigliano struct rte_eth_dev_info *dev_info) 207*598f6726SAlfredo Cardigliano { 208*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 209*598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 210*598f6726SAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 211*598f6726SAlfredo Cardigliano 212*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 213*598f6726SAlfredo Cardigliano 214*598f6726SAlfredo Cardigliano dev_info->max_rx_queues = (uint16_t) 215*598f6726SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ]; 216*598f6726SAlfredo Cardigliano dev_info->max_tx_queues = (uint16_t) 217*598f6726SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ]; 218*598f6726SAlfredo Cardigliano /* Also add ETHER_CRC_LEN if the adapter is able to keep CRC */ 219*598f6726SAlfredo Cardigliano dev_info->min_rx_bufsize = IONIC_MIN_MTU + RTE_ETHER_HDR_LEN; 220*598f6726SAlfredo Cardigliano dev_info->max_rx_pktlen = IONIC_MAX_MTU + RTE_ETHER_HDR_LEN; 221*598f6726SAlfredo Cardigliano dev_info->max_mac_addrs = adapter->max_mac_addrs; 222*598f6726SAlfredo Cardigliano dev_info->min_mtu = IONIC_MIN_MTU; 223*598f6726SAlfredo Cardigliano dev_info->max_mtu = IONIC_MAX_MTU; 224*598f6726SAlfredo Cardigliano 225*598f6726SAlfredo Cardigliano dev_info->speed_capa = 226*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_10G | 227*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_25G | 228*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_40G | 229*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_50G | 230*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_100G; 231*598f6726SAlfredo Cardigliano 232*598f6726SAlfredo Cardigliano return 0; 233*598f6726SAlfredo Cardigliano } 234*598f6726SAlfredo Cardigliano 235*598f6726SAlfredo Cardigliano static int 236*598f6726SAlfredo Cardigliano ionic_dev_configure(struct rte_eth_dev *eth_dev) 237*598f6726SAlfredo Cardigliano { 238*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 239*598f6726SAlfredo Cardigliano int err; 240*598f6726SAlfredo Cardigliano 241*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 242*598f6726SAlfredo Cardigliano 243*598f6726SAlfredo Cardigliano err = ionic_lif_configure(lif); 244*598f6726SAlfredo Cardigliano if (err) { 245*598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot configure LIF: %d", err); 246*598f6726SAlfredo Cardigliano return err; 247*598f6726SAlfredo Cardigliano } 248*598f6726SAlfredo Cardigliano 249*598f6726SAlfredo Cardigliano return 0; 250*598f6726SAlfredo Cardigliano } 251*598f6726SAlfredo Cardigliano 252*598f6726SAlfredo Cardigliano static inline uint32_t 253*598f6726SAlfredo Cardigliano ionic_parse_link_speeds(uint16_t link_speeds) 254*598f6726SAlfredo Cardigliano { 255*598f6726SAlfredo Cardigliano if (link_speeds & ETH_LINK_SPEED_100G) 256*598f6726SAlfredo Cardigliano return 100000; 257*598f6726SAlfredo Cardigliano else if (link_speeds & ETH_LINK_SPEED_50G) 258*598f6726SAlfredo Cardigliano return 50000; 259*598f6726SAlfredo Cardigliano else if (link_speeds & ETH_LINK_SPEED_40G) 260*598f6726SAlfredo Cardigliano return 40000; 261*598f6726SAlfredo Cardigliano else if (link_speeds & ETH_LINK_SPEED_25G) 262*598f6726SAlfredo Cardigliano return 25000; 263*598f6726SAlfredo Cardigliano else if (link_speeds & ETH_LINK_SPEED_10G) 264*598f6726SAlfredo Cardigliano return 10000; 265*598f6726SAlfredo Cardigliano else 266*598f6726SAlfredo Cardigliano return 0; 267*598f6726SAlfredo Cardigliano } 268*598f6726SAlfredo Cardigliano 269*598f6726SAlfredo Cardigliano /* 270*598f6726SAlfredo Cardigliano * Configure device link speed and setup link. 271*598f6726SAlfredo Cardigliano * It returns 0 on success. 272*598f6726SAlfredo Cardigliano */ 273*598f6726SAlfredo Cardigliano static int 274*598f6726SAlfredo Cardigliano ionic_dev_start(struct rte_eth_dev *eth_dev) 275*598f6726SAlfredo Cardigliano { 276*598f6726SAlfredo Cardigliano struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf; 277*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 278*598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 279*598f6726SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 280*598f6726SAlfredo Cardigliano uint32_t allowed_speeds; 281*598f6726SAlfredo Cardigliano int err; 282*598f6726SAlfredo Cardigliano 283*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 284*598f6726SAlfredo Cardigliano 285*598f6726SAlfredo Cardigliano allowed_speeds = 286*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_FIXED | 287*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_10G | 288*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_25G | 289*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_40G | 290*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_50G | 291*598f6726SAlfredo Cardigliano ETH_LINK_SPEED_100G; 292*598f6726SAlfredo Cardigliano 293*598f6726SAlfredo Cardigliano if (dev_conf->link_speeds & ~allowed_speeds) { 294*598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Invalid link setting"); 295*598f6726SAlfredo Cardigliano return -EINVAL; 296*598f6726SAlfredo Cardigliano } 297*598f6726SAlfredo Cardigliano 298*598f6726SAlfredo Cardigliano err = ionic_lif_start(lif); 299*598f6726SAlfredo Cardigliano if (err) { 300*598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot start LIF: %d", err); 301*598f6726SAlfredo Cardigliano return err; 302*598f6726SAlfredo Cardigliano } 303*598f6726SAlfredo Cardigliano 304*598f6726SAlfredo Cardigliano if (eth_dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) { 305*598f6726SAlfredo Cardigliano uint32_t speed = ionic_parse_link_speeds(dev_conf->link_speeds); 306*598f6726SAlfredo Cardigliano 307*598f6726SAlfredo Cardigliano if (speed) 308*598f6726SAlfredo Cardigliano ionic_dev_cmd_port_speed(idev, speed); 309*598f6726SAlfredo Cardigliano } 310*598f6726SAlfredo Cardigliano 311*598f6726SAlfredo Cardigliano ionic_dev_link_update(eth_dev, 0); 312*598f6726SAlfredo Cardigliano 313*598f6726SAlfredo Cardigliano return 0; 314*598f6726SAlfredo Cardigliano } 315*598f6726SAlfredo Cardigliano 316*598f6726SAlfredo Cardigliano /* 317*598f6726SAlfredo Cardigliano * Stop device: disable rx and tx functions to allow for reconfiguring. 318*598f6726SAlfredo Cardigliano */ 319*598f6726SAlfredo Cardigliano static void 320*598f6726SAlfredo Cardigliano ionic_dev_stop(struct rte_eth_dev *eth_dev) 321*598f6726SAlfredo Cardigliano { 322*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 323*598f6726SAlfredo Cardigliano int err; 324*598f6726SAlfredo Cardigliano 325*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 326*598f6726SAlfredo Cardigliano 327*598f6726SAlfredo Cardigliano err = ionic_lif_stop(lif); 328*598f6726SAlfredo Cardigliano if (err) 329*598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot stop LIF: %d", err); 330*598f6726SAlfredo Cardigliano } 331*598f6726SAlfredo Cardigliano 332*598f6726SAlfredo Cardigliano /* 333*598f6726SAlfredo Cardigliano * Reset and stop device. 334*598f6726SAlfredo Cardigliano */ 335*598f6726SAlfredo Cardigliano static void 336*598f6726SAlfredo Cardigliano ionic_dev_close(struct rte_eth_dev *eth_dev) 337*598f6726SAlfredo Cardigliano { 338*598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 339*598f6726SAlfredo Cardigliano int err; 340*598f6726SAlfredo Cardigliano 341*598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 342*598f6726SAlfredo Cardigliano 343*598f6726SAlfredo Cardigliano err = ionic_lif_stop(lif); 344*598f6726SAlfredo Cardigliano if (err) { 345*598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot stop LIF: %d", err); 346*598f6726SAlfredo Cardigliano return; 347*598f6726SAlfredo Cardigliano } 348*598f6726SAlfredo Cardigliano 349*598f6726SAlfredo Cardigliano err = eth_ionic_dev_uninit(eth_dev); 350*598f6726SAlfredo Cardigliano if (err) { 351*598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot destroy LIF: %d", err); 352*598f6726SAlfredo Cardigliano return; 353*598f6726SAlfredo Cardigliano } 354*598f6726SAlfredo Cardigliano } 355*598f6726SAlfredo Cardigliano 356*598f6726SAlfredo Cardigliano static int 357669c8de6SAlfredo Cardigliano eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params) 358669c8de6SAlfredo Cardigliano { 359669c8de6SAlfredo Cardigliano struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 360669c8de6SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 361669c8de6SAlfredo Cardigliano struct ionic_adapter *adapter = (struct ionic_adapter *)init_params; 362669c8de6SAlfredo Cardigliano int err; 363669c8de6SAlfredo Cardigliano 364669c8de6SAlfredo Cardigliano IONIC_PRINT_CALL(); 365669c8de6SAlfredo Cardigliano 366669c8de6SAlfredo Cardigliano eth_dev->dev_ops = &ionic_eth_dev_ops; 367669c8de6SAlfredo Cardigliano 368669c8de6SAlfredo Cardigliano /* Multi-process not supported, primary does initialization anyway */ 369669c8de6SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) 370669c8de6SAlfredo Cardigliano return 0; 371669c8de6SAlfredo Cardigliano 372669c8de6SAlfredo Cardigliano rte_eth_copy_pci_info(eth_dev, pci_dev); 373669c8de6SAlfredo Cardigliano 374669c8de6SAlfredo Cardigliano lif->index = adapter->nlifs; 375669c8de6SAlfredo Cardigliano lif->eth_dev = eth_dev; 376669c8de6SAlfredo Cardigliano lif->adapter = adapter; 377669c8de6SAlfredo Cardigliano adapter->lifs[adapter->nlifs] = lif; 378669c8de6SAlfredo Cardigliano 379*598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Up to %u MAC addresses supported", 380*598f6726SAlfredo Cardigliano adapter->max_mac_addrs); 381*598f6726SAlfredo Cardigliano 382*598f6726SAlfredo Cardigliano /* Allocate memory for storing MAC addresses */ 383*598f6726SAlfredo Cardigliano eth_dev->data->mac_addrs = rte_zmalloc("ionic", 384*598f6726SAlfredo Cardigliano RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs, 0); 385*598f6726SAlfredo Cardigliano 386*598f6726SAlfredo Cardigliano if (eth_dev->data->mac_addrs == NULL) { 387*598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Failed to allocate %u bytes needed to " 388*598f6726SAlfredo Cardigliano "store MAC addresses", 389*598f6726SAlfredo Cardigliano RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs); 390*598f6726SAlfredo Cardigliano err = -ENOMEM; 391*598f6726SAlfredo Cardigliano goto err; 392*598f6726SAlfredo Cardigliano } 393*598f6726SAlfredo Cardigliano 394669c8de6SAlfredo Cardigliano err = ionic_lif_alloc(lif); 395669c8de6SAlfredo Cardigliano if (err) { 396669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate LIFs: %d, aborting", 397669c8de6SAlfredo Cardigliano err); 398669c8de6SAlfredo Cardigliano goto err; 399669c8de6SAlfredo Cardigliano } 400669c8de6SAlfredo Cardigliano 401669c8de6SAlfredo Cardigliano err = ionic_lif_init(lif); 402669c8de6SAlfredo Cardigliano if (err) { 403669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init LIFs: %d, aborting", err); 404669c8de6SAlfredo Cardigliano goto err_free_lif; 405669c8de6SAlfredo Cardigliano } 406669c8de6SAlfredo Cardigliano 407*598f6726SAlfredo Cardigliano /* Copy the MAC address */ 408*598f6726SAlfredo Cardigliano rte_ether_addr_copy((struct rte_ether_addr *)lif->mac_addr, 409*598f6726SAlfredo Cardigliano ð_dev->data->mac_addrs[0]); 410*598f6726SAlfredo Cardigliano 411669c8de6SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Port %u initialized", eth_dev->data->port_id); 412669c8de6SAlfredo Cardigliano 413669c8de6SAlfredo Cardigliano return 0; 414669c8de6SAlfredo Cardigliano 415669c8de6SAlfredo Cardigliano err_free_lif: 416669c8de6SAlfredo Cardigliano ionic_lif_free(lif); 417669c8de6SAlfredo Cardigliano err: 418669c8de6SAlfredo Cardigliano return err; 419669c8de6SAlfredo Cardigliano } 420669c8de6SAlfredo Cardigliano 421669c8de6SAlfredo Cardigliano static int 422669c8de6SAlfredo Cardigliano eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev) 423669c8de6SAlfredo Cardigliano { 424669c8de6SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 425669c8de6SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 426669c8de6SAlfredo Cardigliano 427669c8de6SAlfredo Cardigliano IONIC_PRINT_CALL(); 428669c8de6SAlfredo Cardigliano 429669c8de6SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) 430669c8de6SAlfredo Cardigliano return 0; 431669c8de6SAlfredo Cardigliano 432669c8de6SAlfredo Cardigliano adapter->lifs[lif->index] = NULL; 433669c8de6SAlfredo Cardigliano 434669c8de6SAlfredo Cardigliano ionic_lif_deinit(lif); 435669c8de6SAlfredo Cardigliano ionic_lif_free(lif); 436669c8de6SAlfredo Cardigliano 437669c8de6SAlfredo Cardigliano eth_dev->dev_ops = NULL; 438669c8de6SAlfredo Cardigliano 439669c8de6SAlfredo Cardigliano return 0; 440669c8de6SAlfredo Cardigliano } 441669c8de6SAlfredo Cardigliano 4425ef51809SAlfredo Cardigliano static int 44327b942c8SAlfredo Cardigliano ionic_configure_intr(struct ionic_adapter *adapter) 44427b942c8SAlfredo Cardigliano { 44527b942c8SAlfredo Cardigliano struct rte_pci_device *pci_dev = adapter->pci_dev; 44627b942c8SAlfredo Cardigliano struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 44727b942c8SAlfredo Cardigliano int err; 44827b942c8SAlfredo Cardigliano 44927b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Configuring %u intrs", adapter->nintrs); 45027b942c8SAlfredo Cardigliano 45127b942c8SAlfredo Cardigliano if (rte_intr_efd_enable(intr_handle, adapter->nintrs)) { 45227b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Fail to create eventfd"); 45327b942c8SAlfredo Cardigliano return -1; 45427b942c8SAlfredo Cardigliano } 45527b942c8SAlfredo Cardigliano 45627b942c8SAlfredo Cardigliano if (rte_intr_dp_is_en(intr_handle)) 45727b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, 45827b942c8SAlfredo Cardigliano "Packet I/O interrupt on datapath is enabled"); 45927b942c8SAlfredo Cardigliano 46027b942c8SAlfredo Cardigliano if (!intr_handle->intr_vec) { 46127b942c8SAlfredo Cardigliano intr_handle->intr_vec = rte_zmalloc("intr_vec", 46227b942c8SAlfredo Cardigliano adapter->nintrs * sizeof(int), 0); 46327b942c8SAlfredo Cardigliano 46427b942c8SAlfredo Cardigliano if (!intr_handle->intr_vec) { 46527b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Failed to allocate %u vectors", 46627b942c8SAlfredo Cardigliano adapter->nintrs); 46727b942c8SAlfredo Cardigliano return -ENOMEM; 46827b942c8SAlfredo Cardigliano } 46927b942c8SAlfredo Cardigliano } 47027b942c8SAlfredo Cardigliano 47127b942c8SAlfredo Cardigliano err = rte_intr_callback_register(intr_handle, 47227b942c8SAlfredo Cardigliano ionic_dev_interrupt_handler, 47327b942c8SAlfredo Cardigliano adapter); 47427b942c8SAlfredo Cardigliano 47527b942c8SAlfredo Cardigliano if (err) { 47627b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, 47727b942c8SAlfredo Cardigliano "Failure registering interrupts handler (%d)", 47827b942c8SAlfredo Cardigliano err); 47927b942c8SAlfredo Cardigliano return err; 48027b942c8SAlfredo Cardigliano } 48127b942c8SAlfredo Cardigliano 48227b942c8SAlfredo Cardigliano /* enable intr mapping */ 48327b942c8SAlfredo Cardigliano err = rte_intr_enable(intr_handle); 48427b942c8SAlfredo Cardigliano 48527b942c8SAlfredo Cardigliano if (err) { 48627b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Failure enabling interrupts (%d)", err); 48727b942c8SAlfredo Cardigliano return err; 48827b942c8SAlfredo Cardigliano } 48927b942c8SAlfredo Cardigliano 49027b942c8SAlfredo Cardigliano return 0; 49127b942c8SAlfredo Cardigliano } 49227b942c8SAlfredo Cardigliano 49327b942c8SAlfredo Cardigliano static void 49427b942c8SAlfredo Cardigliano ionic_unconfigure_intr(struct ionic_adapter *adapter) 49527b942c8SAlfredo Cardigliano { 49627b942c8SAlfredo Cardigliano struct rte_pci_device *pci_dev = adapter->pci_dev; 49727b942c8SAlfredo Cardigliano struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 49827b942c8SAlfredo Cardigliano 49927b942c8SAlfredo Cardigliano rte_intr_disable(intr_handle); 50027b942c8SAlfredo Cardigliano 50127b942c8SAlfredo Cardigliano rte_intr_callback_unregister(intr_handle, 50227b942c8SAlfredo Cardigliano ionic_dev_interrupt_handler, 50327b942c8SAlfredo Cardigliano adapter); 50427b942c8SAlfredo Cardigliano } 50527b942c8SAlfredo Cardigliano 50627b942c8SAlfredo Cardigliano static int 5075ef51809SAlfredo Cardigliano eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 5085ef51809SAlfredo Cardigliano struct rte_pci_device *pci_dev) 5095ef51809SAlfredo Cardigliano { 510669c8de6SAlfredo Cardigliano char name[RTE_ETH_NAME_MAX_LEN]; 5115ef51809SAlfredo Cardigliano struct rte_mem_resource *resource; 5125ef51809SAlfredo Cardigliano struct ionic_adapter *adapter; 5135ef51809SAlfredo Cardigliano struct ionic_hw *hw; 5145ef51809SAlfredo Cardigliano unsigned long i; 5155ef51809SAlfredo Cardigliano int err; 5165ef51809SAlfredo Cardigliano 5175ef51809SAlfredo Cardigliano /* Check structs (trigger error at compilation time) */ 5185ef51809SAlfredo Cardigliano ionic_struct_size_checks(); 5195ef51809SAlfredo Cardigliano 5205ef51809SAlfredo Cardigliano /* Multi-process not supported */ 5215ef51809SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 5225ef51809SAlfredo Cardigliano err = -EPERM; 5235ef51809SAlfredo Cardigliano goto err; 5245ef51809SAlfredo Cardigliano } 5255ef51809SAlfredo Cardigliano 5265ef51809SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Initializing device %s", 5275ef51809SAlfredo Cardigliano pci_dev->device.name); 5285ef51809SAlfredo Cardigliano 5295ef51809SAlfredo Cardigliano adapter = rte_zmalloc("ionic", sizeof(*adapter), 0); 5305ef51809SAlfredo Cardigliano if (!adapter) { 5315ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "OOM"); 5325ef51809SAlfredo Cardigliano err = -ENOMEM; 5335ef51809SAlfredo Cardigliano goto err; 5345ef51809SAlfredo Cardigliano } 5355ef51809SAlfredo Cardigliano 5365ef51809SAlfredo Cardigliano adapter->pci_dev = pci_dev; 5375ef51809SAlfredo Cardigliano hw = &adapter->hw; 5385ef51809SAlfredo Cardigliano 5395ef51809SAlfredo Cardigliano hw->device_id = pci_dev->id.device_id; 5405ef51809SAlfredo Cardigliano hw->vendor_id = pci_dev->id.vendor_id; 5415ef51809SAlfredo Cardigliano 5425ef51809SAlfredo Cardigliano err = ionic_init_mac(hw); 5435ef51809SAlfredo Cardigliano if (err != 0) { 5445ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Mac init failed: %d", err); 5455ef51809SAlfredo Cardigliano err = -EIO; 5465ef51809SAlfredo Cardigliano goto err_free_adapter; 5475ef51809SAlfredo Cardigliano } 5485ef51809SAlfredo Cardigliano 5495ef51809SAlfredo Cardigliano adapter->is_mgmt_nic = (pci_dev->id.device_id == IONIC_DEV_ID_ETH_MGMT); 5505ef51809SAlfredo Cardigliano 5515ef51809SAlfredo Cardigliano adapter->num_bars = 0; 5525ef51809SAlfredo Cardigliano for (i = 0; i < PCI_MAX_RESOURCE && i < IONIC_BARS_MAX; i++) { 5535ef51809SAlfredo Cardigliano resource = &pci_dev->mem_resource[i]; 5545ef51809SAlfredo Cardigliano if (resource->phys_addr == 0 || resource->len == 0) 5555ef51809SAlfredo Cardigliano continue; 5565ef51809SAlfredo Cardigliano adapter->bars[adapter->num_bars].vaddr = resource->addr; 5575ef51809SAlfredo Cardigliano adapter->bars[adapter->num_bars].bus_addr = resource->phys_addr; 5585ef51809SAlfredo Cardigliano adapter->bars[adapter->num_bars].len = resource->len; 5595ef51809SAlfredo Cardigliano adapter->num_bars++; 5605ef51809SAlfredo Cardigliano } 5615ef51809SAlfredo Cardigliano 5625ef51809SAlfredo Cardigliano /* Discover ionic dev resources */ 5635ef51809SAlfredo Cardigliano 5645ef51809SAlfredo Cardigliano err = ionic_setup(adapter); 5655ef51809SAlfredo Cardigliano if (err) { 5665ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot setup device: %d, aborting", err); 5675ef51809SAlfredo Cardigliano goto err_free_adapter; 5685ef51809SAlfredo Cardigliano } 5695ef51809SAlfredo Cardigliano 5705ef51809SAlfredo Cardigliano err = ionic_identify(adapter); 5715ef51809SAlfredo Cardigliano if (err) { 5725ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify device: %d, aborting", 5735ef51809SAlfredo Cardigliano err); 5745ef51809SAlfredo Cardigliano goto err_free_adapter; 5755ef51809SAlfredo Cardigliano } 5765ef51809SAlfredo Cardigliano 5775ef51809SAlfredo Cardigliano err = ionic_init(adapter); 5785ef51809SAlfredo Cardigliano if (err) { 5795ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init device: %d, aborting", err); 5805ef51809SAlfredo Cardigliano goto err_free_adapter; 5815ef51809SAlfredo Cardigliano } 5825ef51809SAlfredo Cardigliano 58323bf4ddbSAlfredo Cardigliano /* Configure the ports */ 58423bf4ddbSAlfredo Cardigliano err = ionic_port_identify(adapter); 58523bf4ddbSAlfredo Cardigliano if (err) { 58623bf4ddbSAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify port: %d, aborting", 58723bf4ddbSAlfredo Cardigliano err); 58823bf4ddbSAlfredo Cardigliano goto err_free_adapter; 58923bf4ddbSAlfredo Cardigliano } 59023bf4ddbSAlfredo Cardigliano 59123bf4ddbSAlfredo Cardigliano err = ionic_port_init(adapter); 59223bf4ddbSAlfredo Cardigliano if (err) { 59323bf4ddbSAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init port: %d, aborting", err); 59423bf4ddbSAlfredo Cardigliano goto err_free_adapter; 59523bf4ddbSAlfredo Cardigliano } 59623bf4ddbSAlfredo Cardigliano 597669c8de6SAlfredo Cardigliano /* Configure LIFs */ 598669c8de6SAlfredo Cardigliano err = ionic_lif_identify(adapter); 599669c8de6SAlfredo Cardigliano if (err) { 600669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify lif: %d, aborting", err); 601669c8de6SAlfredo Cardigliano goto err_free_adapter; 602669c8de6SAlfredo Cardigliano } 603669c8de6SAlfredo Cardigliano 604669c8de6SAlfredo Cardigliano /* Allocate and init LIFs */ 605669c8de6SAlfredo Cardigliano err = ionic_lifs_size(adapter); 606669c8de6SAlfredo Cardigliano if (err) { 607669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot size LIFs: %d, aborting", err); 608669c8de6SAlfredo Cardigliano goto err_free_adapter; 609669c8de6SAlfredo Cardigliano } 610669c8de6SAlfredo Cardigliano 611*598f6726SAlfredo Cardigliano adapter->max_mac_addrs = adapter->ident.lif.eth.max_ucast_filters; 612*598f6726SAlfredo Cardigliano 613669c8de6SAlfredo Cardigliano adapter->nlifs = 0; 614669c8de6SAlfredo Cardigliano for (i = 0; i < adapter->ident.dev.nlifs; i++) { 615669c8de6SAlfredo Cardigliano snprintf(name, sizeof(name), "net_%s_lif_%lu", 616669c8de6SAlfredo Cardigliano pci_dev->device.name, i); 617669c8de6SAlfredo Cardigliano 618669c8de6SAlfredo Cardigliano err = rte_eth_dev_create(&pci_dev->device, name, 619669c8de6SAlfredo Cardigliano sizeof(struct ionic_lif), 620669c8de6SAlfredo Cardigliano NULL, NULL, 621669c8de6SAlfredo Cardigliano eth_ionic_dev_init, adapter); 622669c8de6SAlfredo Cardigliano if (err) { 623669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot create eth device for " 624669c8de6SAlfredo Cardigliano "ionic lif %s", name); 625669c8de6SAlfredo Cardigliano break; 626669c8de6SAlfredo Cardigliano } 627669c8de6SAlfredo Cardigliano 628669c8de6SAlfredo Cardigliano adapter->nlifs++; 629669c8de6SAlfredo Cardigliano } 630669c8de6SAlfredo Cardigliano 63127b942c8SAlfredo Cardigliano err = ionic_configure_intr(adapter); 63227b942c8SAlfredo Cardigliano 63327b942c8SAlfredo Cardigliano if (err) { 63427b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Failed to configure interrupts"); 63527b942c8SAlfredo Cardigliano goto err_free_adapter; 63627b942c8SAlfredo Cardigliano } 63727b942c8SAlfredo Cardigliano 6385ef51809SAlfredo Cardigliano return 0; 6395ef51809SAlfredo Cardigliano 6405ef51809SAlfredo Cardigliano err_free_adapter: 6415ef51809SAlfredo Cardigliano rte_free(adapter); 6425ef51809SAlfredo Cardigliano err: 6435ef51809SAlfredo Cardigliano return err; 6445ef51809SAlfredo Cardigliano } 6455ef51809SAlfredo Cardigliano 6465ef51809SAlfredo Cardigliano static int 6475ef51809SAlfredo Cardigliano eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused) 6485ef51809SAlfredo Cardigliano { 649669c8de6SAlfredo Cardigliano char name[RTE_ETH_NAME_MAX_LEN]; 650669c8de6SAlfredo Cardigliano struct ionic_adapter *adapter = NULL; 651669c8de6SAlfredo Cardigliano struct rte_eth_dev *eth_dev; 652669c8de6SAlfredo Cardigliano struct ionic_lif *lif; 653669c8de6SAlfredo Cardigliano uint32_t i; 654669c8de6SAlfredo Cardigliano 655669c8de6SAlfredo Cardigliano /* Adapter lookup is using (the first) eth_dev name */ 656669c8de6SAlfredo Cardigliano snprintf(name, sizeof(name), "net_%s_lif_0", 657669c8de6SAlfredo Cardigliano pci_dev->device.name); 658669c8de6SAlfredo Cardigliano 659669c8de6SAlfredo Cardigliano eth_dev = rte_eth_dev_allocated(name); 660669c8de6SAlfredo Cardigliano if (eth_dev) { 661669c8de6SAlfredo Cardigliano lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 662669c8de6SAlfredo Cardigliano adapter = lif->adapter; 663669c8de6SAlfredo Cardigliano } 664669c8de6SAlfredo Cardigliano 665669c8de6SAlfredo Cardigliano if (adapter) { 66627b942c8SAlfredo Cardigliano ionic_unconfigure_intr(adapter); 66727b942c8SAlfredo Cardigliano 668669c8de6SAlfredo Cardigliano for (i = 0; i < adapter->nlifs; i++) { 669669c8de6SAlfredo Cardigliano lif = adapter->lifs[i]; 670669c8de6SAlfredo Cardigliano rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit); 671669c8de6SAlfredo Cardigliano } 672669c8de6SAlfredo Cardigliano 673669c8de6SAlfredo Cardigliano rte_free(adapter); 674669c8de6SAlfredo Cardigliano } 675669c8de6SAlfredo Cardigliano 6765ef51809SAlfredo Cardigliano return 0; 6775ef51809SAlfredo Cardigliano } 6785ef51809SAlfredo Cardigliano 6795ef51809SAlfredo Cardigliano static struct rte_pci_driver rte_ionic_pmd = { 6805ef51809SAlfredo Cardigliano .id_table = pci_id_ionic_map, 6815ef51809SAlfredo Cardigliano .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 6825ef51809SAlfredo Cardigliano .probe = eth_ionic_pci_probe, 6835ef51809SAlfredo Cardigliano .remove = eth_ionic_pci_remove, 6845ef51809SAlfredo Cardigliano }; 6855ef51809SAlfredo Cardigliano 6865ef51809SAlfredo Cardigliano RTE_PMD_REGISTER_PCI(net_ionic, rte_ionic_pmd); 6875ef51809SAlfredo Cardigliano RTE_PMD_REGISTER_PCI_TABLE(net_ionic, pci_id_ionic_map); 6885ef51809SAlfredo Cardigliano RTE_PMD_REGISTER_KMOD_DEP(net_ionic, "* igb_uio | uio_pci_generic | vfio-pci"); 6895ef51809SAlfredo Cardigliano 6907c125393SAlfredo Cardigliano RTE_INIT(ionic_init_log) 6917c125393SAlfredo Cardigliano { 6927c125393SAlfredo Cardigliano ionic_logtype = rte_log_register("pmd.net.ionic"); 6937c125393SAlfredo Cardigliano if (ionic_logtype >= 0) 6947c125393SAlfredo Cardigliano rte_log_set_level(ionic_logtype, RTE_LOG_NOTICE); 6957c125393SAlfredo Cardigliano } 696