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" 18a27d9013SAlfredo Cardigliano #include "ionic_rxtx.h" 19669c8de6SAlfredo Cardigliano 20669c8de6SAlfredo Cardigliano static int eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params); 21669c8de6SAlfredo Cardigliano static int eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev); 22598f6726SAlfredo Cardigliano static int ionic_dev_info_get(struct rte_eth_dev *eth_dev, 23598f6726SAlfredo Cardigliano struct rte_eth_dev_info *dev_info); 24598f6726SAlfredo Cardigliano static int ionic_dev_configure(struct rte_eth_dev *dev); 25598f6726SAlfredo Cardigliano static int ionic_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); 26598f6726SAlfredo Cardigliano static int ionic_dev_start(struct rte_eth_dev *dev); 27598f6726SAlfredo Cardigliano static void ionic_dev_stop(struct rte_eth_dev *dev); 28598f6726SAlfredo Cardigliano static void ionic_dev_close(struct rte_eth_dev *dev); 29598f6726SAlfredo Cardigliano static int ionic_dev_set_link_up(struct rte_eth_dev *dev); 30598f6726SAlfredo Cardigliano static int ionic_dev_set_link_down(struct rte_eth_dev *dev); 31598f6726SAlfredo Cardigliano static int ionic_dev_link_update(struct rte_eth_dev *eth_dev, 32598f6726SAlfredo Cardigliano int wait_to_complete); 33ec15c66bSAlfredo Cardigliano static int ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev, 34ec15c66bSAlfredo Cardigliano struct rte_eth_fc_conf *fc_conf); 35ec15c66bSAlfredo Cardigliano static int ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev, 36ec15c66bSAlfredo Cardigliano struct rte_eth_fc_conf *fc_conf); 37a27d9013SAlfredo Cardigliano static int ionic_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask); 3822e7171bSAlfredo Cardigliano static int ionic_dev_rss_reta_update(struct rte_eth_dev *eth_dev, 3922e7171bSAlfredo Cardigliano struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); 4022e7171bSAlfredo Cardigliano static int ionic_dev_rss_reta_query(struct rte_eth_dev *eth_dev, 4122e7171bSAlfredo Cardigliano struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); 4222e7171bSAlfredo Cardigliano static int ionic_dev_rss_hash_conf_get(struct rte_eth_dev *eth_dev, 4322e7171bSAlfredo Cardigliano struct rte_eth_rss_conf *rss_conf); 4422e7171bSAlfredo Cardigliano static int ionic_dev_rss_hash_update(struct rte_eth_dev *eth_dev, 4522e7171bSAlfredo Cardigliano struct rte_eth_rss_conf *rss_conf); 46*3cdfd905SAlfredo Cardigliano static int ionic_dev_stats_get(struct rte_eth_dev *eth_dev, 47*3cdfd905SAlfredo Cardigliano struct rte_eth_stats *stats); 48*3cdfd905SAlfredo Cardigliano static int ionic_dev_stats_reset(struct rte_eth_dev *eth_dev); 49*3cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_get(struct rte_eth_dev *dev, 50*3cdfd905SAlfredo Cardigliano struct rte_eth_xstat *xstats, unsigned int n); 51*3cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_get_by_id(struct rte_eth_dev *dev, 52*3cdfd905SAlfredo Cardigliano const uint64_t *ids, uint64_t *values, unsigned int n); 53*3cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_reset(struct rte_eth_dev *dev); 54*3cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_get_names(struct rte_eth_dev *dev, 55*3cdfd905SAlfredo Cardigliano struct rte_eth_xstat_name *xstats_names, unsigned int size); 56*3cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, 57*3cdfd905SAlfredo Cardigliano struct rte_eth_xstat_name *xstats_names, const uint64_t *ids, 58*3cdfd905SAlfredo Cardigliano unsigned int limit); 597c125393SAlfredo Cardigliano 607c125393SAlfredo Cardigliano int ionic_logtype; 617c125393SAlfredo Cardigliano 625ef51809SAlfredo Cardigliano static const struct rte_pci_id pci_id_ionic_map[] = { 635ef51809SAlfredo Cardigliano { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_PF) }, 645ef51809SAlfredo Cardigliano { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_VF) }, 655ef51809SAlfredo Cardigliano { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_MGMT) }, 665ef51809SAlfredo Cardigliano { .vendor_id = 0, /* sentinel */ }, 675ef51809SAlfredo Cardigliano }; 685ef51809SAlfredo Cardigliano 69a27d9013SAlfredo Cardigliano static const struct rte_eth_desc_lim rx_desc_lim = { 70a27d9013SAlfredo Cardigliano .nb_max = IONIC_MAX_RING_DESC, 71a27d9013SAlfredo Cardigliano .nb_min = IONIC_MIN_RING_DESC, 72a27d9013SAlfredo Cardigliano .nb_align = 1, 73a27d9013SAlfredo Cardigliano }; 74a27d9013SAlfredo Cardigliano 75a27d9013SAlfredo Cardigliano static const struct rte_eth_desc_lim tx_desc_lim = { 76a27d9013SAlfredo Cardigliano .nb_max = IONIC_MAX_RING_DESC, 77a27d9013SAlfredo Cardigliano .nb_min = IONIC_MIN_RING_DESC, 78a27d9013SAlfredo Cardigliano .nb_align = 1, 79a27d9013SAlfredo Cardigliano .nb_seg_max = IONIC_TX_MAX_SG_ELEMS, 80a27d9013SAlfredo Cardigliano .nb_mtu_seg_max = IONIC_TX_MAX_SG_ELEMS, 81a27d9013SAlfredo Cardigliano }; 82a27d9013SAlfredo Cardigliano 83669c8de6SAlfredo Cardigliano static const struct eth_dev_ops ionic_eth_dev_ops = { 84598f6726SAlfredo Cardigliano .dev_infos_get = ionic_dev_info_get, 85598f6726SAlfredo Cardigliano .dev_configure = ionic_dev_configure, 86598f6726SAlfredo Cardigliano .mtu_set = ionic_dev_mtu_set, 87598f6726SAlfredo Cardigliano .dev_start = ionic_dev_start, 88598f6726SAlfredo Cardigliano .dev_stop = ionic_dev_stop, 89598f6726SAlfredo Cardigliano .dev_close = ionic_dev_close, 90598f6726SAlfredo Cardigliano .link_update = ionic_dev_link_update, 91598f6726SAlfredo Cardigliano .dev_set_link_up = ionic_dev_set_link_up, 92598f6726SAlfredo Cardigliano .dev_set_link_down = ionic_dev_set_link_down, 9354fe083fSAlfredo Cardigliano .mac_addr_add = ionic_dev_add_mac, 9454fe083fSAlfredo Cardigliano .mac_addr_remove = ionic_dev_remove_mac, 9554fe083fSAlfredo Cardigliano .mac_addr_set = ionic_dev_set_mac, 9654fe083fSAlfredo Cardigliano .vlan_filter_set = ionic_dev_vlan_filter_set, 9754fe083fSAlfredo Cardigliano .promiscuous_enable = ionic_dev_promiscuous_enable, 9854fe083fSAlfredo Cardigliano .promiscuous_disable = ionic_dev_promiscuous_disable, 9954fe083fSAlfredo Cardigliano .allmulticast_enable = ionic_dev_allmulticast_enable, 10054fe083fSAlfredo Cardigliano .allmulticast_disable = ionic_dev_allmulticast_disable, 101ec15c66bSAlfredo Cardigliano .flow_ctrl_get = ionic_flow_ctrl_get, 102ec15c66bSAlfredo Cardigliano .flow_ctrl_set = ionic_flow_ctrl_set, 103a27d9013SAlfredo Cardigliano .rxq_info_get = ionic_rxq_info_get, 104a27d9013SAlfredo Cardigliano .txq_info_get = ionic_txq_info_get, 105a27d9013SAlfredo Cardigliano .rx_queue_setup = ionic_dev_rx_queue_setup, 106a27d9013SAlfredo Cardigliano .rx_queue_release = ionic_dev_rx_queue_release, 107a27d9013SAlfredo Cardigliano .rx_queue_start = ionic_dev_rx_queue_start, 108a27d9013SAlfredo Cardigliano .rx_queue_stop = ionic_dev_rx_queue_stop, 109a27d9013SAlfredo Cardigliano .tx_queue_setup = ionic_dev_tx_queue_setup, 110a27d9013SAlfredo Cardigliano .tx_queue_release = ionic_dev_tx_queue_release, 111a27d9013SAlfredo Cardigliano .tx_queue_start = ionic_dev_tx_queue_start, 112a27d9013SAlfredo Cardigliano .tx_queue_stop = ionic_dev_tx_queue_stop, 113a27d9013SAlfredo Cardigliano .vlan_offload_set = ionic_vlan_offload_set, 11422e7171bSAlfredo Cardigliano .reta_update = ionic_dev_rss_reta_update, 11522e7171bSAlfredo Cardigliano .reta_query = ionic_dev_rss_reta_query, 11622e7171bSAlfredo Cardigliano .rss_hash_conf_get = ionic_dev_rss_hash_conf_get, 11722e7171bSAlfredo Cardigliano .rss_hash_update = ionic_dev_rss_hash_update, 118*3cdfd905SAlfredo Cardigliano .stats_get = ionic_dev_stats_get, 119*3cdfd905SAlfredo Cardigliano .stats_reset = ionic_dev_stats_reset, 120*3cdfd905SAlfredo Cardigliano .xstats_get = ionic_dev_xstats_get, 121*3cdfd905SAlfredo Cardigliano .xstats_get_by_id = ionic_dev_xstats_get_by_id, 122*3cdfd905SAlfredo Cardigliano .xstats_reset = ionic_dev_xstats_reset, 123*3cdfd905SAlfredo Cardigliano .xstats_get_names = ionic_dev_xstats_get_names, 124*3cdfd905SAlfredo Cardigliano .xstats_get_names_by_id = ionic_dev_xstats_get_names_by_id, 125669c8de6SAlfredo Cardigliano }; 126669c8de6SAlfredo Cardigliano 127*3cdfd905SAlfredo Cardigliano struct rte_ionic_xstats_name_off { 128*3cdfd905SAlfredo Cardigliano char name[RTE_ETH_XSTATS_NAME_SIZE]; 129*3cdfd905SAlfredo Cardigliano unsigned int offset; 130*3cdfd905SAlfredo Cardigliano }; 131*3cdfd905SAlfredo Cardigliano 132*3cdfd905SAlfredo Cardigliano static const struct rte_ionic_xstats_name_off rte_ionic_xstats_strings[] = { 133*3cdfd905SAlfredo Cardigliano /* RX */ 134*3cdfd905SAlfredo Cardigliano {"rx_ucast_bytes", offsetof(struct ionic_lif_stats, 135*3cdfd905SAlfredo Cardigliano rx_ucast_bytes)}, 136*3cdfd905SAlfredo Cardigliano {"rx_ucast_packets", offsetof(struct ionic_lif_stats, 137*3cdfd905SAlfredo Cardigliano rx_ucast_packets)}, 138*3cdfd905SAlfredo Cardigliano {"rx_mcast_bytes", offsetof(struct ionic_lif_stats, 139*3cdfd905SAlfredo Cardigliano rx_mcast_bytes)}, 140*3cdfd905SAlfredo Cardigliano {"rx_mcast_packets", offsetof(struct ionic_lif_stats, 141*3cdfd905SAlfredo Cardigliano rx_mcast_packets)}, 142*3cdfd905SAlfredo Cardigliano {"rx_bcast_bytes", offsetof(struct ionic_lif_stats, 143*3cdfd905SAlfredo Cardigliano rx_bcast_bytes)}, 144*3cdfd905SAlfredo Cardigliano {"rx_bcast_packets", offsetof(struct ionic_lif_stats, 145*3cdfd905SAlfredo Cardigliano rx_bcast_packets)}, 146*3cdfd905SAlfredo Cardigliano /* RX drops */ 147*3cdfd905SAlfredo Cardigliano {"rx_ucast_drop_bytes", offsetof(struct ionic_lif_stats, 148*3cdfd905SAlfredo Cardigliano rx_ucast_drop_bytes)}, 149*3cdfd905SAlfredo Cardigliano {"rx_ucast_drop_packets", offsetof(struct ionic_lif_stats, 150*3cdfd905SAlfredo Cardigliano rx_ucast_drop_packets)}, 151*3cdfd905SAlfredo Cardigliano {"rx_mcast_drop_bytes", offsetof(struct ionic_lif_stats, 152*3cdfd905SAlfredo Cardigliano rx_mcast_drop_bytes)}, 153*3cdfd905SAlfredo Cardigliano {"rx_mcast_drop_packets", offsetof(struct ionic_lif_stats, 154*3cdfd905SAlfredo Cardigliano rx_mcast_drop_packets)}, 155*3cdfd905SAlfredo Cardigliano {"rx_bcast_drop_bytes", offsetof(struct ionic_lif_stats, 156*3cdfd905SAlfredo Cardigliano rx_bcast_drop_bytes)}, 157*3cdfd905SAlfredo Cardigliano {"rx_bcast_drop_packets", offsetof(struct ionic_lif_stats, 158*3cdfd905SAlfredo Cardigliano rx_bcast_drop_packets)}, 159*3cdfd905SAlfredo Cardigliano {"rx_dma_error", offsetof(struct ionic_lif_stats, 160*3cdfd905SAlfredo Cardigliano rx_dma_error)}, 161*3cdfd905SAlfredo Cardigliano /* TX */ 162*3cdfd905SAlfredo Cardigliano {"tx_ucast_bytes", offsetof(struct ionic_lif_stats, 163*3cdfd905SAlfredo Cardigliano tx_ucast_bytes)}, 164*3cdfd905SAlfredo Cardigliano {"tx_ucast_packets", offsetof(struct ionic_lif_stats, 165*3cdfd905SAlfredo Cardigliano tx_ucast_packets)}, 166*3cdfd905SAlfredo Cardigliano {"tx_mcast_bytes", offsetof(struct ionic_lif_stats, 167*3cdfd905SAlfredo Cardigliano tx_mcast_bytes)}, 168*3cdfd905SAlfredo Cardigliano {"tx_mcast_packets", offsetof(struct ionic_lif_stats, 169*3cdfd905SAlfredo Cardigliano tx_mcast_packets)}, 170*3cdfd905SAlfredo Cardigliano {"tx_bcast_bytes", offsetof(struct ionic_lif_stats, 171*3cdfd905SAlfredo Cardigliano tx_bcast_bytes)}, 172*3cdfd905SAlfredo Cardigliano {"tx_bcast_packets", offsetof(struct ionic_lif_stats, 173*3cdfd905SAlfredo Cardigliano tx_bcast_packets)}, 174*3cdfd905SAlfredo Cardigliano /* TX drops */ 175*3cdfd905SAlfredo Cardigliano {"tx_ucast_drop_bytes", offsetof(struct ionic_lif_stats, 176*3cdfd905SAlfredo Cardigliano tx_ucast_drop_bytes)}, 177*3cdfd905SAlfredo Cardigliano {"tx_ucast_drop_packets", offsetof(struct ionic_lif_stats, 178*3cdfd905SAlfredo Cardigliano tx_ucast_drop_packets)}, 179*3cdfd905SAlfredo Cardigliano {"tx_mcast_drop_bytes", offsetof(struct ionic_lif_stats, 180*3cdfd905SAlfredo Cardigliano tx_mcast_drop_bytes)}, 181*3cdfd905SAlfredo Cardigliano {"tx_mcast_drop_packets", offsetof(struct ionic_lif_stats, 182*3cdfd905SAlfredo Cardigliano tx_mcast_drop_packets)}, 183*3cdfd905SAlfredo Cardigliano {"tx_bcast_drop_bytes", offsetof(struct ionic_lif_stats, 184*3cdfd905SAlfredo Cardigliano tx_bcast_drop_bytes)}, 185*3cdfd905SAlfredo Cardigliano {"tx_bcast_drop_packets", offsetof(struct ionic_lif_stats, 186*3cdfd905SAlfredo Cardigliano tx_bcast_drop_packets)}, 187*3cdfd905SAlfredo Cardigliano {"tx_dma_error", offsetof(struct ionic_lif_stats, 188*3cdfd905SAlfredo Cardigliano tx_dma_error)}, 189*3cdfd905SAlfredo Cardigliano /* Rx Queue/Ring drops */ 190*3cdfd905SAlfredo Cardigliano {"rx_queue_disabled", offsetof(struct ionic_lif_stats, 191*3cdfd905SAlfredo Cardigliano rx_queue_disabled)}, 192*3cdfd905SAlfredo Cardigliano {"rx_queue_empty", offsetof(struct ionic_lif_stats, 193*3cdfd905SAlfredo Cardigliano rx_queue_empty)}, 194*3cdfd905SAlfredo Cardigliano {"rx_queue_error", offsetof(struct ionic_lif_stats, 195*3cdfd905SAlfredo Cardigliano rx_queue_error)}, 196*3cdfd905SAlfredo Cardigliano {"rx_desc_fetch_error", offsetof(struct ionic_lif_stats, 197*3cdfd905SAlfredo Cardigliano rx_desc_fetch_error)}, 198*3cdfd905SAlfredo Cardigliano {"rx_desc_data_error", offsetof(struct ionic_lif_stats, 199*3cdfd905SAlfredo Cardigliano rx_desc_data_error)}, 200*3cdfd905SAlfredo Cardigliano /* Tx Queue/Ring drops */ 201*3cdfd905SAlfredo Cardigliano {"tx_queue_disabled", offsetof(struct ionic_lif_stats, 202*3cdfd905SAlfredo Cardigliano tx_queue_disabled)}, 203*3cdfd905SAlfredo Cardigliano {"tx_queue_error", offsetof(struct ionic_lif_stats, 204*3cdfd905SAlfredo Cardigliano tx_queue_error)}, 205*3cdfd905SAlfredo Cardigliano {"tx_desc_fetch_error", offsetof(struct ionic_lif_stats, 206*3cdfd905SAlfredo Cardigliano tx_desc_fetch_error)}, 207*3cdfd905SAlfredo Cardigliano {"tx_desc_data_error", offsetof(struct ionic_lif_stats, 208*3cdfd905SAlfredo Cardigliano tx_desc_data_error)}, 209*3cdfd905SAlfredo Cardigliano }; 210*3cdfd905SAlfredo Cardigliano 211*3cdfd905SAlfredo Cardigliano #define IONIC_NB_HW_STATS (sizeof(rte_ionic_xstats_strings) / \ 212*3cdfd905SAlfredo Cardigliano sizeof(rte_ionic_xstats_strings[0])) 213*3cdfd905SAlfredo Cardigliano 214598f6726SAlfredo Cardigliano /* 215598f6726SAlfredo Cardigliano * Set device link up, enable tx. 216598f6726SAlfredo Cardigliano */ 217598f6726SAlfredo Cardigliano static int 218598f6726SAlfredo Cardigliano ionic_dev_set_link_up(struct rte_eth_dev *eth_dev) 219598f6726SAlfredo Cardigliano { 220598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 221598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 222598f6726SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 223598f6726SAlfredo Cardigliano int err; 224598f6726SAlfredo Cardigliano 225598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 226598f6726SAlfredo Cardigliano 227598f6726SAlfredo Cardigliano ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP); 228598f6726SAlfredo Cardigliano 229598f6726SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 230598f6726SAlfredo Cardigliano if (err) { 231598f6726SAlfredo Cardigliano IONIC_PRINT(WARNING, "Failed to bring port UP"); 232598f6726SAlfredo Cardigliano return err; 233598f6726SAlfredo Cardigliano } 234598f6726SAlfredo Cardigliano 235598f6726SAlfredo Cardigliano return 0; 236598f6726SAlfredo Cardigliano } 237598f6726SAlfredo Cardigliano 238598f6726SAlfredo Cardigliano /* 239598f6726SAlfredo Cardigliano * Set device link down, disable tx. 240598f6726SAlfredo Cardigliano */ 241598f6726SAlfredo Cardigliano static int 242598f6726SAlfredo Cardigliano ionic_dev_set_link_down(struct rte_eth_dev *eth_dev) 243598f6726SAlfredo Cardigliano { 244598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 245598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 246598f6726SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 247598f6726SAlfredo Cardigliano int err; 248598f6726SAlfredo Cardigliano 249598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 250598f6726SAlfredo Cardigliano 251598f6726SAlfredo Cardigliano ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_DOWN); 252598f6726SAlfredo Cardigliano 253598f6726SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 254598f6726SAlfredo Cardigliano if (err) { 255598f6726SAlfredo Cardigliano IONIC_PRINT(WARNING, "Failed to bring port DOWN"); 256598f6726SAlfredo Cardigliano return err; 257598f6726SAlfredo Cardigliano } 258598f6726SAlfredo Cardigliano 259598f6726SAlfredo Cardigliano return 0; 260598f6726SAlfredo Cardigliano } 261598f6726SAlfredo Cardigliano 262598f6726SAlfredo Cardigliano static int 263598f6726SAlfredo Cardigliano ionic_dev_link_update(struct rte_eth_dev *eth_dev, 264598f6726SAlfredo Cardigliano int wait_to_complete __rte_unused) 265598f6726SAlfredo Cardigliano { 266598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 267598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 268598f6726SAlfredo Cardigliano struct rte_eth_link link; 269598f6726SAlfredo Cardigliano 270598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 271598f6726SAlfredo Cardigliano 272598f6726SAlfredo Cardigliano /* Initialize */ 273598f6726SAlfredo Cardigliano memset(&link, 0, sizeof(link)); 274598f6726SAlfredo Cardigliano link.link_autoneg = ETH_LINK_AUTONEG; 275598f6726SAlfredo Cardigliano 276598f6726SAlfredo Cardigliano if (!adapter->link_up) { 277598f6726SAlfredo Cardigliano /* Interface is down */ 278598f6726SAlfredo Cardigliano link.link_status = ETH_LINK_DOWN; 279598f6726SAlfredo Cardigliano link.link_duplex = ETH_LINK_HALF_DUPLEX; 280598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_NONE; 281598f6726SAlfredo Cardigliano } else { 282598f6726SAlfredo Cardigliano /* Interface is up */ 283598f6726SAlfredo Cardigliano link.link_status = ETH_LINK_UP; 284598f6726SAlfredo Cardigliano link.link_duplex = ETH_LINK_FULL_DUPLEX; 285598f6726SAlfredo Cardigliano switch (adapter->link_speed) { 286598f6726SAlfredo Cardigliano case 10000: 287598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_10G; 288598f6726SAlfredo Cardigliano break; 289598f6726SAlfredo Cardigliano case 25000: 290598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_25G; 291598f6726SAlfredo Cardigliano break; 292598f6726SAlfredo Cardigliano case 40000: 293598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_40G; 294598f6726SAlfredo Cardigliano break; 295598f6726SAlfredo Cardigliano case 50000: 296598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_50G; 297598f6726SAlfredo Cardigliano break; 298598f6726SAlfredo Cardigliano case 100000: 299598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_100G; 300598f6726SAlfredo Cardigliano break; 301598f6726SAlfredo Cardigliano default: 302598f6726SAlfredo Cardigliano link.link_speed = ETH_SPEED_NUM_NONE; 303598f6726SAlfredo Cardigliano break; 304598f6726SAlfredo Cardigliano } 305598f6726SAlfredo Cardigliano } 306598f6726SAlfredo Cardigliano 307598f6726SAlfredo Cardigliano return rte_eth_linkstatus_set(eth_dev, &link); 308598f6726SAlfredo Cardigliano } 309598f6726SAlfredo Cardigliano 31027b942c8SAlfredo Cardigliano /** 31127b942c8SAlfredo Cardigliano * Interrupt handler triggered by NIC for handling 31227b942c8SAlfredo Cardigliano * specific interrupt. 31327b942c8SAlfredo Cardigliano * 31427b942c8SAlfredo Cardigliano * @param param 31527b942c8SAlfredo Cardigliano * The address of parameter registered before. 31627b942c8SAlfredo Cardigliano * 31727b942c8SAlfredo Cardigliano * @return 31827b942c8SAlfredo Cardigliano * void 31927b942c8SAlfredo Cardigliano */ 32027b942c8SAlfredo Cardigliano static void 32127b942c8SAlfredo Cardigliano ionic_dev_interrupt_handler(void *param) 32227b942c8SAlfredo Cardigliano { 32327b942c8SAlfredo Cardigliano struct ionic_adapter *adapter = (struct ionic_adapter *)param; 32427b942c8SAlfredo Cardigliano uint32_t i; 32527b942c8SAlfredo Cardigliano 32627b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "->"); 32727b942c8SAlfredo Cardigliano 32827b942c8SAlfredo Cardigliano for (i = 0; i < adapter->nlifs; i++) { 32927b942c8SAlfredo Cardigliano if (adapter->lifs[i]) 33027b942c8SAlfredo Cardigliano ionic_notifyq_handler(adapter->lifs[i], -1); 33127b942c8SAlfredo Cardigliano } 33227b942c8SAlfredo Cardigliano } 33327b942c8SAlfredo Cardigliano 334669c8de6SAlfredo Cardigliano static int 335598f6726SAlfredo Cardigliano ionic_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) 336598f6726SAlfredo Cardigliano { 337598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 338598f6726SAlfredo Cardigliano uint32_t max_frame_size; 339598f6726SAlfredo Cardigliano int err; 340598f6726SAlfredo Cardigliano 341598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 342598f6726SAlfredo Cardigliano 343598f6726SAlfredo Cardigliano /* 344598f6726SAlfredo Cardigliano * Note: mtu check against IONIC_MIN_MTU, IONIC_MAX_MTU 345598f6726SAlfredo Cardigliano * is done by the the API. 346598f6726SAlfredo Cardigliano */ 347598f6726SAlfredo Cardigliano 348598f6726SAlfredo Cardigliano /* 349598f6726SAlfredo Cardigliano * Max frame size is MTU + Ethernet header + VLAN + QinQ 350598f6726SAlfredo Cardigliano * (plus ETHER_CRC_LEN if the adapter is able to keep CRC) 351598f6726SAlfredo Cardigliano */ 352598f6726SAlfredo Cardigliano max_frame_size = mtu + RTE_ETHER_HDR_LEN + 4 + 4; 353598f6726SAlfredo Cardigliano 354598f6726SAlfredo Cardigliano if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len < max_frame_size) 355598f6726SAlfredo Cardigliano return -EINVAL; 356598f6726SAlfredo Cardigliano 357598f6726SAlfredo Cardigliano err = ionic_lif_change_mtu(lif, mtu); 358598f6726SAlfredo Cardigliano if (err) 359598f6726SAlfredo Cardigliano return err; 360598f6726SAlfredo Cardigliano 361598f6726SAlfredo Cardigliano return 0; 362598f6726SAlfredo Cardigliano } 363598f6726SAlfredo Cardigliano 364598f6726SAlfredo Cardigliano static int 365598f6726SAlfredo Cardigliano ionic_dev_info_get(struct rte_eth_dev *eth_dev, 366598f6726SAlfredo Cardigliano struct rte_eth_dev_info *dev_info) 367598f6726SAlfredo Cardigliano { 368598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 369598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 370598f6726SAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 371598f6726SAlfredo Cardigliano 372598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 373598f6726SAlfredo Cardigliano 374598f6726SAlfredo Cardigliano dev_info->max_rx_queues = (uint16_t) 375598f6726SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ]; 376598f6726SAlfredo Cardigliano dev_info->max_tx_queues = (uint16_t) 377598f6726SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ]; 378598f6726SAlfredo Cardigliano /* Also add ETHER_CRC_LEN if the adapter is able to keep CRC */ 379598f6726SAlfredo Cardigliano dev_info->min_rx_bufsize = IONIC_MIN_MTU + RTE_ETHER_HDR_LEN; 380598f6726SAlfredo Cardigliano dev_info->max_rx_pktlen = IONIC_MAX_MTU + RTE_ETHER_HDR_LEN; 381598f6726SAlfredo Cardigliano dev_info->max_mac_addrs = adapter->max_mac_addrs; 382598f6726SAlfredo Cardigliano dev_info->min_mtu = IONIC_MIN_MTU; 383598f6726SAlfredo Cardigliano dev_info->max_mtu = IONIC_MAX_MTU; 384598f6726SAlfredo Cardigliano 38522e7171bSAlfredo Cardigliano dev_info->hash_key_size = IONIC_RSS_HASH_KEY_SIZE; 38622e7171bSAlfredo Cardigliano dev_info->reta_size = ident->lif.eth.rss_ind_tbl_sz; 38722e7171bSAlfredo Cardigliano dev_info->flow_type_rss_offloads = IONIC_ETH_RSS_OFFLOAD_ALL; 38822e7171bSAlfredo Cardigliano 389598f6726SAlfredo Cardigliano dev_info->speed_capa = 390598f6726SAlfredo Cardigliano ETH_LINK_SPEED_10G | 391598f6726SAlfredo Cardigliano ETH_LINK_SPEED_25G | 392598f6726SAlfredo Cardigliano ETH_LINK_SPEED_40G | 393598f6726SAlfredo Cardigliano ETH_LINK_SPEED_50G | 394598f6726SAlfredo Cardigliano ETH_LINK_SPEED_100G; 395598f6726SAlfredo Cardigliano 396a27d9013SAlfredo Cardigliano /* 397a27d9013SAlfredo Cardigliano * Per-queue capabilities. Actually most of the offloads are enabled 398a27d9013SAlfredo Cardigliano * by default on the port and can be used on selected queues (by adding 399a27d9013SAlfredo Cardigliano * packet flags at runtime when required) 400a27d9013SAlfredo Cardigliano */ 401a27d9013SAlfredo Cardigliano 402a27d9013SAlfredo Cardigliano dev_info->rx_queue_offload_capa = 403a27d9013SAlfredo Cardigliano DEV_RX_OFFLOAD_IPV4_CKSUM | 404a27d9013SAlfredo Cardigliano DEV_RX_OFFLOAD_UDP_CKSUM | 405a27d9013SAlfredo Cardigliano DEV_RX_OFFLOAD_TCP_CKSUM | 406a27d9013SAlfredo Cardigliano 0; 407a27d9013SAlfredo Cardigliano 408a27d9013SAlfredo Cardigliano dev_info->tx_queue_offload_capa = 409a27d9013SAlfredo Cardigliano DEV_TX_OFFLOAD_VLAN_INSERT | 410a27d9013SAlfredo Cardigliano 0; 411a27d9013SAlfredo Cardigliano 412a27d9013SAlfredo Cardigliano /* 413a27d9013SAlfredo Cardigliano * Per-port capabilities 414a27d9013SAlfredo Cardigliano * See ionic_set_features to request and check supported features 415a27d9013SAlfredo Cardigliano */ 416a27d9013SAlfredo Cardigliano 417a27d9013SAlfredo Cardigliano dev_info->rx_offload_capa = dev_info->rx_queue_offload_capa | 418a27d9013SAlfredo Cardigliano DEV_RX_OFFLOAD_JUMBO_FRAME | 419a27d9013SAlfredo Cardigliano DEV_RX_OFFLOAD_VLAN_FILTER | 420a27d9013SAlfredo Cardigliano DEV_RX_OFFLOAD_VLAN_STRIP | 421a27d9013SAlfredo Cardigliano DEV_RX_OFFLOAD_SCATTER | 422a27d9013SAlfredo Cardigliano 0; 423a27d9013SAlfredo Cardigliano 424a27d9013SAlfredo Cardigliano dev_info->tx_offload_capa = dev_info->tx_queue_offload_capa | 425a27d9013SAlfredo Cardigliano DEV_TX_OFFLOAD_MULTI_SEGS | 426a27d9013SAlfredo Cardigliano DEV_TX_OFFLOAD_TCP_TSO | 427a27d9013SAlfredo Cardigliano 0; 428a27d9013SAlfredo Cardigliano 429a27d9013SAlfredo Cardigliano dev_info->rx_desc_lim = rx_desc_lim; 430a27d9013SAlfredo Cardigliano dev_info->tx_desc_lim = tx_desc_lim; 431a27d9013SAlfredo Cardigliano 432a27d9013SAlfredo Cardigliano /* Driver-preferred Rx/Tx parameters */ 433a27d9013SAlfredo Cardigliano dev_info->default_rxportconf.burst_size = 32; 434a27d9013SAlfredo Cardigliano dev_info->default_txportconf.burst_size = 32; 435a27d9013SAlfredo Cardigliano dev_info->default_rxportconf.nb_queues = 1; 436a27d9013SAlfredo Cardigliano dev_info->default_txportconf.nb_queues = 1; 437a27d9013SAlfredo Cardigliano dev_info->default_rxportconf.ring_size = IONIC_DEF_TXRX_DESC; 438a27d9013SAlfredo Cardigliano dev_info->default_txportconf.ring_size = IONIC_DEF_TXRX_DESC; 439a27d9013SAlfredo Cardigliano 440598f6726SAlfredo Cardigliano return 0; 441598f6726SAlfredo Cardigliano } 442598f6726SAlfredo Cardigliano 443598f6726SAlfredo Cardigliano static int 444ec15c66bSAlfredo Cardigliano ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev, 445ec15c66bSAlfredo Cardigliano struct rte_eth_fc_conf *fc_conf) 446ec15c66bSAlfredo Cardigliano { 447ec15c66bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 448ec15c66bSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 449ec15c66bSAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 450ec15c66bSAlfredo Cardigliano 451ec15c66bSAlfredo Cardigliano if (idev->port_info) { 452ec15c66bSAlfredo Cardigliano fc_conf->autoneg = idev->port_info->config.an_enable; 453ec15c66bSAlfredo Cardigliano 454ec15c66bSAlfredo Cardigliano if (idev->port_info->config.pause_type) 455ec15c66bSAlfredo Cardigliano fc_conf->mode = RTE_FC_FULL; 456ec15c66bSAlfredo Cardigliano else 457ec15c66bSAlfredo Cardigliano fc_conf->mode = RTE_FC_NONE; 458ec15c66bSAlfredo Cardigliano } 459ec15c66bSAlfredo Cardigliano 460ec15c66bSAlfredo Cardigliano return 0; 461ec15c66bSAlfredo Cardigliano } 462ec15c66bSAlfredo Cardigliano 463ec15c66bSAlfredo Cardigliano static int 464ec15c66bSAlfredo Cardigliano ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev, 465ec15c66bSAlfredo Cardigliano struct rte_eth_fc_conf *fc_conf) 466ec15c66bSAlfredo Cardigliano { 467ec15c66bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 468ec15c66bSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 469ec15c66bSAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 470ec15c66bSAlfredo Cardigliano uint8_t pause_type = IONIC_PORT_PAUSE_TYPE_NONE; 471ec15c66bSAlfredo Cardigliano uint8_t an_enable; 472ec15c66bSAlfredo Cardigliano 473ec15c66bSAlfredo Cardigliano switch (fc_conf->mode) { 474ec15c66bSAlfredo Cardigliano case RTE_FC_NONE: 475ec15c66bSAlfredo Cardigliano pause_type = IONIC_PORT_PAUSE_TYPE_NONE; 476ec15c66bSAlfredo Cardigliano break; 477ec15c66bSAlfredo Cardigliano case RTE_FC_FULL: 478ec15c66bSAlfredo Cardigliano pause_type = IONIC_PORT_PAUSE_TYPE_LINK; 479ec15c66bSAlfredo Cardigliano break; 480ec15c66bSAlfredo Cardigliano case RTE_FC_RX_PAUSE: 481ec15c66bSAlfredo Cardigliano case RTE_FC_TX_PAUSE: 482ec15c66bSAlfredo Cardigliano return -ENOTSUP; 483ec15c66bSAlfredo Cardigliano } 484ec15c66bSAlfredo Cardigliano 485ec15c66bSAlfredo Cardigliano an_enable = fc_conf->autoneg; 486ec15c66bSAlfredo Cardigliano 487ec15c66bSAlfredo Cardigliano ionic_dev_cmd_port_pause(idev, pause_type); 488ec15c66bSAlfredo Cardigliano ionic_dev_cmd_port_autoneg(idev, an_enable); 489ec15c66bSAlfredo Cardigliano 490ec15c66bSAlfredo Cardigliano return 0; 491ec15c66bSAlfredo Cardigliano } 492ec15c66bSAlfredo Cardigliano 493ec15c66bSAlfredo Cardigliano static int 494a27d9013SAlfredo Cardigliano ionic_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) 495a27d9013SAlfredo Cardigliano { 496a27d9013SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 497a27d9013SAlfredo Cardigliano struct rte_eth_rxmode *rxmode; 498a27d9013SAlfredo Cardigliano rxmode = ð_dev->data->dev_conf.rxmode; 499a27d9013SAlfredo Cardigliano int i; 500a27d9013SAlfredo Cardigliano 501a27d9013SAlfredo Cardigliano if (mask & ETH_VLAN_STRIP_MASK) { 502a27d9013SAlfredo Cardigliano if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) { 503a27d9013SAlfredo Cardigliano for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { 504a27d9013SAlfredo Cardigliano struct ionic_qcq *rxq = 505a27d9013SAlfredo Cardigliano eth_dev->data->rx_queues[i]; 506a27d9013SAlfredo Cardigliano rxq->offloads |= DEV_RX_OFFLOAD_VLAN_STRIP; 507a27d9013SAlfredo Cardigliano } 508a27d9013SAlfredo Cardigliano lif->features |= IONIC_ETH_HW_VLAN_RX_STRIP; 509a27d9013SAlfredo Cardigliano } else { 510a27d9013SAlfredo Cardigliano for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { 511a27d9013SAlfredo Cardigliano struct ionic_qcq *rxq = 512a27d9013SAlfredo Cardigliano eth_dev->data->rx_queues[i]; 513a27d9013SAlfredo Cardigliano rxq->offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP; 514a27d9013SAlfredo Cardigliano } 515a27d9013SAlfredo Cardigliano lif->features &= ~IONIC_ETH_HW_VLAN_RX_STRIP; 516a27d9013SAlfredo Cardigliano } 517a27d9013SAlfredo Cardigliano } 518a27d9013SAlfredo Cardigliano 519a27d9013SAlfredo Cardigliano if (mask & ETH_VLAN_FILTER_MASK) { 520a27d9013SAlfredo Cardigliano if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) 521a27d9013SAlfredo Cardigliano lif->features |= IONIC_ETH_HW_VLAN_RX_FILTER; 522a27d9013SAlfredo Cardigliano else 523a27d9013SAlfredo Cardigliano lif->features &= ~IONIC_ETH_HW_VLAN_RX_FILTER; 524a27d9013SAlfredo Cardigliano } 525a27d9013SAlfredo Cardigliano 526a27d9013SAlfredo Cardigliano ionic_lif_set_features(lif); 527a27d9013SAlfredo Cardigliano 528a27d9013SAlfredo Cardigliano return 0; 529a27d9013SAlfredo Cardigliano } 530a27d9013SAlfredo Cardigliano 531a27d9013SAlfredo Cardigliano static int 53222e7171bSAlfredo Cardigliano ionic_dev_rss_reta_update(struct rte_eth_dev *eth_dev, 53322e7171bSAlfredo Cardigliano struct rte_eth_rss_reta_entry64 *reta_conf, 53422e7171bSAlfredo Cardigliano uint16_t reta_size) 53522e7171bSAlfredo Cardigliano { 53622e7171bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 53722e7171bSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 53822e7171bSAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 53922e7171bSAlfredo Cardigliano uint32_t i, j, index, num; 54022e7171bSAlfredo Cardigliano 54122e7171bSAlfredo Cardigliano IONIC_PRINT_CALL(); 54222e7171bSAlfredo Cardigliano 54322e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl) { 54422e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "RSS RETA not initialized, " 54522e7171bSAlfredo Cardigliano "can't update the table"); 54622e7171bSAlfredo Cardigliano return -EINVAL; 54722e7171bSAlfredo Cardigliano } 54822e7171bSAlfredo Cardigliano 54922e7171bSAlfredo Cardigliano if (reta_size != ident->lif.eth.rss_ind_tbl_sz) { 55022e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "The size of hash lookup table configured " 55122e7171bSAlfredo Cardigliano "(%d) doesn't match the number hardware can supported " 55222e7171bSAlfredo Cardigliano "(%d)", 55322e7171bSAlfredo Cardigliano reta_size, ident->lif.eth.rss_ind_tbl_sz); 55422e7171bSAlfredo Cardigliano return -EINVAL; 55522e7171bSAlfredo Cardigliano } 55622e7171bSAlfredo Cardigliano 55722e7171bSAlfredo Cardigliano num = lif->adapter->ident.lif.eth.rss_ind_tbl_sz / RTE_RETA_GROUP_SIZE; 55822e7171bSAlfredo Cardigliano 55922e7171bSAlfredo Cardigliano for (i = 0; i < num; i++) { 56022e7171bSAlfredo Cardigliano for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) { 56122e7171bSAlfredo Cardigliano if (reta_conf[i].mask & ((uint64_t)1 << j)) { 56222e7171bSAlfredo Cardigliano index = (i * RTE_RETA_GROUP_SIZE) + j; 56322e7171bSAlfredo Cardigliano lif->rss_ind_tbl[index] = reta_conf[i].reta[j]; 56422e7171bSAlfredo Cardigliano } 56522e7171bSAlfredo Cardigliano } 56622e7171bSAlfredo Cardigliano } 56722e7171bSAlfredo Cardigliano 56822e7171bSAlfredo Cardigliano return ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL); 56922e7171bSAlfredo Cardigliano } 57022e7171bSAlfredo Cardigliano 57122e7171bSAlfredo Cardigliano static int 57222e7171bSAlfredo Cardigliano ionic_dev_rss_reta_query(struct rte_eth_dev *eth_dev, 57322e7171bSAlfredo Cardigliano struct rte_eth_rss_reta_entry64 *reta_conf, 57422e7171bSAlfredo Cardigliano uint16_t reta_size) 57522e7171bSAlfredo Cardigliano { 57622e7171bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 57722e7171bSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 57822e7171bSAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 57922e7171bSAlfredo Cardigliano int i, num; 58022e7171bSAlfredo Cardigliano 58122e7171bSAlfredo Cardigliano IONIC_PRINT_CALL(); 58222e7171bSAlfredo Cardigliano 58322e7171bSAlfredo Cardigliano if (reta_size != ident->lif.eth.rss_ind_tbl_sz) { 58422e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "The size of hash lookup table configured " 58522e7171bSAlfredo Cardigliano "(%d) doesn't match the number hardware can supported " 58622e7171bSAlfredo Cardigliano "(%d)", 58722e7171bSAlfredo Cardigliano reta_size, ident->lif.eth.rss_ind_tbl_sz); 58822e7171bSAlfredo Cardigliano return -EINVAL; 58922e7171bSAlfredo Cardigliano } 59022e7171bSAlfredo Cardigliano 59122e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl) { 59222e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "RSS RETA has not been built yet"); 59322e7171bSAlfredo Cardigliano return -EINVAL; 59422e7171bSAlfredo Cardigliano } 59522e7171bSAlfredo Cardigliano 59622e7171bSAlfredo Cardigliano num = reta_size / RTE_RETA_GROUP_SIZE; 59722e7171bSAlfredo Cardigliano 59822e7171bSAlfredo Cardigliano for (i = 0; i < num; i++) { 59922e7171bSAlfredo Cardigliano memcpy(reta_conf->reta, 60022e7171bSAlfredo Cardigliano &lif->rss_ind_tbl[i * RTE_RETA_GROUP_SIZE], 60122e7171bSAlfredo Cardigliano RTE_RETA_GROUP_SIZE); 60222e7171bSAlfredo Cardigliano reta_conf++; 60322e7171bSAlfredo Cardigliano } 60422e7171bSAlfredo Cardigliano 60522e7171bSAlfredo Cardigliano return 0; 60622e7171bSAlfredo Cardigliano } 60722e7171bSAlfredo Cardigliano 60822e7171bSAlfredo Cardigliano static int 60922e7171bSAlfredo Cardigliano ionic_dev_rss_hash_conf_get(struct rte_eth_dev *eth_dev, 61022e7171bSAlfredo Cardigliano struct rte_eth_rss_conf *rss_conf) 61122e7171bSAlfredo Cardigliano { 61222e7171bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 61322e7171bSAlfredo Cardigliano uint64_t rss_hf = 0; 61422e7171bSAlfredo Cardigliano 61522e7171bSAlfredo Cardigliano IONIC_PRINT_CALL(); 61622e7171bSAlfredo Cardigliano 61722e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl) { 61822e7171bSAlfredo Cardigliano IONIC_PRINT(NOTICE, "RSS not enabled"); 61922e7171bSAlfredo Cardigliano return 0; 62022e7171bSAlfredo Cardigliano } 62122e7171bSAlfredo Cardigliano 62222e7171bSAlfredo Cardigliano /* Get key value (if not null, rss_key is 40-byte) */ 62322e7171bSAlfredo Cardigliano if (rss_conf->rss_key != NULL && 62422e7171bSAlfredo Cardigliano rss_conf->rss_key_len >= IONIC_RSS_HASH_KEY_SIZE) 62522e7171bSAlfredo Cardigliano memcpy(rss_conf->rss_key, lif->rss_hash_key, 62622e7171bSAlfredo Cardigliano IONIC_RSS_HASH_KEY_SIZE); 62722e7171bSAlfredo Cardigliano 62822e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV4) 62922e7171bSAlfredo Cardigliano rss_hf |= ETH_RSS_IPV4; 63022e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV4_TCP) 63122e7171bSAlfredo Cardigliano rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; 63222e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV4_UDP) 63322e7171bSAlfredo Cardigliano rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; 63422e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV6) 63522e7171bSAlfredo Cardigliano rss_hf |= ETH_RSS_IPV6; 63622e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV6_TCP) 63722e7171bSAlfredo Cardigliano rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP; 63822e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV6_UDP) 63922e7171bSAlfredo Cardigliano rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; 64022e7171bSAlfredo Cardigliano 64122e7171bSAlfredo Cardigliano rss_conf->rss_hf = rss_hf; 64222e7171bSAlfredo Cardigliano 64322e7171bSAlfredo Cardigliano return 0; 64422e7171bSAlfredo Cardigliano } 64522e7171bSAlfredo Cardigliano 64622e7171bSAlfredo Cardigliano static int 64722e7171bSAlfredo Cardigliano ionic_dev_rss_hash_update(struct rte_eth_dev *eth_dev, 64822e7171bSAlfredo Cardigliano struct rte_eth_rss_conf *rss_conf) 64922e7171bSAlfredo Cardigliano { 65022e7171bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 65122e7171bSAlfredo Cardigliano uint32_t rss_types = 0; 65222e7171bSAlfredo Cardigliano uint8_t *key = NULL; 65322e7171bSAlfredo Cardigliano 65422e7171bSAlfredo Cardigliano IONIC_PRINT_CALL(); 65522e7171bSAlfredo Cardigliano 65622e7171bSAlfredo Cardigliano if (rss_conf->rss_key) 65722e7171bSAlfredo Cardigliano key = rss_conf->rss_key; 65822e7171bSAlfredo Cardigliano 65922e7171bSAlfredo Cardigliano if ((rss_conf->rss_hf & IONIC_ETH_RSS_OFFLOAD_ALL) == 0) { 66022e7171bSAlfredo Cardigliano /* 66122e7171bSAlfredo Cardigliano * Can't disable rss through hash flags, 66222e7171bSAlfredo Cardigliano * if it is enabled by default during init 66322e7171bSAlfredo Cardigliano */ 66422e7171bSAlfredo Cardigliano if (lif->rss_ind_tbl) 66522e7171bSAlfredo Cardigliano return -EINVAL; 66622e7171bSAlfredo Cardigliano } else { 66722e7171bSAlfredo Cardigliano /* Can't enable rss if disabled by default during init */ 66822e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl) 66922e7171bSAlfredo Cardigliano return -EINVAL; 67022e7171bSAlfredo Cardigliano 67122e7171bSAlfredo Cardigliano if (rss_conf->rss_hf & ETH_RSS_IPV4) 67222e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV4; 67322e7171bSAlfredo Cardigliano if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) 67422e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV4_TCP; 67522e7171bSAlfredo Cardigliano if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) 67622e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV4_UDP; 67722e7171bSAlfredo Cardigliano if (rss_conf->rss_hf & ETH_RSS_IPV6) 67822e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV6; 67922e7171bSAlfredo Cardigliano if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) 68022e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV6_TCP; 68122e7171bSAlfredo Cardigliano if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) 68222e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV6_UDP; 68322e7171bSAlfredo Cardigliano 68422e7171bSAlfredo Cardigliano ionic_lif_rss_config(lif, rss_types, key, NULL); 68522e7171bSAlfredo Cardigliano } 68622e7171bSAlfredo Cardigliano 68722e7171bSAlfredo Cardigliano return 0; 68822e7171bSAlfredo Cardigliano } 68922e7171bSAlfredo Cardigliano 69022e7171bSAlfredo Cardigliano static int 691*3cdfd905SAlfredo Cardigliano ionic_dev_stats_get(struct rte_eth_dev *eth_dev, 692*3cdfd905SAlfredo Cardigliano struct rte_eth_stats *stats) 693*3cdfd905SAlfredo Cardigliano { 694*3cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 695*3cdfd905SAlfredo Cardigliano 696*3cdfd905SAlfredo Cardigliano ionic_lif_get_stats(lif, stats); 697*3cdfd905SAlfredo Cardigliano 698*3cdfd905SAlfredo Cardigliano return 0; 699*3cdfd905SAlfredo Cardigliano } 700*3cdfd905SAlfredo Cardigliano 701*3cdfd905SAlfredo Cardigliano static int 702*3cdfd905SAlfredo Cardigliano ionic_dev_stats_reset(struct rte_eth_dev *eth_dev) 703*3cdfd905SAlfredo Cardigliano { 704*3cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 705*3cdfd905SAlfredo Cardigliano 706*3cdfd905SAlfredo Cardigliano IONIC_PRINT_CALL(); 707*3cdfd905SAlfredo Cardigliano 708*3cdfd905SAlfredo Cardigliano ionic_lif_reset_stats(lif); 709*3cdfd905SAlfredo Cardigliano 710*3cdfd905SAlfredo Cardigliano return 0; 711*3cdfd905SAlfredo Cardigliano } 712*3cdfd905SAlfredo Cardigliano 713*3cdfd905SAlfredo Cardigliano static int 714*3cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_names(__rte_unused struct rte_eth_dev *eth_dev, 715*3cdfd905SAlfredo Cardigliano struct rte_eth_xstat_name *xstats_names, 716*3cdfd905SAlfredo Cardigliano __rte_unused unsigned int size) 717*3cdfd905SAlfredo Cardigliano { 718*3cdfd905SAlfredo Cardigliano unsigned int i; 719*3cdfd905SAlfredo Cardigliano 720*3cdfd905SAlfredo Cardigliano if (xstats_names != NULL) { 721*3cdfd905SAlfredo Cardigliano for (i = 0; i < IONIC_NB_HW_STATS; i++) { 722*3cdfd905SAlfredo Cardigliano snprintf(xstats_names[i].name, 723*3cdfd905SAlfredo Cardigliano sizeof(xstats_names[i].name), 724*3cdfd905SAlfredo Cardigliano "%s", rte_ionic_xstats_strings[i].name); 725*3cdfd905SAlfredo Cardigliano } 726*3cdfd905SAlfredo Cardigliano } 727*3cdfd905SAlfredo Cardigliano 728*3cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 729*3cdfd905SAlfredo Cardigliano } 730*3cdfd905SAlfredo Cardigliano 731*3cdfd905SAlfredo Cardigliano static int 732*3cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_names_by_id(struct rte_eth_dev *eth_dev, 733*3cdfd905SAlfredo Cardigliano struct rte_eth_xstat_name *xstats_names, const uint64_t *ids, 734*3cdfd905SAlfredo Cardigliano unsigned int limit) 735*3cdfd905SAlfredo Cardigliano { 736*3cdfd905SAlfredo Cardigliano struct rte_eth_xstat_name xstats_names_copy[IONIC_NB_HW_STATS]; 737*3cdfd905SAlfredo Cardigliano uint16_t i; 738*3cdfd905SAlfredo Cardigliano 739*3cdfd905SAlfredo Cardigliano if (!ids) { 740*3cdfd905SAlfredo Cardigliano if (xstats_names != NULL) { 741*3cdfd905SAlfredo Cardigliano for (i = 0; i < IONIC_NB_HW_STATS; i++) { 742*3cdfd905SAlfredo Cardigliano snprintf(xstats_names[i].name, 743*3cdfd905SAlfredo Cardigliano sizeof(xstats_names[i].name), 744*3cdfd905SAlfredo Cardigliano "%s", rte_ionic_xstats_strings[i].name); 745*3cdfd905SAlfredo Cardigliano } 746*3cdfd905SAlfredo Cardigliano } 747*3cdfd905SAlfredo Cardigliano 748*3cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 749*3cdfd905SAlfredo Cardigliano } 750*3cdfd905SAlfredo Cardigliano 751*3cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_names_by_id(eth_dev, xstats_names_copy, NULL, 752*3cdfd905SAlfredo Cardigliano IONIC_NB_HW_STATS); 753*3cdfd905SAlfredo Cardigliano 754*3cdfd905SAlfredo Cardigliano for (i = 0; i < limit; i++) { 755*3cdfd905SAlfredo Cardigliano if (ids[i] >= IONIC_NB_HW_STATS) { 756*3cdfd905SAlfredo Cardigliano IONIC_PRINT(ERR, "id value isn't valid"); 757*3cdfd905SAlfredo Cardigliano return -1; 758*3cdfd905SAlfredo Cardigliano } 759*3cdfd905SAlfredo Cardigliano 760*3cdfd905SAlfredo Cardigliano strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name); 761*3cdfd905SAlfredo Cardigliano } 762*3cdfd905SAlfredo Cardigliano 763*3cdfd905SAlfredo Cardigliano return limit; 764*3cdfd905SAlfredo Cardigliano } 765*3cdfd905SAlfredo Cardigliano 766*3cdfd905SAlfredo Cardigliano static int 767*3cdfd905SAlfredo Cardigliano ionic_dev_xstats_get(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats, 768*3cdfd905SAlfredo Cardigliano unsigned int n) 769*3cdfd905SAlfredo Cardigliano { 770*3cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 771*3cdfd905SAlfredo Cardigliano struct ionic_lif_stats hw_stats; 772*3cdfd905SAlfredo Cardigliano uint16_t i; 773*3cdfd905SAlfredo Cardigliano 774*3cdfd905SAlfredo Cardigliano if (n < IONIC_NB_HW_STATS) 775*3cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 776*3cdfd905SAlfredo Cardigliano 777*3cdfd905SAlfredo Cardigliano ionic_lif_get_hw_stats(lif, &hw_stats); 778*3cdfd905SAlfredo Cardigliano 779*3cdfd905SAlfredo Cardigliano for (i = 0; i < IONIC_NB_HW_STATS; i++) { 780*3cdfd905SAlfredo Cardigliano xstats[i].value = *(uint64_t *)(((char *)&hw_stats) + 781*3cdfd905SAlfredo Cardigliano rte_ionic_xstats_strings[i].offset); 782*3cdfd905SAlfredo Cardigliano xstats[i].id = i; 783*3cdfd905SAlfredo Cardigliano } 784*3cdfd905SAlfredo Cardigliano 785*3cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 786*3cdfd905SAlfredo Cardigliano } 787*3cdfd905SAlfredo Cardigliano 788*3cdfd905SAlfredo Cardigliano static int 789*3cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_by_id(struct rte_eth_dev *eth_dev, const uint64_t *ids, 790*3cdfd905SAlfredo Cardigliano uint64_t *values, unsigned int n) 791*3cdfd905SAlfredo Cardigliano { 792*3cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 793*3cdfd905SAlfredo Cardigliano struct ionic_lif_stats hw_stats; 794*3cdfd905SAlfredo Cardigliano uint64_t values_copy[IONIC_NB_HW_STATS]; 795*3cdfd905SAlfredo Cardigliano uint16_t i; 796*3cdfd905SAlfredo Cardigliano 797*3cdfd905SAlfredo Cardigliano if (!ids) { 798*3cdfd905SAlfredo Cardigliano if (!ids && n < IONIC_NB_HW_STATS) 799*3cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 800*3cdfd905SAlfredo Cardigliano 801*3cdfd905SAlfredo Cardigliano ionic_lif_get_hw_stats(lif, &hw_stats); 802*3cdfd905SAlfredo Cardigliano 803*3cdfd905SAlfredo Cardigliano for (i = 0; i < IONIC_NB_HW_STATS; i++) { 804*3cdfd905SAlfredo Cardigliano values[i] = *(uint64_t *)(((char *)&hw_stats) + 805*3cdfd905SAlfredo Cardigliano rte_ionic_xstats_strings[i].offset); 806*3cdfd905SAlfredo Cardigliano } 807*3cdfd905SAlfredo Cardigliano 808*3cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 809*3cdfd905SAlfredo Cardigliano } 810*3cdfd905SAlfredo Cardigliano 811*3cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_by_id(eth_dev, NULL, values_copy, 812*3cdfd905SAlfredo Cardigliano IONIC_NB_HW_STATS); 813*3cdfd905SAlfredo Cardigliano 814*3cdfd905SAlfredo Cardigliano for (i = 0; i < n; i++) { 815*3cdfd905SAlfredo Cardigliano if (ids[i] >= IONIC_NB_HW_STATS) { 816*3cdfd905SAlfredo Cardigliano IONIC_PRINT(ERR, "id value isn't valid"); 817*3cdfd905SAlfredo Cardigliano return -1; 818*3cdfd905SAlfredo Cardigliano } 819*3cdfd905SAlfredo Cardigliano 820*3cdfd905SAlfredo Cardigliano values[i] = values_copy[ids[i]]; 821*3cdfd905SAlfredo Cardigliano } 822*3cdfd905SAlfredo Cardigliano 823*3cdfd905SAlfredo Cardigliano return n; 824*3cdfd905SAlfredo Cardigliano } 825*3cdfd905SAlfredo Cardigliano 826*3cdfd905SAlfredo Cardigliano static int 827*3cdfd905SAlfredo Cardigliano ionic_dev_xstats_reset(struct rte_eth_dev *eth_dev) 828*3cdfd905SAlfredo Cardigliano { 829*3cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 830*3cdfd905SAlfredo Cardigliano 831*3cdfd905SAlfredo Cardigliano ionic_lif_reset_hw_stats(lif); 832*3cdfd905SAlfredo Cardigliano 833*3cdfd905SAlfredo Cardigliano return 0; 834*3cdfd905SAlfredo Cardigliano } 835*3cdfd905SAlfredo Cardigliano 836*3cdfd905SAlfredo Cardigliano static int 837598f6726SAlfredo Cardigliano ionic_dev_configure(struct rte_eth_dev *eth_dev) 838598f6726SAlfredo Cardigliano { 839598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 840598f6726SAlfredo Cardigliano int err; 841598f6726SAlfredo Cardigliano 842598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 843598f6726SAlfredo Cardigliano 844598f6726SAlfredo Cardigliano err = ionic_lif_configure(lif); 845598f6726SAlfredo Cardigliano if (err) { 846598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot configure LIF: %d", err); 847598f6726SAlfredo Cardigliano return err; 848598f6726SAlfredo Cardigliano } 849598f6726SAlfredo Cardigliano 850598f6726SAlfredo Cardigliano return 0; 851598f6726SAlfredo Cardigliano } 852598f6726SAlfredo Cardigliano 853598f6726SAlfredo Cardigliano static inline uint32_t 854598f6726SAlfredo Cardigliano ionic_parse_link_speeds(uint16_t link_speeds) 855598f6726SAlfredo Cardigliano { 856598f6726SAlfredo Cardigliano if (link_speeds & ETH_LINK_SPEED_100G) 857598f6726SAlfredo Cardigliano return 100000; 858598f6726SAlfredo Cardigliano else if (link_speeds & ETH_LINK_SPEED_50G) 859598f6726SAlfredo Cardigliano return 50000; 860598f6726SAlfredo Cardigliano else if (link_speeds & ETH_LINK_SPEED_40G) 861598f6726SAlfredo Cardigliano return 40000; 862598f6726SAlfredo Cardigliano else if (link_speeds & ETH_LINK_SPEED_25G) 863598f6726SAlfredo Cardigliano return 25000; 864598f6726SAlfredo Cardigliano else if (link_speeds & ETH_LINK_SPEED_10G) 865598f6726SAlfredo Cardigliano return 10000; 866598f6726SAlfredo Cardigliano else 867598f6726SAlfredo Cardigliano return 0; 868598f6726SAlfredo Cardigliano } 869598f6726SAlfredo Cardigliano 870598f6726SAlfredo Cardigliano /* 871598f6726SAlfredo Cardigliano * Configure device link speed and setup link. 872598f6726SAlfredo Cardigliano * It returns 0 on success. 873598f6726SAlfredo Cardigliano */ 874598f6726SAlfredo Cardigliano static int 875598f6726SAlfredo Cardigliano ionic_dev_start(struct rte_eth_dev *eth_dev) 876598f6726SAlfredo Cardigliano { 877598f6726SAlfredo Cardigliano struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf; 878598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 879598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 880598f6726SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 881598f6726SAlfredo Cardigliano uint32_t allowed_speeds; 882598f6726SAlfredo Cardigliano int err; 883598f6726SAlfredo Cardigliano 884598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 885598f6726SAlfredo Cardigliano 886598f6726SAlfredo Cardigliano allowed_speeds = 887598f6726SAlfredo Cardigliano ETH_LINK_SPEED_FIXED | 888598f6726SAlfredo Cardigliano ETH_LINK_SPEED_10G | 889598f6726SAlfredo Cardigliano ETH_LINK_SPEED_25G | 890598f6726SAlfredo Cardigliano ETH_LINK_SPEED_40G | 891598f6726SAlfredo Cardigliano ETH_LINK_SPEED_50G | 892598f6726SAlfredo Cardigliano ETH_LINK_SPEED_100G; 893598f6726SAlfredo Cardigliano 894598f6726SAlfredo Cardigliano if (dev_conf->link_speeds & ~allowed_speeds) { 895598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Invalid link setting"); 896598f6726SAlfredo Cardigliano return -EINVAL; 897598f6726SAlfredo Cardigliano } 898598f6726SAlfredo Cardigliano 899598f6726SAlfredo Cardigliano err = ionic_lif_start(lif); 900598f6726SAlfredo Cardigliano if (err) { 901598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot start LIF: %d", err); 902598f6726SAlfredo Cardigliano return err; 903598f6726SAlfredo Cardigliano } 904598f6726SAlfredo Cardigliano 905598f6726SAlfredo Cardigliano if (eth_dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) { 906598f6726SAlfredo Cardigliano uint32_t speed = ionic_parse_link_speeds(dev_conf->link_speeds); 907598f6726SAlfredo Cardigliano 908598f6726SAlfredo Cardigliano if (speed) 909598f6726SAlfredo Cardigliano ionic_dev_cmd_port_speed(idev, speed); 910598f6726SAlfredo Cardigliano } 911598f6726SAlfredo Cardigliano 912598f6726SAlfredo Cardigliano ionic_dev_link_update(eth_dev, 0); 913598f6726SAlfredo Cardigliano 914598f6726SAlfredo Cardigliano return 0; 915598f6726SAlfredo Cardigliano } 916598f6726SAlfredo Cardigliano 917598f6726SAlfredo Cardigliano /* 918598f6726SAlfredo Cardigliano * Stop device: disable rx and tx functions to allow for reconfiguring. 919598f6726SAlfredo Cardigliano */ 920598f6726SAlfredo Cardigliano static void 921598f6726SAlfredo Cardigliano ionic_dev_stop(struct rte_eth_dev *eth_dev) 922598f6726SAlfredo Cardigliano { 923598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 924598f6726SAlfredo Cardigliano int err; 925598f6726SAlfredo Cardigliano 926598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 927598f6726SAlfredo Cardigliano 928598f6726SAlfredo Cardigliano err = ionic_lif_stop(lif); 929598f6726SAlfredo Cardigliano if (err) 930598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot stop LIF: %d", err); 931598f6726SAlfredo Cardigliano } 932598f6726SAlfredo Cardigliano 933598f6726SAlfredo Cardigliano /* 934598f6726SAlfredo Cardigliano * Reset and stop device. 935598f6726SAlfredo Cardigliano */ 936598f6726SAlfredo Cardigliano static void 937598f6726SAlfredo Cardigliano ionic_dev_close(struct rte_eth_dev *eth_dev) 938598f6726SAlfredo Cardigliano { 939598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 940598f6726SAlfredo Cardigliano int err; 941598f6726SAlfredo Cardigliano 942598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 943598f6726SAlfredo Cardigliano 944598f6726SAlfredo Cardigliano err = ionic_lif_stop(lif); 945598f6726SAlfredo Cardigliano if (err) { 946598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot stop LIF: %d", err); 947598f6726SAlfredo Cardigliano return; 948598f6726SAlfredo Cardigliano } 949598f6726SAlfredo Cardigliano 950598f6726SAlfredo Cardigliano err = eth_ionic_dev_uninit(eth_dev); 951598f6726SAlfredo Cardigliano if (err) { 952598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot destroy LIF: %d", err); 953598f6726SAlfredo Cardigliano return; 954598f6726SAlfredo Cardigliano } 955598f6726SAlfredo Cardigliano } 956598f6726SAlfredo Cardigliano 957598f6726SAlfredo Cardigliano static int 958669c8de6SAlfredo Cardigliano eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params) 959669c8de6SAlfredo Cardigliano { 960669c8de6SAlfredo Cardigliano struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 961669c8de6SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 962669c8de6SAlfredo Cardigliano struct ionic_adapter *adapter = (struct ionic_adapter *)init_params; 963669c8de6SAlfredo Cardigliano int err; 964669c8de6SAlfredo Cardigliano 965669c8de6SAlfredo Cardigliano IONIC_PRINT_CALL(); 966669c8de6SAlfredo Cardigliano 967669c8de6SAlfredo Cardigliano eth_dev->dev_ops = &ionic_eth_dev_ops; 968a27d9013SAlfredo Cardigliano eth_dev->rx_pkt_burst = &ionic_recv_pkts; 969a27d9013SAlfredo Cardigliano eth_dev->tx_pkt_burst = &ionic_xmit_pkts; 970a27d9013SAlfredo Cardigliano eth_dev->tx_pkt_prepare = &ionic_prep_pkts; 971669c8de6SAlfredo Cardigliano 972669c8de6SAlfredo Cardigliano /* Multi-process not supported, primary does initialization anyway */ 973669c8de6SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) 974669c8de6SAlfredo Cardigliano return 0; 975669c8de6SAlfredo Cardigliano 976669c8de6SAlfredo Cardigliano rte_eth_copy_pci_info(eth_dev, pci_dev); 977669c8de6SAlfredo Cardigliano 978669c8de6SAlfredo Cardigliano lif->index = adapter->nlifs; 979669c8de6SAlfredo Cardigliano lif->eth_dev = eth_dev; 980669c8de6SAlfredo Cardigliano lif->adapter = adapter; 981669c8de6SAlfredo Cardigliano adapter->lifs[adapter->nlifs] = lif; 982669c8de6SAlfredo Cardigliano 983598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Up to %u MAC addresses supported", 984598f6726SAlfredo Cardigliano adapter->max_mac_addrs); 985598f6726SAlfredo Cardigliano 986598f6726SAlfredo Cardigliano /* Allocate memory for storing MAC addresses */ 987598f6726SAlfredo Cardigliano eth_dev->data->mac_addrs = rte_zmalloc("ionic", 988598f6726SAlfredo Cardigliano RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs, 0); 989598f6726SAlfredo Cardigliano 990598f6726SAlfredo Cardigliano if (eth_dev->data->mac_addrs == NULL) { 991598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Failed to allocate %u bytes needed to " 992598f6726SAlfredo Cardigliano "store MAC addresses", 993598f6726SAlfredo Cardigliano RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs); 994598f6726SAlfredo Cardigliano err = -ENOMEM; 995598f6726SAlfredo Cardigliano goto err; 996598f6726SAlfredo Cardigliano } 997598f6726SAlfredo Cardigliano 998669c8de6SAlfredo Cardigliano err = ionic_lif_alloc(lif); 999669c8de6SAlfredo Cardigliano if (err) { 1000669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate LIFs: %d, aborting", 1001669c8de6SAlfredo Cardigliano err); 1002669c8de6SAlfredo Cardigliano goto err; 1003669c8de6SAlfredo Cardigliano } 1004669c8de6SAlfredo Cardigliano 1005669c8de6SAlfredo Cardigliano err = ionic_lif_init(lif); 1006669c8de6SAlfredo Cardigliano if (err) { 1007669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init LIFs: %d, aborting", err); 1008669c8de6SAlfredo Cardigliano goto err_free_lif; 1009669c8de6SAlfredo Cardigliano } 1010669c8de6SAlfredo Cardigliano 1011598f6726SAlfredo Cardigliano /* Copy the MAC address */ 1012598f6726SAlfredo Cardigliano rte_ether_addr_copy((struct rte_ether_addr *)lif->mac_addr, 1013598f6726SAlfredo Cardigliano ð_dev->data->mac_addrs[0]); 1014598f6726SAlfredo Cardigliano 1015669c8de6SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Port %u initialized", eth_dev->data->port_id); 1016669c8de6SAlfredo Cardigliano 1017669c8de6SAlfredo Cardigliano return 0; 1018669c8de6SAlfredo Cardigliano 1019669c8de6SAlfredo Cardigliano err_free_lif: 1020669c8de6SAlfredo Cardigliano ionic_lif_free(lif); 1021669c8de6SAlfredo Cardigliano err: 1022669c8de6SAlfredo Cardigliano return err; 1023669c8de6SAlfredo Cardigliano } 1024669c8de6SAlfredo Cardigliano 1025669c8de6SAlfredo Cardigliano static int 1026669c8de6SAlfredo Cardigliano eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev) 1027669c8de6SAlfredo Cardigliano { 1028669c8de6SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 1029669c8de6SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 1030669c8de6SAlfredo Cardigliano 1031669c8de6SAlfredo Cardigliano IONIC_PRINT_CALL(); 1032669c8de6SAlfredo Cardigliano 1033669c8de6SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1034669c8de6SAlfredo Cardigliano return 0; 1035669c8de6SAlfredo Cardigliano 1036669c8de6SAlfredo Cardigliano adapter->lifs[lif->index] = NULL; 1037669c8de6SAlfredo Cardigliano 1038669c8de6SAlfredo Cardigliano ionic_lif_deinit(lif); 1039669c8de6SAlfredo Cardigliano ionic_lif_free(lif); 1040669c8de6SAlfredo Cardigliano 1041669c8de6SAlfredo Cardigliano eth_dev->dev_ops = NULL; 1042a27d9013SAlfredo Cardigliano eth_dev->rx_pkt_burst = NULL; 1043a27d9013SAlfredo Cardigliano eth_dev->tx_pkt_burst = NULL; 1044a27d9013SAlfredo Cardigliano eth_dev->tx_pkt_prepare = NULL; 1045669c8de6SAlfredo Cardigliano 1046669c8de6SAlfredo Cardigliano return 0; 1047669c8de6SAlfredo Cardigliano } 1048669c8de6SAlfredo Cardigliano 10495ef51809SAlfredo Cardigliano static int 105027b942c8SAlfredo Cardigliano ionic_configure_intr(struct ionic_adapter *adapter) 105127b942c8SAlfredo Cardigliano { 105227b942c8SAlfredo Cardigliano struct rte_pci_device *pci_dev = adapter->pci_dev; 105327b942c8SAlfredo Cardigliano struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 105427b942c8SAlfredo Cardigliano int err; 105527b942c8SAlfredo Cardigliano 105627b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Configuring %u intrs", adapter->nintrs); 105727b942c8SAlfredo Cardigliano 105827b942c8SAlfredo Cardigliano if (rte_intr_efd_enable(intr_handle, adapter->nintrs)) { 105927b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Fail to create eventfd"); 106027b942c8SAlfredo Cardigliano return -1; 106127b942c8SAlfredo Cardigliano } 106227b942c8SAlfredo Cardigliano 106327b942c8SAlfredo Cardigliano if (rte_intr_dp_is_en(intr_handle)) 106427b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, 106527b942c8SAlfredo Cardigliano "Packet I/O interrupt on datapath is enabled"); 106627b942c8SAlfredo Cardigliano 106727b942c8SAlfredo Cardigliano if (!intr_handle->intr_vec) { 106827b942c8SAlfredo Cardigliano intr_handle->intr_vec = rte_zmalloc("intr_vec", 106927b942c8SAlfredo Cardigliano adapter->nintrs * sizeof(int), 0); 107027b942c8SAlfredo Cardigliano 107127b942c8SAlfredo Cardigliano if (!intr_handle->intr_vec) { 107227b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Failed to allocate %u vectors", 107327b942c8SAlfredo Cardigliano adapter->nintrs); 107427b942c8SAlfredo Cardigliano return -ENOMEM; 107527b942c8SAlfredo Cardigliano } 107627b942c8SAlfredo Cardigliano } 107727b942c8SAlfredo Cardigliano 107827b942c8SAlfredo Cardigliano err = rte_intr_callback_register(intr_handle, 107927b942c8SAlfredo Cardigliano ionic_dev_interrupt_handler, 108027b942c8SAlfredo Cardigliano adapter); 108127b942c8SAlfredo Cardigliano 108227b942c8SAlfredo Cardigliano if (err) { 108327b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, 108427b942c8SAlfredo Cardigliano "Failure registering interrupts handler (%d)", 108527b942c8SAlfredo Cardigliano err); 108627b942c8SAlfredo Cardigliano return err; 108727b942c8SAlfredo Cardigliano } 108827b942c8SAlfredo Cardigliano 108927b942c8SAlfredo Cardigliano /* enable intr mapping */ 109027b942c8SAlfredo Cardigliano err = rte_intr_enable(intr_handle); 109127b942c8SAlfredo Cardigliano 109227b942c8SAlfredo Cardigliano if (err) { 109327b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Failure enabling interrupts (%d)", err); 109427b942c8SAlfredo Cardigliano return err; 109527b942c8SAlfredo Cardigliano } 109627b942c8SAlfredo Cardigliano 109727b942c8SAlfredo Cardigliano return 0; 109827b942c8SAlfredo Cardigliano } 109927b942c8SAlfredo Cardigliano 110027b942c8SAlfredo Cardigliano static void 110127b942c8SAlfredo Cardigliano ionic_unconfigure_intr(struct ionic_adapter *adapter) 110227b942c8SAlfredo Cardigliano { 110327b942c8SAlfredo Cardigliano struct rte_pci_device *pci_dev = adapter->pci_dev; 110427b942c8SAlfredo Cardigliano struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 110527b942c8SAlfredo Cardigliano 110627b942c8SAlfredo Cardigliano rte_intr_disable(intr_handle); 110727b942c8SAlfredo Cardigliano 110827b942c8SAlfredo Cardigliano rte_intr_callback_unregister(intr_handle, 110927b942c8SAlfredo Cardigliano ionic_dev_interrupt_handler, 111027b942c8SAlfredo Cardigliano adapter); 111127b942c8SAlfredo Cardigliano } 111227b942c8SAlfredo Cardigliano 111327b942c8SAlfredo Cardigliano static int 11145ef51809SAlfredo Cardigliano eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 11155ef51809SAlfredo Cardigliano struct rte_pci_device *pci_dev) 11165ef51809SAlfredo Cardigliano { 1117669c8de6SAlfredo Cardigliano char name[RTE_ETH_NAME_MAX_LEN]; 11185ef51809SAlfredo Cardigliano struct rte_mem_resource *resource; 11195ef51809SAlfredo Cardigliano struct ionic_adapter *adapter; 11205ef51809SAlfredo Cardigliano struct ionic_hw *hw; 11215ef51809SAlfredo Cardigliano unsigned long i; 11225ef51809SAlfredo Cardigliano int err; 11235ef51809SAlfredo Cardigliano 11245ef51809SAlfredo Cardigliano /* Check structs (trigger error at compilation time) */ 11255ef51809SAlfredo Cardigliano ionic_struct_size_checks(); 11265ef51809SAlfredo Cardigliano 11275ef51809SAlfredo Cardigliano /* Multi-process not supported */ 11285ef51809SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 11295ef51809SAlfredo Cardigliano err = -EPERM; 11305ef51809SAlfredo Cardigliano goto err; 11315ef51809SAlfredo Cardigliano } 11325ef51809SAlfredo Cardigliano 11335ef51809SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Initializing device %s", 11345ef51809SAlfredo Cardigliano pci_dev->device.name); 11355ef51809SAlfredo Cardigliano 11365ef51809SAlfredo Cardigliano adapter = rte_zmalloc("ionic", sizeof(*adapter), 0); 11375ef51809SAlfredo Cardigliano if (!adapter) { 11385ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "OOM"); 11395ef51809SAlfredo Cardigliano err = -ENOMEM; 11405ef51809SAlfredo Cardigliano goto err; 11415ef51809SAlfredo Cardigliano } 11425ef51809SAlfredo Cardigliano 11435ef51809SAlfredo Cardigliano adapter->pci_dev = pci_dev; 11445ef51809SAlfredo Cardigliano hw = &adapter->hw; 11455ef51809SAlfredo Cardigliano 11465ef51809SAlfredo Cardigliano hw->device_id = pci_dev->id.device_id; 11475ef51809SAlfredo Cardigliano hw->vendor_id = pci_dev->id.vendor_id; 11485ef51809SAlfredo Cardigliano 11495ef51809SAlfredo Cardigliano err = ionic_init_mac(hw); 11505ef51809SAlfredo Cardigliano if (err != 0) { 11515ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Mac init failed: %d", err); 11525ef51809SAlfredo Cardigliano err = -EIO; 11535ef51809SAlfredo Cardigliano goto err_free_adapter; 11545ef51809SAlfredo Cardigliano } 11555ef51809SAlfredo Cardigliano 11565ef51809SAlfredo Cardigliano adapter->is_mgmt_nic = (pci_dev->id.device_id == IONIC_DEV_ID_ETH_MGMT); 11575ef51809SAlfredo Cardigliano 11585ef51809SAlfredo Cardigliano adapter->num_bars = 0; 11595ef51809SAlfredo Cardigliano for (i = 0; i < PCI_MAX_RESOURCE && i < IONIC_BARS_MAX; i++) { 11605ef51809SAlfredo Cardigliano resource = &pci_dev->mem_resource[i]; 11615ef51809SAlfredo Cardigliano if (resource->phys_addr == 0 || resource->len == 0) 11625ef51809SAlfredo Cardigliano continue; 11635ef51809SAlfredo Cardigliano adapter->bars[adapter->num_bars].vaddr = resource->addr; 11645ef51809SAlfredo Cardigliano adapter->bars[adapter->num_bars].bus_addr = resource->phys_addr; 11655ef51809SAlfredo Cardigliano adapter->bars[adapter->num_bars].len = resource->len; 11665ef51809SAlfredo Cardigliano adapter->num_bars++; 11675ef51809SAlfredo Cardigliano } 11685ef51809SAlfredo Cardigliano 11695ef51809SAlfredo Cardigliano /* Discover ionic dev resources */ 11705ef51809SAlfredo Cardigliano 11715ef51809SAlfredo Cardigliano err = ionic_setup(adapter); 11725ef51809SAlfredo Cardigliano if (err) { 11735ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot setup device: %d, aborting", err); 11745ef51809SAlfredo Cardigliano goto err_free_adapter; 11755ef51809SAlfredo Cardigliano } 11765ef51809SAlfredo Cardigliano 11775ef51809SAlfredo Cardigliano err = ionic_identify(adapter); 11785ef51809SAlfredo Cardigliano if (err) { 11795ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify device: %d, aborting", 11805ef51809SAlfredo Cardigliano err); 11815ef51809SAlfredo Cardigliano goto err_free_adapter; 11825ef51809SAlfredo Cardigliano } 11835ef51809SAlfredo Cardigliano 11845ef51809SAlfredo Cardigliano err = ionic_init(adapter); 11855ef51809SAlfredo Cardigliano if (err) { 11865ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init device: %d, aborting", err); 11875ef51809SAlfredo Cardigliano goto err_free_adapter; 11885ef51809SAlfredo Cardigliano } 11895ef51809SAlfredo Cardigliano 119023bf4ddbSAlfredo Cardigliano /* Configure the ports */ 119123bf4ddbSAlfredo Cardigliano err = ionic_port_identify(adapter); 119223bf4ddbSAlfredo Cardigliano if (err) { 119323bf4ddbSAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify port: %d, aborting", 119423bf4ddbSAlfredo Cardigliano err); 119523bf4ddbSAlfredo Cardigliano goto err_free_adapter; 119623bf4ddbSAlfredo Cardigliano } 119723bf4ddbSAlfredo Cardigliano 119823bf4ddbSAlfredo Cardigliano err = ionic_port_init(adapter); 119923bf4ddbSAlfredo Cardigliano if (err) { 120023bf4ddbSAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init port: %d, aborting", err); 120123bf4ddbSAlfredo Cardigliano goto err_free_adapter; 120223bf4ddbSAlfredo Cardigliano } 120323bf4ddbSAlfredo Cardigliano 1204669c8de6SAlfredo Cardigliano /* Configure LIFs */ 1205669c8de6SAlfredo Cardigliano err = ionic_lif_identify(adapter); 1206669c8de6SAlfredo Cardigliano if (err) { 1207669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify lif: %d, aborting", err); 1208669c8de6SAlfredo Cardigliano goto err_free_adapter; 1209669c8de6SAlfredo Cardigliano } 1210669c8de6SAlfredo Cardigliano 1211669c8de6SAlfredo Cardigliano /* Allocate and init LIFs */ 1212669c8de6SAlfredo Cardigliano err = ionic_lifs_size(adapter); 1213669c8de6SAlfredo Cardigliano if (err) { 1214669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot size LIFs: %d, aborting", err); 1215669c8de6SAlfredo Cardigliano goto err_free_adapter; 1216669c8de6SAlfredo Cardigliano } 1217669c8de6SAlfredo Cardigliano 1218598f6726SAlfredo Cardigliano adapter->max_mac_addrs = adapter->ident.lif.eth.max_ucast_filters; 1219598f6726SAlfredo Cardigliano 1220669c8de6SAlfredo Cardigliano adapter->nlifs = 0; 1221669c8de6SAlfredo Cardigliano for (i = 0; i < adapter->ident.dev.nlifs; i++) { 1222669c8de6SAlfredo Cardigliano snprintf(name, sizeof(name), "net_%s_lif_%lu", 1223669c8de6SAlfredo Cardigliano pci_dev->device.name, i); 1224669c8de6SAlfredo Cardigliano 1225669c8de6SAlfredo Cardigliano err = rte_eth_dev_create(&pci_dev->device, name, 1226669c8de6SAlfredo Cardigliano sizeof(struct ionic_lif), 1227669c8de6SAlfredo Cardigliano NULL, NULL, 1228669c8de6SAlfredo Cardigliano eth_ionic_dev_init, adapter); 1229669c8de6SAlfredo Cardigliano if (err) { 1230669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot create eth device for " 1231669c8de6SAlfredo Cardigliano "ionic lif %s", name); 1232669c8de6SAlfredo Cardigliano break; 1233669c8de6SAlfredo Cardigliano } 1234669c8de6SAlfredo Cardigliano 1235669c8de6SAlfredo Cardigliano adapter->nlifs++; 1236669c8de6SAlfredo Cardigliano } 1237669c8de6SAlfredo Cardigliano 123827b942c8SAlfredo Cardigliano err = ionic_configure_intr(adapter); 123927b942c8SAlfredo Cardigliano 124027b942c8SAlfredo Cardigliano if (err) { 124127b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Failed to configure interrupts"); 124227b942c8SAlfredo Cardigliano goto err_free_adapter; 124327b942c8SAlfredo Cardigliano } 124427b942c8SAlfredo Cardigliano 12455ef51809SAlfredo Cardigliano return 0; 12465ef51809SAlfredo Cardigliano 12475ef51809SAlfredo Cardigliano err_free_adapter: 12485ef51809SAlfredo Cardigliano rte_free(adapter); 12495ef51809SAlfredo Cardigliano err: 12505ef51809SAlfredo Cardigliano return err; 12515ef51809SAlfredo Cardigliano } 12525ef51809SAlfredo Cardigliano 12535ef51809SAlfredo Cardigliano static int 12545ef51809SAlfredo Cardigliano eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused) 12555ef51809SAlfredo Cardigliano { 1256669c8de6SAlfredo Cardigliano char name[RTE_ETH_NAME_MAX_LEN]; 1257669c8de6SAlfredo Cardigliano struct ionic_adapter *adapter = NULL; 1258669c8de6SAlfredo Cardigliano struct rte_eth_dev *eth_dev; 1259669c8de6SAlfredo Cardigliano struct ionic_lif *lif; 1260669c8de6SAlfredo Cardigliano uint32_t i; 1261669c8de6SAlfredo Cardigliano 1262669c8de6SAlfredo Cardigliano /* Adapter lookup is using (the first) eth_dev name */ 1263669c8de6SAlfredo Cardigliano snprintf(name, sizeof(name), "net_%s_lif_0", 1264669c8de6SAlfredo Cardigliano pci_dev->device.name); 1265669c8de6SAlfredo Cardigliano 1266669c8de6SAlfredo Cardigliano eth_dev = rte_eth_dev_allocated(name); 1267669c8de6SAlfredo Cardigliano if (eth_dev) { 1268669c8de6SAlfredo Cardigliano lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 1269669c8de6SAlfredo Cardigliano adapter = lif->adapter; 1270669c8de6SAlfredo Cardigliano } 1271669c8de6SAlfredo Cardigliano 1272669c8de6SAlfredo Cardigliano if (adapter) { 127327b942c8SAlfredo Cardigliano ionic_unconfigure_intr(adapter); 127427b942c8SAlfredo Cardigliano 1275669c8de6SAlfredo Cardigliano for (i = 0; i < adapter->nlifs; i++) { 1276669c8de6SAlfredo Cardigliano lif = adapter->lifs[i]; 1277669c8de6SAlfredo Cardigliano rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit); 1278669c8de6SAlfredo Cardigliano } 1279669c8de6SAlfredo Cardigliano 1280669c8de6SAlfredo Cardigliano rte_free(adapter); 1281669c8de6SAlfredo Cardigliano } 1282669c8de6SAlfredo Cardigliano 12835ef51809SAlfredo Cardigliano return 0; 12845ef51809SAlfredo Cardigliano } 12855ef51809SAlfredo Cardigliano 12865ef51809SAlfredo Cardigliano static struct rte_pci_driver rte_ionic_pmd = { 12875ef51809SAlfredo Cardigliano .id_table = pci_id_ionic_map, 12885ef51809SAlfredo Cardigliano .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 12895ef51809SAlfredo Cardigliano .probe = eth_ionic_pci_probe, 12905ef51809SAlfredo Cardigliano .remove = eth_ionic_pci_remove, 12915ef51809SAlfredo Cardigliano }; 12925ef51809SAlfredo Cardigliano 12935ef51809SAlfredo Cardigliano RTE_PMD_REGISTER_PCI(net_ionic, rte_ionic_pmd); 12945ef51809SAlfredo Cardigliano RTE_PMD_REGISTER_PCI_TABLE(net_ionic, pci_id_ionic_map); 12955ef51809SAlfredo Cardigliano RTE_PMD_REGISTER_KMOD_DEP(net_ionic, "* igb_uio | uio_pci_generic | vfio-pci"); 12965ef51809SAlfredo Cardigliano 12977c125393SAlfredo Cardigliano RTE_INIT(ionic_init_log) 12987c125393SAlfredo Cardigliano { 12997c125393SAlfredo Cardigliano ionic_logtype = rte_log_register("pmd.net.ionic"); 13007c125393SAlfredo Cardigliano if (ionic_logtype >= 0) 13017c125393SAlfredo Cardigliano rte_log_set_level(ionic_logtype, RTE_LOG_NOTICE); 13027c125393SAlfredo Cardigliano } 1303