176668754SAndrew Boyer /* SPDX-License-Identifier: BSD-3-Clause 2a5205992SAndrew Boyer * Copyright 2018-2022 Advanced Micro Devices, Inc. 37c125393SAlfredo Cardigliano */ 47c125393SAlfredo Cardigliano 55ef51809SAlfredo Cardigliano #include <rte_ethdev.h> 6df96fd0dSBruce Richardson #include <ethdev_driver.h> 75ef51809SAlfredo Cardigliano #include <rte_malloc.h> 85ef51809SAlfredo Cardigliano 97c125393SAlfredo Cardigliano #include "ionic_logs.h" 105ef51809SAlfredo Cardigliano #include "ionic.h" 115ef51809SAlfredo Cardigliano #include "ionic_dev.h" 125ef51809SAlfredo Cardigliano #include "ionic_mac_api.h" 13669c8de6SAlfredo Cardigliano #include "ionic_lif.h" 14669c8de6SAlfredo Cardigliano #include "ionic_ethdev.h" 15a27d9013SAlfredo Cardigliano #include "ionic_rxtx.h" 16669c8de6SAlfredo Cardigliano 17669c8de6SAlfredo Cardigliano static int eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params); 18669c8de6SAlfredo Cardigliano static int eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev); 19598f6726SAlfredo Cardigliano static int ionic_dev_info_get(struct rte_eth_dev *eth_dev, 20598f6726SAlfredo Cardigliano struct rte_eth_dev_info *dev_info); 21598f6726SAlfredo Cardigliano static int ionic_dev_configure(struct rte_eth_dev *dev); 22598f6726SAlfredo Cardigliano static int ionic_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); 23598f6726SAlfredo Cardigliano static int ionic_dev_start(struct rte_eth_dev *dev); 2462024eb8SIvan Ilchenko static int ionic_dev_stop(struct rte_eth_dev *dev); 25b142387bSThomas Monjalon static int ionic_dev_close(struct rte_eth_dev *dev); 26598f6726SAlfredo Cardigliano static int ionic_dev_set_link_up(struct rte_eth_dev *dev); 27598f6726SAlfredo Cardigliano static int ionic_dev_set_link_down(struct rte_eth_dev *dev); 28ec15c66bSAlfredo Cardigliano static int ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev, 29ec15c66bSAlfredo Cardigliano struct rte_eth_fc_conf *fc_conf); 30ec15c66bSAlfredo Cardigliano static int ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev, 31ec15c66bSAlfredo Cardigliano struct rte_eth_fc_conf *fc_conf); 32a27d9013SAlfredo Cardigliano static int ionic_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask); 3322e7171bSAlfredo Cardigliano static int ionic_dev_rss_reta_update(struct rte_eth_dev *eth_dev, 3422e7171bSAlfredo Cardigliano struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); 3522e7171bSAlfredo Cardigliano static int ionic_dev_rss_reta_query(struct rte_eth_dev *eth_dev, 3622e7171bSAlfredo Cardigliano struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); 3722e7171bSAlfredo Cardigliano static int ionic_dev_rss_hash_conf_get(struct rte_eth_dev *eth_dev, 3822e7171bSAlfredo Cardigliano struct rte_eth_rss_conf *rss_conf); 3922e7171bSAlfredo Cardigliano static int ionic_dev_rss_hash_update(struct rte_eth_dev *eth_dev, 4022e7171bSAlfredo Cardigliano struct rte_eth_rss_conf *rss_conf); 413cdfd905SAlfredo Cardigliano static int ionic_dev_stats_get(struct rte_eth_dev *eth_dev, 423cdfd905SAlfredo Cardigliano struct rte_eth_stats *stats); 433cdfd905SAlfredo Cardigliano static int ionic_dev_stats_reset(struct rte_eth_dev *eth_dev); 443cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_get(struct rte_eth_dev *dev, 453cdfd905SAlfredo Cardigliano struct rte_eth_xstat *xstats, unsigned int n); 463cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_get_by_id(struct rte_eth_dev *dev, 473cdfd905SAlfredo Cardigliano const uint64_t *ids, uint64_t *values, unsigned int n); 483cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_reset(struct rte_eth_dev *dev); 493cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_get_names(struct rte_eth_dev *dev, 503cdfd905SAlfredo Cardigliano struct rte_eth_xstat_name *xstats_names, unsigned int size); 513cdfd905SAlfredo Cardigliano static int ionic_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, 528c9f976fSAndrew Rybchenko const uint64_t *ids, struct rte_eth_xstat_name *xstats_names, 533cdfd905SAlfredo Cardigliano unsigned int limit); 54eec10fb0SAlfredo Cardigliano static int ionic_dev_fw_version_get(struct rte_eth_dev *eth_dev, 55eec10fb0SAlfredo Cardigliano char *fw_version, size_t fw_size); 567c125393SAlfredo Cardigliano 57a27d9013SAlfredo Cardigliano static const struct rte_eth_desc_lim rx_desc_lim = { 58a27d9013SAlfredo Cardigliano .nb_max = IONIC_MAX_RING_DESC, 59a27d9013SAlfredo Cardigliano .nb_min = IONIC_MIN_RING_DESC, 60a27d9013SAlfredo Cardigliano .nb_align = 1, 61a27d9013SAlfredo Cardigliano }; 62a27d9013SAlfredo Cardigliano 6356117636SAndrew Boyer static const struct rte_eth_desc_lim tx_desc_lim_v1 = { 64a27d9013SAlfredo Cardigliano .nb_max = IONIC_MAX_RING_DESC, 65a27d9013SAlfredo Cardigliano .nb_min = IONIC_MIN_RING_DESC, 66a27d9013SAlfredo Cardigliano .nb_align = 1, 67d13d7829SAndrew Boyer .nb_seg_max = IONIC_TX_MAX_SG_ELEMS_V1 + 1, 68d13d7829SAndrew Boyer .nb_mtu_seg_max = IONIC_TX_MAX_SG_ELEMS_V1 + 1, 69a27d9013SAlfredo Cardigliano }; 70a27d9013SAlfredo Cardigliano 71669c8de6SAlfredo Cardigliano static const struct eth_dev_ops ionic_eth_dev_ops = { 72598f6726SAlfredo Cardigliano .dev_infos_get = ionic_dev_info_get, 73b5b56afdSAndrew Boyer .dev_supported_ptypes_get = ionic_dev_supported_ptypes_get, 74598f6726SAlfredo Cardigliano .dev_configure = ionic_dev_configure, 75598f6726SAlfredo Cardigliano .mtu_set = ionic_dev_mtu_set, 76598f6726SAlfredo Cardigliano .dev_start = ionic_dev_start, 77598f6726SAlfredo Cardigliano .dev_stop = ionic_dev_stop, 78598f6726SAlfredo Cardigliano .dev_close = ionic_dev_close, 79598f6726SAlfredo Cardigliano .link_update = ionic_dev_link_update, 80598f6726SAlfredo Cardigliano .dev_set_link_up = ionic_dev_set_link_up, 81598f6726SAlfredo Cardigliano .dev_set_link_down = ionic_dev_set_link_down, 8254fe083fSAlfredo Cardigliano .mac_addr_add = ionic_dev_add_mac, 8354fe083fSAlfredo Cardigliano .mac_addr_remove = ionic_dev_remove_mac, 8454fe083fSAlfredo Cardigliano .mac_addr_set = ionic_dev_set_mac, 8554fe083fSAlfredo Cardigliano .vlan_filter_set = ionic_dev_vlan_filter_set, 8654fe083fSAlfredo Cardigliano .promiscuous_enable = ionic_dev_promiscuous_enable, 8754fe083fSAlfredo Cardigliano .promiscuous_disable = ionic_dev_promiscuous_disable, 8854fe083fSAlfredo Cardigliano .allmulticast_enable = ionic_dev_allmulticast_enable, 8954fe083fSAlfredo Cardigliano .allmulticast_disable = ionic_dev_allmulticast_disable, 90ec15c66bSAlfredo Cardigliano .flow_ctrl_get = ionic_flow_ctrl_get, 91ec15c66bSAlfredo Cardigliano .flow_ctrl_set = ionic_flow_ctrl_set, 92a27d9013SAlfredo Cardigliano .rxq_info_get = ionic_rxq_info_get, 93a27d9013SAlfredo Cardigliano .txq_info_get = ionic_txq_info_get, 94a27d9013SAlfredo Cardigliano .rx_queue_setup = ionic_dev_rx_queue_setup, 95a27d9013SAlfredo Cardigliano .rx_queue_release = ionic_dev_rx_queue_release, 96a27d9013SAlfredo Cardigliano .rx_queue_start = ionic_dev_rx_queue_start, 97a27d9013SAlfredo Cardigliano .rx_queue_stop = ionic_dev_rx_queue_stop, 98a27d9013SAlfredo Cardigliano .tx_queue_setup = ionic_dev_tx_queue_setup, 99a27d9013SAlfredo Cardigliano .tx_queue_release = ionic_dev_tx_queue_release, 100a27d9013SAlfredo Cardigliano .tx_queue_start = ionic_dev_tx_queue_start, 101a27d9013SAlfredo Cardigliano .tx_queue_stop = ionic_dev_tx_queue_stop, 102a27d9013SAlfredo Cardigliano .vlan_offload_set = ionic_vlan_offload_set, 10322e7171bSAlfredo Cardigliano .reta_update = ionic_dev_rss_reta_update, 10422e7171bSAlfredo Cardigliano .reta_query = ionic_dev_rss_reta_query, 10522e7171bSAlfredo Cardigliano .rss_hash_conf_get = ionic_dev_rss_hash_conf_get, 10622e7171bSAlfredo Cardigliano .rss_hash_update = ionic_dev_rss_hash_update, 1073cdfd905SAlfredo Cardigliano .stats_get = ionic_dev_stats_get, 1083cdfd905SAlfredo Cardigliano .stats_reset = ionic_dev_stats_reset, 1093cdfd905SAlfredo Cardigliano .xstats_get = ionic_dev_xstats_get, 1103cdfd905SAlfredo Cardigliano .xstats_get_by_id = ionic_dev_xstats_get_by_id, 1113cdfd905SAlfredo Cardigliano .xstats_reset = ionic_dev_xstats_reset, 1123cdfd905SAlfredo Cardigliano .xstats_get_names = ionic_dev_xstats_get_names, 1133cdfd905SAlfredo Cardigliano .xstats_get_names_by_id = ionic_dev_xstats_get_names_by_id, 114eec10fb0SAlfredo Cardigliano .fw_version_get = ionic_dev_fw_version_get, 115669c8de6SAlfredo Cardigliano }; 116669c8de6SAlfredo Cardigliano 1173cdfd905SAlfredo Cardigliano struct rte_ionic_xstats_name_off { 1183cdfd905SAlfredo Cardigliano char name[RTE_ETH_XSTATS_NAME_SIZE]; 1193cdfd905SAlfredo Cardigliano unsigned int offset; 1203cdfd905SAlfredo Cardigliano }; 1213cdfd905SAlfredo Cardigliano 1223cdfd905SAlfredo Cardigliano static const struct rte_ionic_xstats_name_off rte_ionic_xstats_strings[] = { 1233cdfd905SAlfredo Cardigliano /* RX */ 1243cdfd905SAlfredo Cardigliano {"rx_ucast_bytes", offsetof(struct ionic_lif_stats, 1253cdfd905SAlfredo Cardigliano rx_ucast_bytes)}, 1263cdfd905SAlfredo Cardigliano {"rx_ucast_packets", offsetof(struct ionic_lif_stats, 1273cdfd905SAlfredo Cardigliano rx_ucast_packets)}, 1283cdfd905SAlfredo Cardigliano {"rx_mcast_bytes", offsetof(struct ionic_lif_stats, 1293cdfd905SAlfredo Cardigliano rx_mcast_bytes)}, 1303cdfd905SAlfredo Cardigliano {"rx_mcast_packets", offsetof(struct ionic_lif_stats, 1313cdfd905SAlfredo Cardigliano rx_mcast_packets)}, 1323cdfd905SAlfredo Cardigliano {"rx_bcast_bytes", offsetof(struct ionic_lif_stats, 1333cdfd905SAlfredo Cardigliano rx_bcast_bytes)}, 1343cdfd905SAlfredo Cardigliano {"rx_bcast_packets", offsetof(struct ionic_lif_stats, 1353cdfd905SAlfredo Cardigliano rx_bcast_packets)}, 1363cdfd905SAlfredo Cardigliano /* RX drops */ 1373cdfd905SAlfredo Cardigliano {"rx_ucast_drop_bytes", offsetof(struct ionic_lif_stats, 1383cdfd905SAlfredo Cardigliano rx_ucast_drop_bytes)}, 1393cdfd905SAlfredo Cardigliano {"rx_ucast_drop_packets", offsetof(struct ionic_lif_stats, 1403cdfd905SAlfredo Cardigliano rx_ucast_drop_packets)}, 1413cdfd905SAlfredo Cardigliano {"rx_mcast_drop_bytes", offsetof(struct ionic_lif_stats, 1423cdfd905SAlfredo Cardigliano rx_mcast_drop_bytes)}, 1433cdfd905SAlfredo Cardigliano {"rx_mcast_drop_packets", offsetof(struct ionic_lif_stats, 1443cdfd905SAlfredo Cardigliano rx_mcast_drop_packets)}, 1453cdfd905SAlfredo Cardigliano {"rx_bcast_drop_bytes", offsetof(struct ionic_lif_stats, 1463cdfd905SAlfredo Cardigliano rx_bcast_drop_bytes)}, 1473cdfd905SAlfredo Cardigliano {"rx_bcast_drop_packets", offsetof(struct ionic_lif_stats, 1483cdfd905SAlfredo Cardigliano rx_bcast_drop_packets)}, 1493cdfd905SAlfredo Cardigliano {"rx_dma_error", offsetof(struct ionic_lif_stats, 1503cdfd905SAlfredo Cardigliano rx_dma_error)}, 1513cdfd905SAlfredo Cardigliano /* TX */ 1523cdfd905SAlfredo Cardigliano {"tx_ucast_bytes", offsetof(struct ionic_lif_stats, 1533cdfd905SAlfredo Cardigliano tx_ucast_bytes)}, 1543cdfd905SAlfredo Cardigliano {"tx_ucast_packets", offsetof(struct ionic_lif_stats, 1553cdfd905SAlfredo Cardigliano tx_ucast_packets)}, 1563cdfd905SAlfredo Cardigliano {"tx_mcast_bytes", offsetof(struct ionic_lif_stats, 1573cdfd905SAlfredo Cardigliano tx_mcast_bytes)}, 1583cdfd905SAlfredo Cardigliano {"tx_mcast_packets", offsetof(struct ionic_lif_stats, 1593cdfd905SAlfredo Cardigliano tx_mcast_packets)}, 1603cdfd905SAlfredo Cardigliano {"tx_bcast_bytes", offsetof(struct ionic_lif_stats, 1613cdfd905SAlfredo Cardigliano tx_bcast_bytes)}, 1623cdfd905SAlfredo Cardigliano {"tx_bcast_packets", offsetof(struct ionic_lif_stats, 1633cdfd905SAlfredo Cardigliano tx_bcast_packets)}, 1643cdfd905SAlfredo Cardigliano /* TX drops */ 1653cdfd905SAlfredo Cardigliano {"tx_ucast_drop_bytes", offsetof(struct ionic_lif_stats, 1663cdfd905SAlfredo Cardigliano tx_ucast_drop_bytes)}, 1673cdfd905SAlfredo Cardigliano {"tx_ucast_drop_packets", offsetof(struct ionic_lif_stats, 1683cdfd905SAlfredo Cardigliano tx_ucast_drop_packets)}, 1693cdfd905SAlfredo Cardigliano {"tx_mcast_drop_bytes", offsetof(struct ionic_lif_stats, 1703cdfd905SAlfredo Cardigliano tx_mcast_drop_bytes)}, 1713cdfd905SAlfredo Cardigliano {"tx_mcast_drop_packets", offsetof(struct ionic_lif_stats, 1723cdfd905SAlfredo Cardigliano tx_mcast_drop_packets)}, 1733cdfd905SAlfredo Cardigliano {"tx_bcast_drop_bytes", offsetof(struct ionic_lif_stats, 1743cdfd905SAlfredo Cardigliano tx_bcast_drop_bytes)}, 1753cdfd905SAlfredo Cardigliano {"tx_bcast_drop_packets", offsetof(struct ionic_lif_stats, 1763cdfd905SAlfredo Cardigliano tx_bcast_drop_packets)}, 1773cdfd905SAlfredo Cardigliano {"tx_dma_error", offsetof(struct ionic_lif_stats, 1783cdfd905SAlfredo Cardigliano tx_dma_error)}, 1793cdfd905SAlfredo Cardigliano /* Rx Queue/Ring drops */ 1803cdfd905SAlfredo Cardigliano {"rx_queue_disabled", offsetof(struct ionic_lif_stats, 1813cdfd905SAlfredo Cardigliano rx_queue_disabled)}, 1823cdfd905SAlfredo Cardigliano {"rx_queue_empty", offsetof(struct ionic_lif_stats, 1833cdfd905SAlfredo Cardigliano rx_queue_empty)}, 1843cdfd905SAlfredo Cardigliano {"rx_queue_error", offsetof(struct ionic_lif_stats, 1853cdfd905SAlfredo Cardigliano rx_queue_error)}, 1863cdfd905SAlfredo Cardigliano {"rx_desc_fetch_error", offsetof(struct ionic_lif_stats, 1873cdfd905SAlfredo Cardigliano rx_desc_fetch_error)}, 1883cdfd905SAlfredo Cardigliano {"rx_desc_data_error", offsetof(struct ionic_lif_stats, 1893cdfd905SAlfredo Cardigliano rx_desc_data_error)}, 1903cdfd905SAlfredo Cardigliano /* Tx Queue/Ring drops */ 1913cdfd905SAlfredo Cardigliano {"tx_queue_disabled", offsetof(struct ionic_lif_stats, 1923cdfd905SAlfredo Cardigliano tx_queue_disabled)}, 1933cdfd905SAlfredo Cardigliano {"tx_queue_error", offsetof(struct ionic_lif_stats, 1943cdfd905SAlfredo Cardigliano tx_queue_error)}, 1953cdfd905SAlfredo Cardigliano {"tx_desc_fetch_error", offsetof(struct ionic_lif_stats, 1963cdfd905SAlfredo Cardigliano tx_desc_fetch_error)}, 1973cdfd905SAlfredo Cardigliano {"tx_desc_data_error", offsetof(struct ionic_lif_stats, 1983cdfd905SAlfredo Cardigliano tx_desc_data_error)}, 199081d035eSBrad Larson /* Flexible firmware events */ 200081d035eSBrad Larson {"fw_flex_event1", offsetof(struct ionic_lif_stats, flex1)}, 201081d035eSBrad Larson {"fw_flex_event2", offsetof(struct ionic_lif_stats, flex2)}, 202081d035eSBrad Larson {"fw_flex_event3", offsetof(struct ionic_lif_stats, flex3)}, 203081d035eSBrad Larson {"fw_flex_event4", offsetof(struct ionic_lif_stats, flex4)}, 204081d035eSBrad Larson {"fw_flex_event5", offsetof(struct ionic_lif_stats, flex5)}, 205081d035eSBrad Larson {"fw_flex_event6", offsetof(struct ionic_lif_stats, flex6)}, 206081d035eSBrad Larson {"fw_flex_event7", offsetof(struct ionic_lif_stats, flex7)}, 207081d035eSBrad Larson {"fw_flex_event8", offsetof(struct ionic_lif_stats, flex8)}, 208081d035eSBrad Larson {"fw_flex_event9", offsetof(struct ionic_lif_stats, flex9)}, 209081d035eSBrad Larson {"fw_flex_event10", offsetof(struct ionic_lif_stats, flex10)}, 210081d035eSBrad Larson {"fw_flex_event11", offsetof(struct ionic_lif_stats, flex11)}, 211081d035eSBrad Larson {"fw_flex_event12", offsetof(struct ionic_lif_stats, flex12)}, 212081d035eSBrad Larson {"fw_flex_event13", offsetof(struct ionic_lif_stats, flex13)}, 213081d035eSBrad Larson {"fw_flex_event14", offsetof(struct ionic_lif_stats, flex14)}, 214081d035eSBrad Larson {"fw_flex_event15", offsetof(struct ionic_lif_stats, flex15)}, 215081d035eSBrad Larson {"fw_flex_event16", offsetof(struct ionic_lif_stats, flex16)}, 216081d035eSBrad Larson {"fw_flex_event17", offsetof(struct ionic_lif_stats, flex17)}, 217081d035eSBrad Larson {"fw_flex_event18", offsetof(struct ionic_lif_stats, flex18)}, 218081d035eSBrad Larson {"fw_flex_event19", offsetof(struct ionic_lif_stats, flex19)}, 219081d035eSBrad Larson {"fw_flex_event20", offsetof(struct ionic_lif_stats, flex20)}, 220081d035eSBrad Larson {"fw_flex_event21", offsetof(struct ionic_lif_stats, flex21)}, 221081d035eSBrad Larson {"fw_flex_event22", offsetof(struct ionic_lif_stats, flex22)}, 222081d035eSBrad Larson {"fw_flex_event23", offsetof(struct ionic_lif_stats, flex23)}, 223081d035eSBrad Larson {"fw_flex_event24", offsetof(struct ionic_lif_stats, flex24)}, 224081d035eSBrad Larson {"fw_flex_event25", offsetof(struct ionic_lif_stats, flex25)}, 225081d035eSBrad Larson {"fw_flex_event26", offsetof(struct ionic_lif_stats, flex26)}, 226081d035eSBrad Larson {"fw_flex_event27", offsetof(struct ionic_lif_stats, flex27)}, 227081d035eSBrad Larson {"fw_flex_event28", offsetof(struct ionic_lif_stats, flex28)}, 228081d035eSBrad Larson {"fw_flex_event29", offsetof(struct ionic_lif_stats, flex29)}, 229081d035eSBrad Larson {"fw_flex_event30", offsetof(struct ionic_lif_stats, flex30)}, 230081d035eSBrad Larson {"fw_flex_event31", offsetof(struct ionic_lif_stats, flex31)}, 231081d035eSBrad Larson {"fw_flex_event32", offsetof(struct ionic_lif_stats, flex32)}, 2323cdfd905SAlfredo Cardigliano }; 2333cdfd905SAlfredo Cardigliano 23476276d71SAndrew Boyer #define IONIC_NB_HW_STATS RTE_DIM(rte_ionic_xstats_strings) 2353cdfd905SAlfredo Cardigliano 236eec10fb0SAlfredo Cardigliano static int 237eec10fb0SAlfredo Cardigliano ionic_dev_fw_version_get(struct rte_eth_dev *eth_dev, 238eec10fb0SAlfredo Cardigliano char *fw_version, size_t fw_size) 239eec10fb0SAlfredo Cardigliano { 240eec10fb0SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 241eec10fb0SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 242d345d6c9SFerruh Yigit int ret; 243eec10fb0SAlfredo Cardigliano 244d345d6c9SFerruh Yigit ret = snprintf(fw_version, fw_size, "%s", 245d345d6c9SFerruh Yigit adapter->fw_version); 246d345d6c9SFerruh Yigit if (ret < 0) 247eec10fb0SAlfredo Cardigliano return -EINVAL; 248eec10fb0SAlfredo Cardigliano 249d345d6c9SFerruh Yigit ret += 1; /* add the size of '\0' */ 250d345d6c9SFerruh Yigit if (fw_size < (size_t)ret) 251d345d6c9SFerruh Yigit return ret; 252d345d6c9SFerruh Yigit else 253eec10fb0SAlfredo Cardigliano return 0; 254eec10fb0SAlfredo Cardigliano } 255eec10fb0SAlfredo Cardigliano 256598f6726SAlfredo Cardigliano /* 257598f6726SAlfredo Cardigliano * Set device link up, enable tx. 258598f6726SAlfredo Cardigliano */ 259598f6726SAlfredo Cardigliano static int 260598f6726SAlfredo Cardigliano ionic_dev_set_link_up(struct rte_eth_dev *eth_dev) 261598f6726SAlfredo Cardigliano { 262598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 263598f6726SAlfredo Cardigliano int err; 264598f6726SAlfredo Cardigliano 265598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 266598f6726SAlfredo Cardigliano 267be63459eSAndrew Boyer err = ionic_lif_start(lif); 268be63459eSAndrew Boyer if (err) 269be63459eSAndrew Boyer IONIC_PRINT(ERR, "Could not start lif to set link up"); 270598f6726SAlfredo Cardigliano 271be63459eSAndrew Boyer ionic_dev_link_update(lif->eth_dev, 0); 272be63459eSAndrew Boyer 273598f6726SAlfredo Cardigliano return err; 274598f6726SAlfredo Cardigliano } 275598f6726SAlfredo Cardigliano 276598f6726SAlfredo Cardigliano /* 277598f6726SAlfredo Cardigliano * Set device link down, disable tx. 278598f6726SAlfredo Cardigliano */ 279598f6726SAlfredo Cardigliano static int 280598f6726SAlfredo Cardigliano ionic_dev_set_link_down(struct rte_eth_dev *eth_dev) 281598f6726SAlfredo Cardigliano { 282598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 283598f6726SAlfredo Cardigliano 284598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 285598f6726SAlfredo Cardigliano 286be63459eSAndrew Boyer ionic_lif_stop(lif); 287598f6726SAlfredo Cardigliano 288be63459eSAndrew Boyer ionic_dev_link_update(lif->eth_dev, 0); 289598f6726SAlfredo Cardigliano 290598f6726SAlfredo Cardigliano return 0; 291598f6726SAlfredo Cardigliano } 292598f6726SAlfredo Cardigliano 293be63459eSAndrew Boyer int 294598f6726SAlfredo Cardigliano ionic_dev_link_update(struct rte_eth_dev *eth_dev, 295598f6726SAlfredo Cardigliano int wait_to_complete __rte_unused) 296598f6726SAlfredo Cardigliano { 297598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 298598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 299598f6726SAlfredo Cardigliano struct rte_eth_link link; 300598f6726SAlfredo Cardigliano 301598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 302598f6726SAlfredo Cardigliano 303598f6726SAlfredo Cardigliano /* Initialize */ 304598f6726SAlfredo Cardigliano memset(&link, 0, sizeof(link)); 3050dad8b3dSAndrew Boyer 3060dad8b3dSAndrew Boyer if (adapter->idev.port_info->config.an_enable) { 307295968d1SFerruh Yigit link.link_autoneg = RTE_ETH_LINK_AUTONEG; 3080dad8b3dSAndrew Boyer } 309598f6726SAlfredo Cardigliano 310be63459eSAndrew Boyer if (!adapter->link_up || 311be63459eSAndrew Boyer !(lif->state & IONIC_LIF_F_UP)) { 312598f6726SAlfredo Cardigliano /* Interface is down */ 313295968d1SFerruh Yigit link.link_status = RTE_ETH_LINK_DOWN; 314295968d1SFerruh Yigit link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX; 315295968d1SFerruh Yigit link.link_speed = RTE_ETH_SPEED_NUM_NONE; 316598f6726SAlfredo Cardigliano } else { 317598f6726SAlfredo Cardigliano /* Interface is up */ 318295968d1SFerruh Yigit link.link_status = RTE_ETH_LINK_UP; 319295968d1SFerruh Yigit link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX; 320598f6726SAlfredo Cardigliano switch (adapter->link_speed) { 3212d342155SVamsi Krishna Atluri case 1000: 3222d342155SVamsi Krishna Atluri link.link_speed = RTE_ETH_SPEED_NUM_1G; 3232d342155SVamsi Krishna Atluri break; 324598f6726SAlfredo Cardigliano case 10000: 325295968d1SFerruh Yigit link.link_speed = RTE_ETH_SPEED_NUM_10G; 326598f6726SAlfredo Cardigliano break; 327598f6726SAlfredo Cardigliano case 25000: 328295968d1SFerruh Yigit link.link_speed = RTE_ETH_SPEED_NUM_25G; 329598f6726SAlfredo Cardigliano break; 330598f6726SAlfredo Cardigliano case 40000: 331295968d1SFerruh Yigit link.link_speed = RTE_ETH_SPEED_NUM_40G; 332598f6726SAlfredo Cardigliano break; 333598f6726SAlfredo Cardigliano case 50000: 334295968d1SFerruh Yigit link.link_speed = RTE_ETH_SPEED_NUM_50G; 335598f6726SAlfredo Cardigliano break; 336598f6726SAlfredo Cardigliano case 100000: 337295968d1SFerruh Yigit link.link_speed = RTE_ETH_SPEED_NUM_100G; 338598f6726SAlfredo Cardigliano break; 3392d342155SVamsi Krishna Atluri case 200000: 3402d342155SVamsi Krishna Atluri link.link_speed = RTE_ETH_SPEED_NUM_200G; 3412d342155SVamsi Krishna Atluri break; 342598f6726SAlfredo Cardigliano default: 343295968d1SFerruh Yigit link.link_speed = RTE_ETH_SPEED_NUM_NONE; 344598f6726SAlfredo Cardigliano break; 345598f6726SAlfredo Cardigliano } 346598f6726SAlfredo Cardigliano } 347598f6726SAlfredo Cardigliano 348598f6726SAlfredo Cardigliano return rte_eth_linkstatus_set(eth_dev, &link); 349598f6726SAlfredo Cardigliano } 350598f6726SAlfredo Cardigliano 35127b942c8SAlfredo Cardigliano /** 35227b942c8SAlfredo Cardigliano * Interrupt handler triggered by NIC for handling 35327b942c8SAlfredo Cardigliano * specific interrupt. 35427b942c8SAlfredo Cardigliano * 35527b942c8SAlfredo Cardigliano * @param param 35627b942c8SAlfredo Cardigliano * The address of parameter registered before. 35727b942c8SAlfredo Cardigliano * 35827b942c8SAlfredo Cardigliano * @return 35927b942c8SAlfredo Cardigliano * void 36027b942c8SAlfredo Cardigliano */ 3618eaafff3SAndrew Boyer void 36227b942c8SAlfredo Cardigliano ionic_dev_interrupt_handler(void *param) 36327b942c8SAlfredo Cardigliano { 36427b942c8SAlfredo Cardigliano struct ionic_adapter *adapter = (struct ionic_adapter *)param; 36527b942c8SAlfredo Cardigliano 36627b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "->"); 36727b942c8SAlfredo Cardigliano 36800b65da5SAndrew Boyer if (adapter->lif) 36900b65da5SAndrew Boyer ionic_notifyq_handler(adapter->lif, -1); 37027b942c8SAlfredo Cardigliano } 37127b942c8SAlfredo Cardigliano 372669c8de6SAlfredo Cardigliano static int 373598f6726SAlfredo Cardigliano ionic_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) 374598f6726SAlfredo Cardigliano { 375598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 376598f6726SAlfredo Cardigliano 377b671e69aSAndrew Boyer if (lif->state & IONIC_LIF_F_UP) { 378b671e69aSAndrew Boyer IONIC_PRINT(ERR, "Stop %s before setting mtu", lif->name); 379b671e69aSAndrew Boyer return -EBUSY; 380b671e69aSAndrew Boyer } 381598f6726SAlfredo Cardigliano 382b671e69aSAndrew Boyer /* Note: mtu check against min/max is done by the API */ 383b671e69aSAndrew Boyer IONIC_PRINT(INFO, "Setting mtu %u", mtu); 384598f6726SAlfredo Cardigliano 385b671e69aSAndrew Boyer /* Update the frame size used by the Rx path */ 386b671e69aSAndrew Boyer lif->frame_size = mtu + IONIC_ETH_OVERHEAD; 387598f6726SAlfredo Cardigliano 388598f6726SAlfredo Cardigliano return 0; 389598f6726SAlfredo Cardigliano } 390598f6726SAlfredo Cardigliano 391598f6726SAlfredo Cardigliano static int 392598f6726SAlfredo Cardigliano ionic_dev_info_get(struct rte_eth_dev *eth_dev, 393598f6726SAlfredo Cardigliano struct rte_eth_dev_info *dev_info) 394598f6726SAlfredo Cardigliano { 395598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 396598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 397598f6726SAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 39809f806e9SAndrew Boyer union ionic_lif_config *cfg = &ident->lif.eth.config; 399598f6726SAlfredo Cardigliano 400598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 401598f6726SAlfredo Cardigliano 402598f6726SAlfredo Cardigliano dev_info->max_rx_queues = (uint16_t) 40309f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_RXQ]); 404598f6726SAlfredo Cardigliano dev_info->max_tx_queues = (uint16_t) 40509f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_TXQ]); 40609f806e9SAndrew Boyer 407598f6726SAlfredo Cardigliano /* Also add ETHER_CRC_LEN if the adapter is able to keep CRC */ 408b671e69aSAndrew Boyer dev_info->min_mtu = RTE_MAX((uint32_t)IONIC_MIN_MTU, 409b671e69aSAndrew Boyer rte_le_to_cpu_32(ident->lif.eth.min_mtu)); 410b671e69aSAndrew Boyer dev_info->max_mtu = RTE_MIN((uint32_t)IONIC_MAX_MTU, 411b671e69aSAndrew Boyer rte_le_to_cpu_32(ident->lif.eth.max_mtu)); 412b671e69aSAndrew Boyer dev_info->min_rx_bufsize = dev_info->min_mtu + IONIC_ETH_OVERHEAD; 413b671e69aSAndrew Boyer dev_info->max_rx_pktlen = dev_info->max_mtu + IONIC_ETH_OVERHEAD; 414b671e69aSAndrew Boyer dev_info->max_lro_pkt_size = 415b671e69aSAndrew Boyer eth_dev->data->dev_conf.rxmode.max_lro_pkt_size; 416598f6726SAlfredo Cardigliano 417b671e69aSAndrew Boyer dev_info->max_mac_addrs = adapter->max_mac_addrs; 41822e7171bSAlfredo Cardigliano dev_info->hash_key_size = IONIC_RSS_HASH_KEY_SIZE; 41909f806e9SAndrew Boyer dev_info->reta_size = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz); 42022e7171bSAlfredo Cardigliano dev_info->flow_type_rss_offloads = IONIC_ETH_RSS_OFFLOAD_ALL; 42122e7171bSAlfredo Cardigliano 422598f6726SAlfredo Cardigliano dev_info->speed_capa = 423295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_10G | 424295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_25G | 425295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_40G | 426295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_50G | 427295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_100G; 428598f6726SAlfredo Cardigliano 429a27d9013SAlfredo Cardigliano /* 43018a44465SAndrew Boyer * Per-queue capabilities 43118a44465SAndrew Boyer * RTE does not support disabling a feature on a queue if it is 43218a44465SAndrew Boyer * enabled globally on the device. Thus the driver does not advertise 433295968d1SFerruh Yigit * capabilities like RTE_ETH_TX_OFFLOAD_IPV4_CKSUM as per-queue even 43418a44465SAndrew Boyer * though the driver would be otherwise capable of disabling it on 43518a44465SAndrew Boyer * a per-queue basis. 436a27d9013SAlfredo Cardigliano */ 437a27d9013SAlfredo Cardigliano 43818a44465SAndrew Boyer dev_info->rx_queue_offload_capa = 0; 4399ac234eeSAndrew Boyer dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; 440a27d9013SAlfredo Cardigliano 441a27d9013SAlfredo Cardigliano /* 442a27d9013SAlfredo Cardigliano * Per-port capabilities 443a27d9013SAlfredo Cardigliano * See ionic_set_features to request and check supported features 444a27d9013SAlfredo Cardigliano */ 445a27d9013SAlfredo Cardigliano 446a27d9013SAlfredo Cardigliano dev_info->rx_offload_capa = dev_info->rx_queue_offload_capa | 447295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | 448295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_UDP_CKSUM | 449295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_TCP_CKSUM | 450295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_FILTER | 451295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_STRIP | 452295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_SCATTER | 453295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_RSS_HASH | 454a27d9013SAlfredo Cardigliano 0; 455a27d9013SAlfredo Cardigliano 456a27d9013SAlfredo Cardigliano dev_info->tx_offload_capa = dev_info->tx_queue_offload_capa | 457295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | 458295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_UDP_CKSUM | 459295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_TCP_CKSUM | 460295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | 461295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | 462295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_MULTI_SEGS | 463295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_TCP_TSO | 464295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_VLAN_INSERT | 465a27d9013SAlfredo Cardigliano 0; 466a27d9013SAlfredo Cardigliano 467a27d9013SAlfredo Cardigliano dev_info->rx_desc_lim = rx_desc_lim; 46856117636SAndrew Boyer dev_info->tx_desc_lim = tx_desc_lim_v1; 469a27d9013SAlfredo Cardigliano 470a27d9013SAlfredo Cardigliano /* Driver-preferred Rx/Tx parameters */ 47107512941SAndrew Boyer dev_info->default_rxportconf.burst_size = IONIC_DEF_TXRX_BURST; 47207512941SAndrew Boyer dev_info->default_txportconf.burst_size = IONIC_DEF_TXRX_BURST; 473a27d9013SAlfredo Cardigliano dev_info->default_rxportconf.nb_queues = 1; 474a27d9013SAlfredo Cardigliano dev_info->default_txportconf.nb_queues = 1; 475a27d9013SAlfredo Cardigliano dev_info->default_rxportconf.ring_size = IONIC_DEF_TXRX_DESC; 476a27d9013SAlfredo Cardigliano dev_info->default_txportconf.ring_size = IONIC_DEF_TXRX_DESC; 477a27d9013SAlfredo Cardigliano 47818a44465SAndrew Boyer dev_info->default_rxconf = (struct rte_eth_rxconf) { 47918a44465SAndrew Boyer /* Packets are always dropped if no desc are available */ 48018a44465SAndrew Boyer .rx_drop_en = 1, 48118a44465SAndrew Boyer }; 48218a44465SAndrew Boyer 483598f6726SAlfredo Cardigliano return 0; 484598f6726SAlfredo Cardigliano } 485598f6726SAlfredo Cardigliano 486598f6726SAlfredo Cardigliano static int 487ec15c66bSAlfredo Cardigliano ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev, 488ec15c66bSAlfredo Cardigliano struct rte_eth_fc_conf *fc_conf) 489ec15c66bSAlfredo Cardigliano { 490ec15c66bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 491ec15c66bSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 492ec15c66bSAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 493ec15c66bSAlfredo Cardigliano 494ec15c66bSAlfredo Cardigliano if (idev->port_info) { 495c3ab74fcSAndrew Boyer /* Flow control autoneg not supported */ 496c3ab74fcSAndrew Boyer fc_conf->autoneg = 0; 497ec15c66bSAlfredo Cardigliano 498ec15c66bSAlfredo Cardigliano if (idev->port_info->config.pause_type) 499295968d1SFerruh Yigit fc_conf->mode = RTE_ETH_FC_FULL; 500ec15c66bSAlfredo Cardigliano else 501295968d1SFerruh Yigit fc_conf->mode = RTE_ETH_FC_NONE; 502ec15c66bSAlfredo Cardigliano } 503ec15c66bSAlfredo Cardigliano 504ec15c66bSAlfredo Cardigliano return 0; 505ec15c66bSAlfredo Cardigliano } 506ec15c66bSAlfredo Cardigliano 507ec15c66bSAlfredo Cardigliano static int 508ec15c66bSAlfredo Cardigliano ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev, 509ec15c66bSAlfredo Cardigliano struct rte_eth_fc_conf *fc_conf) 510ec15c66bSAlfredo Cardigliano { 511ec15c66bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 512ec15c66bSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 513ec15c66bSAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 514ec15c66bSAlfredo Cardigliano uint8_t pause_type = IONIC_PORT_PAUSE_TYPE_NONE; 515c3ab74fcSAndrew Boyer int err; 516c3ab74fcSAndrew Boyer 517c3ab74fcSAndrew Boyer if (fc_conf->autoneg) { 518c3ab74fcSAndrew Boyer IONIC_PRINT(WARNING, "Flow control autoneg not supported"); 519c3ab74fcSAndrew Boyer return -ENOTSUP; 520c3ab74fcSAndrew Boyer } 521ec15c66bSAlfredo Cardigliano 522ec15c66bSAlfredo Cardigliano switch (fc_conf->mode) { 523295968d1SFerruh Yigit case RTE_ETH_FC_NONE: 524ec15c66bSAlfredo Cardigliano pause_type = IONIC_PORT_PAUSE_TYPE_NONE; 525ec15c66bSAlfredo Cardigliano break; 526295968d1SFerruh Yigit case RTE_ETH_FC_FULL: 527ec15c66bSAlfredo Cardigliano pause_type = IONIC_PORT_PAUSE_TYPE_LINK; 528ec15c66bSAlfredo Cardigliano break; 529295968d1SFerruh Yigit case RTE_ETH_FC_RX_PAUSE: 530295968d1SFerruh Yigit case RTE_ETH_FC_TX_PAUSE: 531ec15c66bSAlfredo Cardigliano return -ENOTSUP; 532ec15c66bSAlfredo Cardigliano } 533ec15c66bSAlfredo Cardigliano 534ec15c66bSAlfredo Cardigliano ionic_dev_cmd_port_pause(idev, pause_type); 535c3ab74fcSAndrew Boyer err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 536c3ab74fcSAndrew Boyer if (err) 537c3ab74fcSAndrew Boyer IONIC_PRINT(WARNING, "Failed to configure flow control"); 538ec15c66bSAlfredo Cardigliano 539c3ab74fcSAndrew Boyer return err; 540ec15c66bSAlfredo Cardigliano } 541ec15c66bSAlfredo Cardigliano 542ec15c66bSAlfredo Cardigliano static int 543a27d9013SAlfredo Cardigliano ionic_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) 544a27d9013SAlfredo Cardigliano { 545a27d9013SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 546a27d9013SAlfredo Cardigliano 54718a44465SAndrew Boyer ionic_lif_configure_vlan_offload(lif, mask); 548a27d9013SAlfredo Cardigliano 549a27d9013SAlfredo Cardigliano ionic_lif_set_features(lif); 550a27d9013SAlfredo Cardigliano 551a27d9013SAlfredo Cardigliano return 0; 552a27d9013SAlfredo Cardigliano } 553a27d9013SAlfredo Cardigliano 554a27d9013SAlfredo Cardigliano static int 55522e7171bSAlfredo Cardigliano ionic_dev_rss_reta_update(struct rte_eth_dev *eth_dev, 55622e7171bSAlfredo Cardigliano struct rte_eth_rss_reta_entry64 *reta_conf, 55722e7171bSAlfredo Cardigliano uint16_t reta_size) 55822e7171bSAlfredo Cardigliano { 55922e7171bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 56022e7171bSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 56122e7171bSAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 56222e7171bSAlfredo Cardigliano uint32_t i, j, index, num; 56309f806e9SAndrew Boyer uint16_t tbl_sz = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz); 56422e7171bSAlfredo Cardigliano 56522e7171bSAlfredo Cardigliano IONIC_PRINT_CALL(); 56622e7171bSAlfredo Cardigliano 56722e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl) { 56822e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "RSS RETA not initialized, " 56922e7171bSAlfredo Cardigliano "can't update the table"); 57022e7171bSAlfredo Cardigliano return -EINVAL; 57122e7171bSAlfredo Cardigliano } 57222e7171bSAlfredo Cardigliano 57309f806e9SAndrew Boyer if (reta_size != tbl_sz) { 57422e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "The size of hash lookup table configured " 5754ae96cb8SAndrew Boyer "(%d) does not match the number hardware can support " 57622e7171bSAlfredo Cardigliano "(%d)", 57709f806e9SAndrew Boyer reta_size, tbl_sz); 57822e7171bSAlfredo Cardigliano return -EINVAL; 57922e7171bSAlfredo Cardigliano } 58022e7171bSAlfredo Cardigliano 581295968d1SFerruh Yigit num = tbl_sz / RTE_ETH_RETA_GROUP_SIZE; 58222e7171bSAlfredo Cardigliano 58322e7171bSAlfredo Cardigliano for (i = 0; i < num; i++) { 584295968d1SFerruh Yigit for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) { 58522e7171bSAlfredo Cardigliano if (reta_conf[i].mask & ((uint64_t)1 << j)) { 586295968d1SFerruh Yigit index = (i * RTE_ETH_RETA_GROUP_SIZE) + j; 58722e7171bSAlfredo Cardigliano lif->rss_ind_tbl[index] = reta_conf[i].reta[j]; 58822e7171bSAlfredo Cardigliano } 58922e7171bSAlfredo Cardigliano } 59022e7171bSAlfredo Cardigliano } 59122e7171bSAlfredo Cardigliano 59222e7171bSAlfredo Cardigliano return ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL); 59322e7171bSAlfredo Cardigliano } 59422e7171bSAlfredo Cardigliano 59522e7171bSAlfredo Cardigliano static int 59622e7171bSAlfredo Cardigliano ionic_dev_rss_reta_query(struct rte_eth_dev *eth_dev, 59722e7171bSAlfredo Cardigliano struct rte_eth_rss_reta_entry64 *reta_conf, 59822e7171bSAlfredo Cardigliano uint16_t reta_size) 59922e7171bSAlfredo Cardigliano { 60022e7171bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 60122e7171bSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 60222e7171bSAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 6031df32bfdSAkshay Dorwat int i, j, num; 60409f806e9SAndrew Boyer uint16_t tbl_sz = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz); 60522e7171bSAlfredo Cardigliano 60622e7171bSAlfredo Cardigliano IONIC_PRINT_CALL(); 60722e7171bSAlfredo Cardigliano 60809f806e9SAndrew Boyer if (reta_size != tbl_sz) { 60922e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "The size of hash lookup table configured " 6104ae96cb8SAndrew Boyer "(%d) does not match the number hardware can support " 61122e7171bSAlfredo Cardigliano "(%d)", 61209f806e9SAndrew Boyer reta_size, tbl_sz); 61322e7171bSAlfredo Cardigliano return -EINVAL; 61422e7171bSAlfredo Cardigliano } 61522e7171bSAlfredo Cardigliano 61622e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl) { 61722e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "RSS RETA has not been built yet"); 61822e7171bSAlfredo Cardigliano return -EINVAL; 61922e7171bSAlfredo Cardigliano } 62022e7171bSAlfredo Cardigliano 621295968d1SFerruh Yigit num = reta_size / RTE_ETH_RETA_GROUP_SIZE; 62222e7171bSAlfredo Cardigliano 62322e7171bSAlfredo Cardigliano for (i = 0; i < num; i++) { 6241df32bfdSAkshay Dorwat for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) { 6251df32bfdSAkshay Dorwat reta_conf->reta[j] = 6261df32bfdSAkshay Dorwat lif->rss_ind_tbl[(i * RTE_ETH_RETA_GROUP_SIZE) + j]; 6271df32bfdSAkshay Dorwat } 62822e7171bSAlfredo Cardigliano reta_conf++; 62922e7171bSAlfredo Cardigliano } 63022e7171bSAlfredo Cardigliano 63122e7171bSAlfredo Cardigliano return 0; 63222e7171bSAlfredo Cardigliano } 63322e7171bSAlfredo Cardigliano 63422e7171bSAlfredo Cardigliano static int 63522e7171bSAlfredo Cardigliano ionic_dev_rss_hash_conf_get(struct rte_eth_dev *eth_dev, 63622e7171bSAlfredo Cardigliano struct rte_eth_rss_conf *rss_conf) 63722e7171bSAlfredo Cardigliano { 63822e7171bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 63922e7171bSAlfredo Cardigliano uint64_t rss_hf = 0; 64022e7171bSAlfredo Cardigliano 64122e7171bSAlfredo Cardigliano IONIC_PRINT_CALL(); 64222e7171bSAlfredo Cardigliano 64322e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl) { 64422e7171bSAlfredo Cardigliano IONIC_PRINT(NOTICE, "RSS not enabled"); 64522e7171bSAlfredo Cardigliano return 0; 64622e7171bSAlfredo Cardigliano } 64722e7171bSAlfredo Cardigliano 64822e7171bSAlfredo Cardigliano /* Get key value (if not null, rss_key is 40-byte) */ 64922e7171bSAlfredo Cardigliano if (rss_conf->rss_key != NULL && 65022e7171bSAlfredo Cardigliano rss_conf->rss_key_len >= IONIC_RSS_HASH_KEY_SIZE) 65122e7171bSAlfredo Cardigliano memcpy(rss_conf->rss_key, lif->rss_hash_key, 65222e7171bSAlfredo Cardigliano IONIC_RSS_HASH_KEY_SIZE); 65322e7171bSAlfredo Cardigliano 65422e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV4) 655295968d1SFerruh Yigit rss_hf |= RTE_ETH_RSS_IPV4; 65622e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV4_TCP) 657295968d1SFerruh Yigit rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP; 65822e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV4_UDP) 659295968d1SFerruh Yigit rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP; 66022e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV6) 661295968d1SFerruh Yigit rss_hf |= RTE_ETH_RSS_IPV6; 66222e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV6_TCP) 663295968d1SFerruh Yigit rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP; 66422e7171bSAlfredo Cardigliano if (lif->rss_types & IONIC_RSS_TYPE_IPV6_UDP) 665295968d1SFerruh Yigit rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP; 66622e7171bSAlfredo Cardigliano 66722e7171bSAlfredo Cardigliano rss_conf->rss_hf = rss_hf; 66822e7171bSAlfredo Cardigliano 66922e7171bSAlfredo Cardigliano return 0; 67022e7171bSAlfredo Cardigliano } 67122e7171bSAlfredo Cardigliano 67222e7171bSAlfredo Cardigliano static int 67322e7171bSAlfredo Cardigliano ionic_dev_rss_hash_update(struct rte_eth_dev *eth_dev, 67422e7171bSAlfredo Cardigliano struct rte_eth_rss_conf *rss_conf) 67522e7171bSAlfredo Cardigliano { 67622e7171bSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 67722e7171bSAlfredo Cardigliano uint32_t rss_types = 0; 67822e7171bSAlfredo Cardigliano uint8_t *key = NULL; 67922e7171bSAlfredo Cardigliano 68022e7171bSAlfredo Cardigliano IONIC_PRINT_CALL(); 68122e7171bSAlfredo Cardigliano 68222e7171bSAlfredo Cardigliano if (rss_conf->rss_key) 68322e7171bSAlfredo Cardigliano key = rss_conf->rss_key; 68422e7171bSAlfredo Cardigliano 68522e7171bSAlfredo Cardigliano if ((rss_conf->rss_hf & IONIC_ETH_RSS_OFFLOAD_ALL) == 0) { 68622e7171bSAlfredo Cardigliano /* 68722e7171bSAlfredo Cardigliano * Can't disable rss through hash flags, 68822e7171bSAlfredo Cardigliano * if it is enabled by default during init 68922e7171bSAlfredo Cardigliano */ 69022e7171bSAlfredo Cardigliano if (lif->rss_ind_tbl) 69122e7171bSAlfredo Cardigliano return -EINVAL; 69222e7171bSAlfredo Cardigliano } else { 69322e7171bSAlfredo Cardigliano /* Can't enable rss if disabled by default during init */ 69422e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl) 69522e7171bSAlfredo Cardigliano return -EINVAL; 69622e7171bSAlfredo Cardigliano 697295968d1SFerruh Yigit if (rss_conf->rss_hf & RTE_ETH_RSS_IPV4) 69822e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV4; 699295968d1SFerruh Yigit if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) 70022e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV4_TCP; 701295968d1SFerruh Yigit if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) 70222e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV4_UDP; 703295968d1SFerruh Yigit if (rss_conf->rss_hf & RTE_ETH_RSS_IPV6) 70422e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV6; 705295968d1SFerruh Yigit if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) 70622e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV6_TCP; 707295968d1SFerruh Yigit if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) 70822e7171bSAlfredo Cardigliano rss_types |= IONIC_RSS_TYPE_IPV6_UDP; 70922e7171bSAlfredo Cardigliano 71022e7171bSAlfredo Cardigliano ionic_lif_rss_config(lif, rss_types, key, NULL); 71122e7171bSAlfredo Cardigliano } 71222e7171bSAlfredo Cardigliano 71322e7171bSAlfredo Cardigliano return 0; 71422e7171bSAlfredo Cardigliano } 71522e7171bSAlfredo Cardigliano 71622e7171bSAlfredo Cardigliano static int 7173cdfd905SAlfredo Cardigliano ionic_dev_stats_get(struct rte_eth_dev *eth_dev, 7183cdfd905SAlfredo Cardigliano struct rte_eth_stats *stats) 7193cdfd905SAlfredo Cardigliano { 7203cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 7213cdfd905SAlfredo Cardigliano 7223cdfd905SAlfredo Cardigliano ionic_lif_get_stats(lif, stats); 7233cdfd905SAlfredo Cardigliano 7243cdfd905SAlfredo Cardigliano return 0; 7253cdfd905SAlfredo Cardigliano } 7263cdfd905SAlfredo Cardigliano 7273cdfd905SAlfredo Cardigliano static int 7283cdfd905SAlfredo Cardigliano ionic_dev_stats_reset(struct rte_eth_dev *eth_dev) 7293cdfd905SAlfredo Cardigliano { 7303cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 7313cdfd905SAlfredo Cardigliano 7323cdfd905SAlfredo Cardigliano IONIC_PRINT_CALL(); 7333cdfd905SAlfredo Cardigliano 7343cdfd905SAlfredo Cardigliano ionic_lif_reset_stats(lif); 7353cdfd905SAlfredo Cardigliano 7363cdfd905SAlfredo Cardigliano return 0; 7373cdfd905SAlfredo Cardigliano } 7383cdfd905SAlfredo Cardigliano 7393cdfd905SAlfredo Cardigliano static int 7403cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_names(__rte_unused struct rte_eth_dev *eth_dev, 7413cdfd905SAlfredo Cardigliano struct rte_eth_xstat_name *xstats_names, 7423cdfd905SAlfredo Cardigliano __rte_unused unsigned int size) 7433cdfd905SAlfredo Cardigliano { 7443cdfd905SAlfredo Cardigliano unsigned int i; 7453cdfd905SAlfredo Cardigliano 7463cdfd905SAlfredo Cardigliano if (xstats_names != NULL) { 7473cdfd905SAlfredo Cardigliano for (i = 0; i < IONIC_NB_HW_STATS; i++) { 7483cdfd905SAlfredo Cardigliano snprintf(xstats_names[i].name, 7493cdfd905SAlfredo Cardigliano sizeof(xstats_names[i].name), 7503cdfd905SAlfredo Cardigliano "%s", rte_ionic_xstats_strings[i].name); 7513cdfd905SAlfredo Cardigliano } 7523cdfd905SAlfredo Cardigliano } 7533cdfd905SAlfredo Cardigliano 7543cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 7553cdfd905SAlfredo Cardigliano } 7563cdfd905SAlfredo Cardigliano 7573cdfd905SAlfredo Cardigliano static int 7583cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_names_by_id(struct rte_eth_dev *eth_dev, 7598c9f976fSAndrew Rybchenko const uint64_t *ids, struct rte_eth_xstat_name *xstats_names, 7603cdfd905SAlfredo Cardigliano unsigned int limit) 7613cdfd905SAlfredo Cardigliano { 7623cdfd905SAlfredo Cardigliano struct rte_eth_xstat_name xstats_names_copy[IONIC_NB_HW_STATS]; 7633cdfd905SAlfredo Cardigliano uint16_t i; 7643cdfd905SAlfredo Cardigliano 7653cdfd905SAlfredo Cardigliano if (!ids) { 7663cdfd905SAlfredo Cardigliano if (xstats_names != NULL) { 7673cdfd905SAlfredo Cardigliano for (i = 0; i < IONIC_NB_HW_STATS; i++) { 7683cdfd905SAlfredo Cardigliano snprintf(xstats_names[i].name, 7693cdfd905SAlfredo Cardigliano sizeof(xstats_names[i].name), 7703cdfd905SAlfredo Cardigliano "%s", rte_ionic_xstats_strings[i].name); 7713cdfd905SAlfredo Cardigliano } 7723cdfd905SAlfredo Cardigliano } 7733cdfd905SAlfredo Cardigliano 7743cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 7753cdfd905SAlfredo Cardigliano } 7763cdfd905SAlfredo Cardigliano 7778c9f976fSAndrew Rybchenko ionic_dev_xstats_get_names_by_id(eth_dev, NULL, xstats_names_copy, 7783cdfd905SAlfredo Cardigliano IONIC_NB_HW_STATS); 7793cdfd905SAlfredo Cardigliano 7803cdfd905SAlfredo Cardigliano for (i = 0; i < limit; i++) { 7813cdfd905SAlfredo Cardigliano if (ids[i] >= IONIC_NB_HW_STATS) { 7823cdfd905SAlfredo Cardigliano IONIC_PRINT(ERR, "id value isn't valid"); 7833cdfd905SAlfredo Cardigliano return -1; 7843cdfd905SAlfredo Cardigliano } 7853cdfd905SAlfredo Cardigliano 7863cdfd905SAlfredo Cardigliano strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name); 7873cdfd905SAlfredo Cardigliano } 7883cdfd905SAlfredo Cardigliano 7893cdfd905SAlfredo Cardigliano return limit; 7903cdfd905SAlfredo Cardigliano } 7913cdfd905SAlfredo Cardigliano 7923cdfd905SAlfredo Cardigliano static int 7933cdfd905SAlfredo Cardigliano ionic_dev_xstats_get(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats, 7943cdfd905SAlfredo Cardigliano unsigned int n) 7953cdfd905SAlfredo Cardigliano { 7963cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 7973cdfd905SAlfredo Cardigliano struct ionic_lif_stats hw_stats; 7983cdfd905SAlfredo Cardigliano uint16_t i; 7993cdfd905SAlfredo Cardigliano 8003cdfd905SAlfredo Cardigliano if (n < IONIC_NB_HW_STATS) 8013cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 8023cdfd905SAlfredo Cardigliano 8033cdfd905SAlfredo Cardigliano ionic_lif_get_hw_stats(lif, &hw_stats); 8043cdfd905SAlfredo Cardigliano 8053cdfd905SAlfredo Cardigliano for (i = 0; i < IONIC_NB_HW_STATS; i++) { 8063cdfd905SAlfredo Cardigliano xstats[i].value = *(uint64_t *)(((char *)&hw_stats) + 8073cdfd905SAlfredo Cardigliano rte_ionic_xstats_strings[i].offset); 8083cdfd905SAlfredo Cardigliano xstats[i].id = i; 8093cdfd905SAlfredo Cardigliano } 8103cdfd905SAlfredo Cardigliano 8113cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 8123cdfd905SAlfredo Cardigliano } 8133cdfd905SAlfredo Cardigliano 8143cdfd905SAlfredo Cardigliano static int 8153cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_by_id(struct rte_eth_dev *eth_dev, const uint64_t *ids, 8163cdfd905SAlfredo Cardigliano uint64_t *values, unsigned int n) 8173cdfd905SAlfredo Cardigliano { 8183cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 8193cdfd905SAlfredo Cardigliano struct ionic_lif_stats hw_stats; 8203cdfd905SAlfredo Cardigliano uint64_t values_copy[IONIC_NB_HW_STATS]; 8213cdfd905SAlfredo Cardigliano uint16_t i; 8223cdfd905SAlfredo Cardigliano 8233cdfd905SAlfredo Cardigliano if (!ids) { 8243cdfd905SAlfredo Cardigliano if (!ids && n < IONIC_NB_HW_STATS) 8253cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 8263cdfd905SAlfredo Cardigliano 8273cdfd905SAlfredo Cardigliano ionic_lif_get_hw_stats(lif, &hw_stats); 8283cdfd905SAlfredo Cardigliano 8293cdfd905SAlfredo Cardigliano for (i = 0; i < IONIC_NB_HW_STATS; i++) { 8303cdfd905SAlfredo Cardigliano values[i] = *(uint64_t *)(((char *)&hw_stats) + 8313cdfd905SAlfredo Cardigliano rte_ionic_xstats_strings[i].offset); 8323cdfd905SAlfredo Cardigliano } 8333cdfd905SAlfredo Cardigliano 8343cdfd905SAlfredo Cardigliano return IONIC_NB_HW_STATS; 8353cdfd905SAlfredo Cardigliano } 8363cdfd905SAlfredo Cardigliano 8373cdfd905SAlfredo Cardigliano ionic_dev_xstats_get_by_id(eth_dev, NULL, values_copy, 8383cdfd905SAlfredo Cardigliano IONIC_NB_HW_STATS); 8393cdfd905SAlfredo Cardigliano 8403cdfd905SAlfredo Cardigliano for (i = 0; i < n; i++) { 8413cdfd905SAlfredo Cardigliano if (ids[i] >= IONIC_NB_HW_STATS) { 8423cdfd905SAlfredo Cardigliano IONIC_PRINT(ERR, "id value isn't valid"); 8433cdfd905SAlfredo Cardigliano return -1; 8443cdfd905SAlfredo Cardigliano } 8453cdfd905SAlfredo Cardigliano 8463cdfd905SAlfredo Cardigliano values[i] = values_copy[ids[i]]; 8473cdfd905SAlfredo Cardigliano } 8483cdfd905SAlfredo Cardigliano 8493cdfd905SAlfredo Cardigliano return n; 8503cdfd905SAlfredo Cardigliano } 8513cdfd905SAlfredo Cardigliano 8523cdfd905SAlfredo Cardigliano static int 8533cdfd905SAlfredo Cardigliano ionic_dev_xstats_reset(struct rte_eth_dev *eth_dev) 8543cdfd905SAlfredo Cardigliano { 8553cdfd905SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 8563cdfd905SAlfredo Cardigliano 8573cdfd905SAlfredo Cardigliano ionic_lif_reset_hw_stats(lif); 8583cdfd905SAlfredo Cardigliano 8593cdfd905SAlfredo Cardigliano return 0; 8603cdfd905SAlfredo Cardigliano } 8613cdfd905SAlfredo Cardigliano 8623cdfd905SAlfredo Cardigliano static int 863598f6726SAlfredo Cardigliano ionic_dev_configure(struct rte_eth_dev *eth_dev) 864598f6726SAlfredo Cardigliano { 865598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 866598f6726SAlfredo Cardigliano 867598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 868598f6726SAlfredo Cardigliano 86918a44465SAndrew Boyer ionic_lif_configure(lif); 87018a44465SAndrew Boyer 871598f6726SAlfredo Cardigliano return 0; 872598f6726SAlfredo Cardigliano } 873598f6726SAlfredo Cardigliano 874598f6726SAlfredo Cardigliano static inline uint32_t 875598f6726SAlfredo Cardigliano ionic_parse_link_speeds(uint16_t link_speeds) 876598f6726SAlfredo Cardigliano { 877295968d1SFerruh Yigit if (link_speeds & RTE_ETH_LINK_SPEED_100G) 878598f6726SAlfredo Cardigliano return 100000; 879295968d1SFerruh Yigit else if (link_speeds & RTE_ETH_LINK_SPEED_50G) 880598f6726SAlfredo Cardigliano return 50000; 881295968d1SFerruh Yigit else if (link_speeds & RTE_ETH_LINK_SPEED_40G) 882598f6726SAlfredo Cardigliano return 40000; 883295968d1SFerruh Yigit else if (link_speeds & RTE_ETH_LINK_SPEED_25G) 884598f6726SAlfredo Cardigliano return 25000; 885295968d1SFerruh Yigit else if (link_speeds & RTE_ETH_LINK_SPEED_10G) 886598f6726SAlfredo Cardigliano return 10000; 887598f6726SAlfredo Cardigliano else 888598f6726SAlfredo Cardigliano return 0; 889598f6726SAlfredo Cardigliano } 890598f6726SAlfredo Cardigliano 891598f6726SAlfredo Cardigliano /* 892598f6726SAlfredo Cardigliano * Configure device link speed and setup link. 893598f6726SAlfredo Cardigliano * It returns 0 on success. 894598f6726SAlfredo Cardigliano */ 895598f6726SAlfredo Cardigliano static int 896598f6726SAlfredo Cardigliano ionic_dev_start(struct rte_eth_dev *eth_dev) 897598f6726SAlfredo Cardigliano { 898598f6726SAlfredo Cardigliano struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf; 899598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 900598f6726SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter; 901598f6726SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 9020dad8b3dSAndrew Boyer uint32_t speed = 0, allowed_speeds; 9030dad8b3dSAndrew Boyer uint8_t an_enable; 904598f6726SAlfredo Cardigliano int err; 905598f6726SAlfredo Cardigliano 906598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 907598f6726SAlfredo Cardigliano 908598f6726SAlfredo Cardigliano allowed_speeds = 909295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_FIXED | 910295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_10G | 911295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_25G | 912295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_40G | 913295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_50G | 914295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_100G; 915598f6726SAlfredo Cardigliano 916598f6726SAlfredo Cardigliano if (dev_conf->link_speeds & ~allowed_speeds) { 917598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Invalid link setting"); 918598f6726SAlfredo Cardigliano return -EINVAL; 919598f6726SAlfredo Cardigliano } 920598f6726SAlfredo Cardigliano 92120e577e4SAndrew Boyer if (dev_conf->lpbk_mode) 92220e577e4SAndrew Boyer IONIC_PRINT(WARNING, "Loopback mode not supported"); 92320e577e4SAndrew Boyer 924e86a6fccSAndrew Boyer /* Re-set features in case SG flag was added in rx_queue_setup() */ 925e86a6fccSAndrew Boyer err = ionic_lif_set_features(lif); 926e86a6fccSAndrew Boyer if (err) { 927e86a6fccSAndrew Boyer IONIC_PRINT(ERR, "Cannot set LIF features: %d", err); 928e86a6fccSAndrew Boyer return err; 929e86a6fccSAndrew Boyer } 930e86a6fccSAndrew Boyer 931b671e69aSAndrew Boyer lif->frame_size = eth_dev->data->mtu + IONIC_ETH_OVERHEAD; 932b671e69aSAndrew Boyer 933b671e69aSAndrew Boyer err = ionic_lif_change_mtu(lif, eth_dev->data->mtu); 934b671e69aSAndrew Boyer if (err) { 935b671e69aSAndrew Boyer IONIC_PRINT(ERR, "Cannot set LIF frame size %u: %d", 936b671e69aSAndrew Boyer lif->frame_size, err); 937b671e69aSAndrew Boyer return err; 938b671e69aSAndrew Boyer } 939b671e69aSAndrew Boyer 940598f6726SAlfredo Cardigliano err = ionic_lif_start(lif); 941598f6726SAlfredo Cardigliano if (err) { 942598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot start LIF: %d", err); 943598f6726SAlfredo Cardigliano return err; 944598f6726SAlfredo Cardigliano } 945598f6726SAlfredo Cardigliano 9460dad8b3dSAndrew Boyer /* Configure link */ 947295968d1SFerruh Yigit an_enable = (dev_conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) == 0; 948598f6726SAlfredo Cardigliano 9490dad8b3dSAndrew Boyer ionic_dev_cmd_port_autoneg(idev, an_enable); 9500dad8b3dSAndrew Boyer err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 9510dad8b3dSAndrew Boyer if (err) 9520dad8b3dSAndrew Boyer IONIC_PRINT(WARNING, "Failed to %s autonegotiation", 9530dad8b3dSAndrew Boyer an_enable ? "enable" : "disable"); 9540dad8b3dSAndrew Boyer 9550dad8b3dSAndrew Boyer if (!an_enable) 9560dad8b3dSAndrew Boyer speed = ionic_parse_link_speeds(dev_conf->link_speeds); 9570dad8b3dSAndrew Boyer if (speed) { 958598f6726SAlfredo Cardigliano ionic_dev_cmd_port_speed(idev, speed); 9590dad8b3dSAndrew Boyer err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 9600dad8b3dSAndrew Boyer if (err) 9610dad8b3dSAndrew Boyer IONIC_PRINT(WARNING, "Failed to set link speed %u", 9620dad8b3dSAndrew Boyer speed); 963598f6726SAlfredo Cardigliano } 964598f6726SAlfredo Cardigliano 965e86a6fccSAndrew Boyer if (lif->hw_features & IONIC_ETH_HW_RX_SG) 966e86a6fccSAndrew Boyer eth_dev->rx_pkt_burst = &ionic_recv_pkts_sg; 967e86a6fccSAndrew Boyer else 968e86a6fccSAndrew Boyer eth_dev->rx_pkt_burst = &ionic_recv_pkts; 969e86a6fccSAndrew Boyer 970e86a6fccSAndrew Boyer if (lif->hw_features & IONIC_ETH_HW_TX_SG) 971e86a6fccSAndrew Boyer eth_dev->tx_pkt_burst = &ionic_xmit_pkts_sg; 972e86a6fccSAndrew Boyer else 973e86a6fccSAndrew Boyer eth_dev->tx_pkt_burst = &ionic_xmit_pkts; 974e86a6fccSAndrew Boyer 975e86a6fccSAndrew Boyer eth_dev->tx_pkt_prepare = &ionic_prep_pkts; 976e86a6fccSAndrew Boyer 977598f6726SAlfredo Cardigliano ionic_dev_link_update(eth_dev, 0); 978598f6726SAlfredo Cardigliano 979598f6726SAlfredo Cardigliano return 0; 980598f6726SAlfredo Cardigliano } 981598f6726SAlfredo Cardigliano 982598f6726SAlfredo Cardigliano /* 983598f6726SAlfredo Cardigliano * Stop device: disable rx and tx functions to allow for reconfiguring. 984598f6726SAlfredo Cardigliano */ 98562024eb8SIvan Ilchenko static int 986598f6726SAlfredo Cardigliano ionic_dev_stop(struct rte_eth_dev *eth_dev) 987598f6726SAlfredo Cardigliano { 988598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 989598f6726SAlfredo Cardigliano 990598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 991598f6726SAlfredo Cardigliano 992be63459eSAndrew Boyer ionic_lif_stop(lif); 99362024eb8SIvan Ilchenko 994be63459eSAndrew Boyer return 0; 995598f6726SAlfredo Cardigliano } 996598f6726SAlfredo Cardigliano 997598f6726SAlfredo Cardigliano /* 998598f6726SAlfredo Cardigliano * Reset and stop device. 999598f6726SAlfredo Cardigliano */ 1000b142387bSThomas Monjalon static int 1001598f6726SAlfredo Cardigliano ionic_dev_close(struct rte_eth_dev *eth_dev) 1002598f6726SAlfredo Cardigliano { 1003598f6726SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 1004175e4e7eSAndrew Boyer struct ionic_adapter *adapter = lif->adapter; 1005598f6726SAlfredo Cardigliano 1006598f6726SAlfredo Cardigliano IONIC_PRINT_CALL(); 100730410493SThomas Monjalon if (rte_eal_process_type() != RTE_PROC_PRIMARY) 100830410493SThomas Monjalon return 0; 1009598f6726SAlfredo Cardigliano 1010be63459eSAndrew Boyer ionic_lif_stop(lif); 1011598f6726SAlfredo Cardigliano 1012175e4e7eSAndrew Boyer IONIC_PRINT(NOTICE, "Removing device %s", eth_dev->device->name); 10138eaafff3SAndrew Boyer if (adapter->intf->unconfigure_intr) 10148eaafff3SAndrew Boyer (*adapter->intf->unconfigure_intr)(adapter); 1015175e4e7eSAndrew Boyer 1016175e4e7eSAndrew Boyer ionic_port_reset(adapter); 1017175e4e7eSAndrew Boyer ionic_reset(adapter); 1018*73028be3SAndrew Boyer 1019*73028be3SAndrew Boyer ionic_lif_free_queues(lif); 1020*73028be3SAndrew Boyer ionic_lif_deinit(lif); 1021*73028be3SAndrew Boyer ionic_lif_free(lif); /* Does not free LIF object */ 1022*73028be3SAndrew Boyer 10238eaafff3SAndrew Boyer if (adapter->intf->unmap_bars) 10248eaafff3SAndrew Boyer (*adapter->intf->unmap_bars)(adapter); 1025175e4e7eSAndrew Boyer 1026*73028be3SAndrew Boyer lif->adapter = NULL; 1027175e4e7eSAndrew Boyer rte_free(adapter); 1028b142387bSThomas Monjalon 1029b142387bSThomas Monjalon return 0; 1030598f6726SAlfredo Cardigliano } 1031598f6726SAlfredo Cardigliano 10328eaafff3SAndrew Boyer int 1033669c8de6SAlfredo Cardigliano eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params) 1034669c8de6SAlfredo Cardigliano { 1035669c8de6SAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); 1036669c8de6SAlfredo Cardigliano struct ionic_adapter *adapter = (struct ionic_adapter *)init_params; 1037669c8de6SAlfredo Cardigliano int err; 1038669c8de6SAlfredo Cardigliano 1039669c8de6SAlfredo Cardigliano IONIC_PRINT_CALL(); 1040669c8de6SAlfredo Cardigliano 1041669c8de6SAlfredo Cardigliano eth_dev->dev_ops = &ionic_eth_dev_ops; 10420983a74aSAndrew Boyer eth_dev->rx_descriptor_status = ionic_dev_rx_descriptor_status; 104360625147SAndrew Boyer eth_dev->tx_descriptor_status = ionic_dev_tx_descriptor_status; 10440983a74aSAndrew Boyer 1045669c8de6SAlfredo Cardigliano /* Multi-process not supported, primary does initialization anyway */ 1046669c8de6SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1047669c8de6SAlfredo Cardigliano return 0; 1048669c8de6SAlfredo Cardigliano 10498eaafff3SAndrew Boyer if (adapter->intf->copy_bus_info) 10508eaafff3SAndrew Boyer (*adapter->intf->copy_bus_info)(adapter, eth_dev); 1051f30e69b4SFerruh Yigit eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 1052669c8de6SAlfredo Cardigliano 1053669c8de6SAlfredo Cardigliano lif->eth_dev = eth_dev; 1054669c8de6SAlfredo Cardigliano lif->adapter = adapter; 105500b65da5SAndrew Boyer adapter->lif = lif; 1056669c8de6SAlfredo Cardigliano 1057598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Up to %u MAC addresses supported", 1058598f6726SAlfredo Cardigliano adapter->max_mac_addrs); 1059598f6726SAlfredo Cardigliano 1060598f6726SAlfredo Cardigliano /* Allocate memory for storing MAC addresses */ 1061c663c7ecSAndrew Boyer eth_dev->data->mac_addrs = rte_calloc("ionic", 1062c663c7ecSAndrew Boyer adapter->max_mac_addrs, 1063c5d0bb79SAndrew Boyer RTE_ETHER_ADDR_LEN, 1064c5d0bb79SAndrew Boyer RTE_CACHE_LINE_SIZE); 1065598f6726SAlfredo Cardigliano if (eth_dev->data->mac_addrs == NULL) { 1066598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Failed to allocate %u bytes needed to " 1067598f6726SAlfredo Cardigliano "store MAC addresses", 1068598f6726SAlfredo Cardigliano RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs); 1069598f6726SAlfredo Cardigliano err = -ENOMEM; 1070598f6726SAlfredo Cardigliano goto err; 1071598f6726SAlfredo Cardigliano } 1072598f6726SAlfredo Cardigliano 1073669c8de6SAlfredo Cardigliano err = ionic_lif_alloc(lif); 1074669c8de6SAlfredo Cardigliano if (err) { 1075669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate LIFs: %d, aborting", 1076669c8de6SAlfredo Cardigliano err); 1077669c8de6SAlfredo Cardigliano goto err; 1078669c8de6SAlfredo Cardigliano } 1079669c8de6SAlfredo Cardigliano 1080669c8de6SAlfredo Cardigliano err = ionic_lif_init(lif); 1081669c8de6SAlfredo Cardigliano if (err) { 1082669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init LIFs: %d, aborting", err); 1083669c8de6SAlfredo Cardigliano goto err_free_lif; 1084669c8de6SAlfredo Cardigliano } 1085669c8de6SAlfredo Cardigliano 1086598f6726SAlfredo Cardigliano /* Copy the MAC address */ 1087598f6726SAlfredo Cardigliano rte_ether_addr_copy((struct rte_ether_addr *)lif->mac_addr, 1088598f6726SAlfredo Cardigliano ð_dev->data->mac_addrs[0]); 1089598f6726SAlfredo Cardigliano 1090669c8de6SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Port %u initialized", eth_dev->data->port_id); 1091669c8de6SAlfredo Cardigliano 1092669c8de6SAlfredo Cardigliano return 0; 1093669c8de6SAlfredo Cardigliano 1094669c8de6SAlfredo Cardigliano err_free_lif: 1095669c8de6SAlfredo Cardigliano ionic_lif_free(lif); 1096669c8de6SAlfredo Cardigliano err: 1097669c8de6SAlfredo Cardigliano return err; 1098669c8de6SAlfredo Cardigliano } 1099669c8de6SAlfredo Cardigliano 1100669c8de6SAlfredo Cardigliano static int 1101669c8de6SAlfredo Cardigliano eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev) 1102669c8de6SAlfredo Cardigliano { 1103669c8de6SAlfredo Cardigliano IONIC_PRINT_CALL(); 1104669c8de6SAlfredo Cardigliano 1105669c8de6SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1106669c8de6SAlfredo Cardigliano return 0; 1107669c8de6SAlfredo Cardigliano 1108*73028be3SAndrew Boyer if (eth_dev->state != RTE_ETH_DEV_UNUSED) 1109*73028be3SAndrew Boyer ionic_dev_close(eth_dev); 1110669c8de6SAlfredo Cardigliano 1111*73028be3SAndrew Boyer eth_dev->dev_ops = NULL; 1112*73028be3SAndrew Boyer eth_dev->rx_pkt_burst = NULL; 1113*73028be3SAndrew Boyer eth_dev->tx_pkt_burst = NULL; 1114*73028be3SAndrew Boyer eth_dev->tx_pkt_prepare = NULL; 1115be63459eSAndrew Boyer 1116669c8de6SAlfredo Cardigliano return 0; 1117669c8de6SAlfredo Cardigliano } 1118669c8de6SAlfredo Cardigliano 11198eaafff3SAndrew Boyer int 11208eaafff3SAndrew Boyer eth_ionic_dev_probe(void *bus_dev, struct rte_device *rte_dev, 11218eaafff3SAndrew Boyer struct ionic_bars *bars, const struct ionic_dev_intf *intf, 11228eaafff3SAndrew Boyer uint16_t device_id, uint16_t vendor_id) 11235ef51809SAlfredo Cardigliano { 1124669c8de6SAlfredo Cardigliano char name[RTE_ETH_NAME_MAX_LEN]; 11255ef51809SAlfredo Cardigliano struct ionic_adapter *adapter; 11265ef51809SAlfredo Cardigliano struct ionic_hw *hw; 11275ef51809SAlfredo Cardigliano unsigned long i; 11285ef51809SAlfredo Cardigliano int err; 11295ef51809SAlfredo Cardigliano 11305ef51809SAlfredo Cardigliano /* Check structs (trigger error at compilation time) */ 11315ef51809SAlfredo Cardigliano ionic_struct_size_checks(); 11325ef51809SAlfredo Cardigliano 11335ef51809SAlfredo Cardigliano /* Multi-process not supported */ 11345ef51809SAlfredo Cardigliano if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 11355ef51809SAlfredo Cardigliano err = -EPERM; 11365ef51809SAlfredo Cardigliano goto err; 11375ef51809SAlfredo Cardigliano } 11385ef51809SAlfredo Cardigliano 1139c5d0bb79SAndrew Boyer adapter = rte_zmalloc("ionic", sizeof(*adapter), RTE_CACHE_LINE_SIZE); 11405ef51809SAlfredo Cardigliano if (!adapter) { 11415ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "OOM"); 11425ef51809SAlfredo Cardigliano err = -ENOMEM; 11435ef51809SAlfredo Cardigliano goto err; 11445ef51809SAlfredo Cardigliano } 11455ef51809SAlfredo Cardigliano 11468eaafff3SAndrew Boyer adapter->bus_dev = bus_dev; 11475ef51809SAlfredo Cardigliano hw = &adapter->hw; 11485ef51809SAlfredo Cardigliano 11498eaafff3SAndrew Boyer /* Vendor and Device ID need to be set before init of shared code */ 11508eaafff3SAndrew Boyer hw->device_id = device_id; 11518eaafff3SAndrew Boyer hw->vendor_id = vendor_id; 11525ef51809SAlfredo Cardigliano 11535ef51809SAlfredo Cardigliano err = ionic_init_mac(hw); 11545ef51809SAlfredo Cardigliano if (err != 0) { 11555ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Mac init failed: %d", err); 11565ef51809SAlfredo Cardigliano err = -EIO; 11575ef51809SAlfredo Cardigliano goto err_free_adapter; 11585ef51809SAlfredo Cardigliano } 11595ef51809SAlfredo Cardigliano 11608eaafff3SAndrew Boyer adapter->bars.num_bars = bars->num_bars; 11618eaafff3SAndrew Boyer for (i = 0; i < bars->num_bars; i++) { 11628eaafff3SAndrew Boyer adapter->bars.bar[i].vaddr = bars->bar[i].vaddr; 11638eaafff3SAndrew Boyer adapter->bars.bar[i].bus_addr = bars->bar[i].bus_addr; 11648eaafff3SAndrew Boyer adapter->bars.bar[i].len = bars->bar[i].len; 11655ef51809SAlfredo Cardigliano } 11665ef51809SAlfredo Cardigliano 11678eaafff3SAndrew Boyer if (intf->setup == NULL) { 11688eaafff3SAndrew Boyer IONIC_PRINT(ERR, "Device setup function is mandatory"); 11698eaafff3SAndrew Boyer goto err_free_adapter; 11708eaafff3SAndrew Boyer } 11715ef51809SAlfredo Cardigliano 11728eaafff3SAndrew Boyer adapter->intf = intf; 11738eaafff3SAndrew Boyer 11749de21005SAndrew Boyer /* Parse device arguments */ 11759de21005SAndrew Boyer if (adapter->intf->devargs) { 11769de21005SAndrew Boyer err = (*adapter->intf->devargs)(adapter, rte_dev->devargs); 11779de21005SAndrew Boyer if (err) { 11789de21005SAndrew Boyer IONIC_PRINT(ERR, "Cannot parse device arguments"); 11799de21005SAndrew Boyer goto err_free_adapter; 11809de21005SAndrew Boyer } 11819de21005SAndrew Boyer } 11829de21005SAndrew Boyer 11838eaafff3SAndrew Boyer /* Discover ionic dev resources */ 11845ef51809SAlfredo Cardigliano err = ionic_setup(adapter); 11855ef51809SAlfredo Cardigliano if (err) { 11865ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot setup device: %d, aborting", err); 11875ef51809SAlfredo Cardigliano goto err_free_adapter; 11885ef51809SAlfredo Cardigliano } 11895ef51809SAlfredo Cardigliano 11905ef51809SAlfredo Cardigliano err = ionic_identify(adapter); 11915ef51809SAlfredo Cardigliano if (err) { 11925ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify device: %d, aborting", 11935ef51809SAlfredo Cardigliano err); 11945ef51809SAlfredo Cardigliano goto err_free_adapter; 11955ef51809SAlfredo Cardigliano } 11965ef51809SAlfredo Cardigliano 11975ef51809SAlfredo Cardigliano err = ionic_init(adapter); 11985ef51809SAlfredo Cardigliano if (err) { 11995ef51809SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init device: %d, aborting", err); 12005ef51809SAlfredo Cardigliano goto err_free_adapter; 12015ef51809SAlfredo Cardigliano } 12025ef51809SAlfredo Cardigliano 120323bf4ddbSAlfredo Cardigliano /* Configure the ports */ 120423bf4ddbSAlfredo Cardigliano err = ionic_port_identify(adapter); 120523bf4ddbSAlfredo Cardigliano if (err) { 120623bf4ddbSAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify port: %d, aborting", 120723bf4ddbSAlfredo Cardigliano err); 120823bf4ddbSAlfredo Cardigliano goto err_free_adapter; 120923bf4ddbSAlfredo Cardigliano } 121023bf4ddbSAlfredo Cardigliano 121123bf4ddbSAlfredo Cardigliano err = ionic_port_init(adapter); 121223bf4ddbSAlfredo Cardigliano if (err) { 121323bf4ddbSAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot init port: %d, aborting", err); 121423bf4ddbSAlfredo Cardigliano goto err_free_adapter; 121523bf4ddbSAlfredo Cardigliano } 121623bf4ddbSAlfredo Cardigliano 1217669c8de6SAlfredo Cardigliano /* Configure LIFs */ 1218669c8de6SAlfredo Cardigliano err = ionic_lif_identify(adapter); 1219669c8de6SAlfredo Cardigliano if (err) { 1220669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot identify lif: %d, aborting", err); 1221669c8de6SAlfredo Cardigliano goto err_free_adapter; 1222669c8de6SAlfredo Cardigliano } 1223669c8de6SAlfredo Cardigliano 1224669c8de6SAlfredo Cardigliano /* Allocate and init LIFs */ 1225669c8de6SAlfredo Cardigliano err = ionic_lifs_size(adapter); 1226669c8de6SAlfredo Cardigliano if (err) { 1227669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot size LIFs: %d, aborting", err); 1228669c8de6SAlfredo Cardigliano goto err_free_adapter; 1229669c8de6SAlfredo Cardigliano } 1230669c8de6SAlfredo Cardigliano 123109f806e9SAndrew Boyer adapter->max_mac_addrs = 123209f806e9SAndrew Boyer rte_le_to_cpu_32(adapter->ident.lif.eth.max_ucast_filters); 1233598f6726SAlfredo Cardigliano 123409f806e9SAndrew Boyer if (rte_le_to_cpu_32(adapter->ident.dev.nlifs) != 1) { 123500b65da5SAndrew Boyer IONIC_PRINT(ERR, "Unexpected request for %d LIFs", 123609f806e9SAndrew Boyer rte_le_to_cpu_32(adapter->ident.dev.nlifs)); 123700b65da5SAndrew Boyer goto err_free_adapter; 1238669c8de6SAlfredo Cardigliano } 1239669c8de6SAlfredo Cardigliano 12408eaafff3SAndrew Boyer snprintf(name, sizeof(name), "%s_lif", rte_dev->name); 12418eaafff3SAndrew Boyer err = rte_eth_dev_create(rte_dev, name, sizeof(struct ionic_lif), 124200b65da5SAndrew Boyer NULL, NULL, eth_ionic_dev_init, adapter); 124300b65da5SAndrew Boyer if (err) { 124400b65da5SAndrew Boyer IONIC_PRINT(ERR, "Cannot create eth device for %s", name); 124500b65da5SAndrew Boyer goto err_free_adapter; 1246669c8de6SAlfredo Cardigliano } 1247669c8de6SAlfredo Cardigliano 12488eaafff3SAndrew Boyer if (adapter->intf->configure_intr) { 12498eaafff3SAndrew Boyer err = (*adapter->intf->configure_intr)(adapter); 125027b942c8SAlfredo Cardigliano if (err) { 125127b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Failed to configure interrupts"); 125227b942c8SAlfredo Cardigliano goto err_free_adapter; 125327b942c8SAlfredo Cardigliano } 12548eaafff3SAndrew Boyer } 125527b942c8SAlfredo Cardigliano 12565ef51809SAlfredo Cardigliano return 0; 12575ef51809SAlfredo Cardigliano 12585ef51809SAlfredo Cardigliano err_free_adapter: 12595ef51809SAlfredo Cardigliano rte_free(adapter); 12605ef51809SAlfredo Cardigliano err: 12615ef51809SAlfredo Cardigliano return err; 12625ef51809SAlfredo Cardigliano } 12635ef51809SAlfredo Cardigliano 12648eaafff3SAndrew Boyer int 12658eaafff3SAndrew Boyer eth_ionic_dev_remove(struct rte_device *rte_dev) 12665ef51809SAlfredo Cardigliano { 1267669c8de6SAlfredo Cardigliano char name[RTE_ETH_NAME_MAX_LEN]; 1268669c8de6SAlfredo Cardigliano struct rte_eth_dev *eth_dev; 1269*73028be3SAndrew Boyer int ret = 0; 1270669c8de6SAlfredo Cardigliano 127100b65da5SAndrew Boyer /* Adapter lookup is using the eth_dev name */ 12728eaafff3SAndrew Boyer snprintf(name, sizeof(name), "%s_lif", rte_dev->name); 1273669c8de6SAlfredo Cardigliano 1274669c8de6SAlfredo Cardigliano eth_dev = rte_eth_dev_allocated(name); 1275175e4e7eSAndrew Boyer if (eth_dev) 1276*73028be3SAndrew Boyer ret = rte_eth_dev_destroy(eth_dev, eth_ionic_dev_uninit); 1277175e4e7eSAndrew Boyer else 12788eaafff3SAndrew Boyer IONIC_PRINT(DEBUG, "Cannot find device %s", rte_dev->name); 1279669c8de6SAlfredo Cardigliano 1280*73028be3SAndrew Boyer return ret; 12815ef51809SAlfredo Cardigliano } 12825ef51809SAlfredo Cardigliano 1283eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(ionic_logtype, NOTICE); 1284