13126df22SRasesh Mody /* SPDX-License-Identifier: BSD-3-Clause 29adde217SRasesh Mody * Copyright (c) 2016 - 2018 Cavium Inc. 32ea6f76aSRasesh Mody * All rights reserved. 49adde217SRasesh Mody * www.cavium.com 52ea6f76aSRasesh Mody */ 62ea6f76aSRasesh Mody 72ea6f76aSRasesh Mody #include "qede_ethdev.h" 86723c0fcSBruce Richardson #include <rte_string_fns.h> 92af14ca7SHarish Patil #include <rte_alarm.h> 107eca78ceSHarish Patil #include <rte_version.h> 11f64b91b0SRasesh Mody #include <rte_kvargs.h> 122ea6f76aSRasesh Mody 132ea6f76aSRasesh Mody /* Globals */ 1469b65739SStephen Hemminger int qede_logtype_init; 1569b65739SStephen Hemminger int qede_logtype_driver; 1669b65739SStephen Hemminger 172ea6f76aSRasesh Mody static const struct qed_eth_ops *qed_ops; 18ad4d092bSShahed Shaikh static int qede_eth_dev_uninit(struct rte_eth_dev *eth_dev); 19ad4d092bSShahed Shaikh static int qede_eth_dev_init(struct rte_eth_dev *eth_dev); 20ad4d092bSShahed Shaikh 210833120fSShahed Shaikh #define QEDE_SP_TIMER_PERIOD 10000 /* 100ms */ 222ea6f76aSRasesh Mody 23d1216e22SRasesh Mody struct rte_qede_xstats_name_off { 24d1216e22SRasesh Mody char name[RTE_ETH_XSTATS_NAME_SIZE]; 25d1216e22SRasesh Mody uint64_t offset; 26d1216e22SRasesh Mody }; 27d1216e22SRasesh Mody 28d1216e22SRasesh Mody static const struct rte_qede_xstats_name_off qede_xstats_strings[] = { 299c1aa3e1SRasesh Mody {"rx_unicast_bytes", 309c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_ucast_bytes)}, 31d1216e22SRasesh Mody {"rx_multicast_bytes", 329c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mcast_bytes)}, 33d1216e22SRasesh Mody {"rx_broadcast_bytes", 349c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_bcast_bytes)}, 359c1aa3e1SRasesh Mody {"rx_unicast_packets", 369c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_ucast_pkts)}, 37d1216e22SRasesh Mody {"rx_multicast_packets", 389c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mcast_pkts)}, 39d1216e22SRasesh Mody {"rx_broadcast_packets", 409c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_bcast_pkts)}, 41d1216e22SRasesh Mody 429c1aa3e1SRasesh Mody {"tx_unicast_bytes", 439c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_ucast_bytes)}, 44d1216e22SRasesh Mody {"tx_multicast_bytes", 459c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mcast_bytes)}, 46d1216e22SRasesh Mody {"tx_broadcast_bytes", 479c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_bcast_bytes)}, 489c1aa3e1SRasesh Mody {"tx_unicast_packets", 499c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_ucast_pkts)}, 50d1216e22SRasesh Mody {"tx_multicast_packets", 519c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mcast_pkts)}, 52d1216e22SRasesh Mody {"tx_broadcast_packets", 539c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_bcast_pkts)}, 54d1216e22SRasesh Mody 55d1216e22SRasesh Mody {"rx_64_byte_packets", 569c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_64_byte_packets)}, 57d1216e22SRasesh Mody {"rx_65_to_127_byte_packets", 589c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 599c1aa3e1SRasesh Mody rx_65_to_127_byte_packets)}, 60d1216e22SRasesh Mody {"rx_128_to_255_byte_packets", 619c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 629c1aa3e1SRasesh Mody rx_128_to_255_byte_packets)}, 63d1216e22SRasesh Mody {"rx_256_to_511_byte_packets", 649c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 659c1aa3e1SRasesh Mody rx_256_to_511_byte_packets)}, 66d1216e22SRasesh Mody {"rx_512_to_1023_byte_packets", 679c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 689c1aa3e1SRasesh Mody rx_512_to_1023_byte_packets)}, 69d1216e22SRasesh Mody {"rx_1024_to_1518_byte_packets", 709c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 719c1aa3e1SRasesh Mody rx_1024_to_1518_byte_packets)}, 72d1216e22SRasesh Mody {"tx_64_byte_packets", 739c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_64_byte_packets)}, 74d1216e22SRasesh Mody {"tx_65_to_127_byte_packets", 759c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 769c1aa3e1SRasesh Mody tx_65_to_127_byte_packets)}, 77d1216e22SRasesh Mody {"tx_128_to_255_byte_packets", 789c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 799c1aa3e1SRasesh Mody tx_128_to_255_byte_packets)}, 80d1216e22SRasesh Mody {"tx_256_to_511_byte_packets", 819c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 829c1aa3e1SRasesh Mody tx_256_to_511_byte_packets)}, 83d1216e22SRasesh Mody {"tx_512_to_1023_byte_packets", 849c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 859c1aa3e1SRasesh Mody tx_512_to_1023_byte_packets)}, 86d1216e22SRasesh Mody {"tx_1024_to_1518_byte_packets", 879c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 889c1aa3e1SRasesh Mody tx_1024_to_1518_byte_packets)}, 89d1216e22SRasesh Mody 90d1216e22SRasesh Mody {"rx_mac_crtl_frames", 919c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_crtl_frames)}, 92d1216e22SRasesh Mody {"tx_mac_control_frames", 939c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mac_ctrl_frames)}, 949c1aa3e1SRasesh Mody {"rx_pause_frames", 959c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_pause_frames)}, 969c1aa3e1SRasesh Mody {"tx_pause_frames", 979c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_pause_frames)}, 98d1216e22SRasesh Mody {"rx_priority_flow_control_frames", 999c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_pfc_frames)}, 100d1216e22SRasesh Mody {"tx_priority_flow_control_frames", 1019c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_pfc_frames)}, 102d1216e22SRasesh Mody 1039c1aa3e1SRasesh Mody {"rx_crc_errors", 1049c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_crc_errors)}, 1059c1aa3e1SRasesh Mody {"rx_align_errors", 1069c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_align_errors)}, 107d1216e22SRasesh Mody {"rx_carrier_errors", 1089c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_carrier_errors)}, 109d1216e22SRasesh Mody {"rx_oversize_packet_errors", 1109c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_oversize_packets)}, 1119c1aa3e1SRasesh Mody {"rx_jabber_errors", 1129c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_jabbers)}, 113d1216e22SRasesh Mody {"rx_undersize_packet_errors", 1149c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_undersize_packets)}, 1159c1aa3e1SRasesh Mody {"rx_fragments", offsetof(struct ecore_eth_stats_common, rx_fragments)}, 116d1216e22SRasesh Mody {"rx_host_buffer_not_available", 1179c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, no_buff_discards)}, 118d1216e22SRasesh Mody /* Number of packets discarded because they are bigger than MTU */ 119d1216e22SRasesh Mody {"rx_packet_too_big_discards", 1209c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 1219c1aa3e1SRasesh Mody packet_too_big_discard)}, 122d1216e22SRasesh Mody {"rx_ttl_zero_discards", 1239c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, ttl0_discard)}, 124d1216e22SRasesh Mody {"rx_multi_function_tag_filter_discards", 1259c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, mftag_filter_discards)}, 126d1216e22SRasesh Mody {"rx_mac_filter_discards", 1279c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, mac_filter_discards)}, 1282c0784ebSShahed Shaikh {"rx_gft_filter_drop", 1292c0784ebSShahed Shaikh offsetof(struct ecore_eth_stats_common, gft_filter_drop)}, 130d1216e22SRasesh Mody {"rx_hw_buffer_truncates", 1319c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, brb_truncates)}, 132d1216e22SRasesh Mody {"rx_hw_buffer_discards", 1339c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, brb_discards)}, 134d1216e22SRasesh Mody {"tx_error_drop_packets", 1359c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_err_drop_pkts)}, 136d1216e22SRasesh Mody 1379c1aa3e1SRasesh Mody {"rx_mac_bytes", offsetof(struct ecore_eth_stats_common, rx_mac_bytes)}, 138d1216e22SRasesh Mody {"rx_mac_unicast_packets", 1399c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_uc_packets)}, 140d1216e22SRasesh Mody {"rx_mac_multicast_packets", 1419c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_mc_packets)}, 142d1216e22SRasesh Mody {"rx_mac_broadcast_packets", 1439c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_bc_packets)}, 144d1216e22SRasesh Mody {"rx_mac_frames_ok", 1459c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_frames_ok)}, 1469c1aa3e1SRasesh Mody {"tx_mac_bytes", offsetof(struct ecore_eth_stats_common, tx_mac_bytes)}, 147d1216e22SRasesh Mody {"tx_mac_unicast_packets", 1489c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mac_uc_packets)}, 149d1216e22SRasesh Mody {"tx_mac_multicast_packets", 1509c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mac_mc_packets)}, 151d1216e22SRasesh Mody {"tx_mac_broadcast_packets", 1529c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mac_bc_packets)}, 153d1216e22SRasesh Mody 154d1216e22SRasesh Mody {"lro_coalesced_packets", 1559c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tpa_coalesced_pkts)}, 156d1216e22SRasesh Mody {"lro_coalesced_events", 1579c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tpa_coalesced_events)}, 158d1216e22SRasesh Mody {"lro_aborts_num", 1599c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tpa_aborts_num)}, 160d1216e22SRasesh Mody {"lro_not_coalesced_packets", 1619c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 1629c1aa3e1SRasesh Mody tpa_not_coalesced_pkts)}, 163d1216e22SRasesh Mody {"lro_coalesced_bytes", 1649c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 1659c1aa3e1SRasesh Mody tpa_coalesced_bytes)}, 1669c1aa3e1SRasesh Mody }; 1679c1aa3e1SRasesh Mody 1689c1aa3e1SRasesh Mody static const struct rte_qede_xstats_name_off qede_bb_xstats_strings[] = { 1699c1aa3e1SRasesh Mody {"rx_1519_to_1522_byte_packets", 1709c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1719c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1729c1aa3e1SRasesh Mody rx_1519_to_1522_byte_packets)}, 1739c1aa3e1SRasesh Mody {"rx_1519_to_2047_byte_packets", 1749c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1759c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1769c1aa3e1SRasesh Mody rx_1519_to_2047_byte_packets)}, 1779c1aa3e1SRasesh Mody {"rx_2048_to_4095_byte_packets", 1789c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1799c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1809c1aa3e1SRasesh Mody rx_2048_to_4095_byte_packets)}, 1819c1aa3e1SRasesh Mody {"rx_4096_to_9216_byte_packets", 1829c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1839c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1849c1aa3e1SRasesh Mody rx_4096_to_9216_byte_packets)}, 1859c1aa3e1SRasesh Mody {"rx_9217_to_16383_byte_packets", 1869c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1879c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1889c1aa3e1SRasesh Mody rx_9217_to_16383_byte_packets)}, 1899c1aa3e1SRasesh Mody 1909c1aa3e1SRasesh Mody {"tx_1519_to_2047_byte_packets", 1919c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1929c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1939c1aa3e1SRasesh Mody tx_1519_to_2047_byte_packets)}, 1949c1aa3e1SRasesh Mody {"tx_2048_to_4095_byte_packets", 1959c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1969c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1979c1aa3e1SRasesh Mody tx_2048_to_4095_byte_packets)}, 1989c1aa3e1SRasesh Mody {"tx_4096_to_9216_byte_packets", 1999c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 2009c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 2019c1aa3e1SRasesh Mody tx_4096_to_9216_byte_packets)}, 2029c1aa3e1SRasesh Mody {"tx_9217_to_16383_byte_packets", 2039c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 2049c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 2059c1aa3e1SRasesh Mody tx_9217_to_16383_byte_packets)}, 2069c1aa3e1SRasesh Mody 2079c1aa3e1SRasesh Mody {"tx_lpi_entry_count", 2089c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 2099c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, tx_lpi_entry_count)}, 2109c1aa3e1SRasesh Mody {"tx_total_collisions", 2119c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 2129c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, tx_total_collisions)}, 2139c1aa3e1SRasesh Mody }; 2149c1aa3e1SRasesh Mody 2159c1aa3e1SRasesh Mody static const struct rte_qede_xstats_name_off qede_ah_xstats_strings[] = { 2169c1aa3e1SRasesh Mody {"rx_1519_to_max_byte_packets", 2179c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, ah) + 2189c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_ah, 2199c1aa3e1SRasesh Mody rx_1519_to_max_byte_packets)}, 2209c1aa3e1SRasesh Mody {"tx_1519_to_max_byte_packets", 2219c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, ah) + 2229c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_ah, 2239c1aa3e1SRasesh Mody tx_1519_to_max_byte_packets)}, 224d1216e22SRasesh Mody }; 225d1216e22SRasesh Mody 2267634c5f9SRasesh Mody static const struct rte_qede_xstats_name_off qede_rxq_xstats_strings[] = { 2277634c5f9SRasesh Mody {"rx_q_segments", 2287634c5f9SRasesh Mody offsetof(struct qede_rx_queue, rx_segs)}, 2297634c5f9SRasesh Mody {"rx_q_hw_errors", 2307634c5f9SRasesh Mody offsetof(struct qede_rx_queue, rx_hw_errors)}, 2317634c5f9SRasesh Mody {"rx_q_allocation_errors", 2327634c5f9SRasesh Mody offsetof(struct qede_rx_queue, rx_alloc_errors)} 2337634c5f9SRasesh Mody }; 2347634c5f9SRasesh Mody 2352ea6f76aSRasesh Mody static void qede_interrupt_action(struct ecore_hwfn *p_hwfn) 2362ea6f76aSRasesh Mody { 2372ea6f76aSRasesh Mody ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn)); 2382ea6f76aSRasesh Mody } 2392ea6f76aSRasesh Mody 2402ea6f76aSRasesh Mody static void 241245aec28SShahed Shaikh qede_interrupt_handler_intx(void *param) 242245aec28SShahed Shaikh { 243245aec28SShahed Shaikh struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 244245aec28SShahed Shaikh struct qede_dev *qdev = eth_dev->data->dev_private; 245245aec28SShahed Shaikh struct ecore_dev *edev = &qdev->edev; 246245aec28SShahed Shaikh u64 status; 247245aec28SShahed Shaikh 248245aec28SShahed Shaikh /* Check if our device actually raised an interrupt */ 249245aec28SShahed Shaikh status = ecore_int_igu_read_sisr_reg(ECORE_LEADING_HWFN(edev)); 250245aec28SShahed Shaikh if (status & 0x1) { 251245aec28SShahed Shaikh qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 252245aec28SShahed Shaikh 2536bee9d5fSNithin Dabilpuram if (rte_intr_ack(eth_dev->intr_handle)) 2546bee9d5fSNithin Dabilpuram DP_ERR(edev, "rte_intr_ack failed\n"); 255245aec28SShahed Shaikh } 256245aec28SShahed Shaikh } 257245aec28SShahed Shaikh 258245aec28SShahed Shaikh static void 259c23a1a30SQi Zhang qede_interrupt_handler(void *param) 2602ea6f76aSRasesh Mody { 2612ea6f76aSRasesh Mody struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 2622ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 2632ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 2642ea6f76aSRasesh Mody 2652ea6f76aSRasesh Mody qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 2666bee9d5fSNithin Dabilpuram if (rte_intr_ack(eth_dev->intr_handle)) 2676bee9d5fSNithin Dabilpuram DP_ERR(edev, "rte_intr_ack failed\n"); 2682ea6f76aSRasesh Mody } 2692ea6f76aSRasesh Mody 2702ea6f76aSRasesh Mody static void 27181f88049SShahed Shaikh qede_assign_rxtx_handlers(struct rte_eth_dev *dev) 27281f88049SShahed Shaikh { 273*74e5a25dSShahed Shaikh uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads; 27481f88049SShahed Shaikh struct qede_dev *qdev = dev->data->dev_private; 27581f88049SShahed Shaikh struct ecore_dev *edev = &qdev->edev; 276*74e5a25dSShahed Shaikh bool use_tx_offload = false; 27781f88049SShahed Shaikh 27881f88049SShahed Shaikh if (ECORE_IS_CMT(edev)) { 27981f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts_cmt; 28081f88049SShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts_cmt; 28181f88049SShahed Shaikh return; 28281f88049SShahed Shaikh } 28381f88049SShahed Shaikh 28481f88049SShahed Shaikh if (dev->data->lro || dev->data->scattered_rx) { 28581f88049SShahed Shaikh DP_INFO(edev, "Assigning qede_recv_pkts\n"); 28681f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts; 28781f88049SShahed Shaikh } else { 28881f88049SShahed Shaikh DP_INFO(edev, "Assigning qede_recv_pkts_regular\n"); 28981f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts_regular; 29081f88049SShahed Shaikh } 29181f88049SShahed Shaikh 292*74e5a25dSShahed Shaikh use_tx_offload = !!(tx_offloads & 293*74e5a25dSShahed Shaikh (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | /* tunnel */ 294*74e5a25dSShahed Shaikh DEV_TX_OFFLOAD_TCP_TSO | /* tso */ 295*74e5a25dSShahed Shaikh DEV_TX_OFFLOAD_VLAN_INSERT)); /* vlan insert */ 296*74e5a25dSShahed Shaikh 297*74e5a25dSShahed Shaikh if (use_tx_offload) { 298*74e5a25dSShahed Shaikh DP_INFO(edev, "Assigning qede_xmit_pkts\n"); 29981f88049SShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts; 300*74e5a25dSShahed Shaikh } else { 301*74e5a25dSShahed Shaikh DP_INFO(edev, "Assigning qede_xmit_pkts_regular\n"); 302*74e5a25dSShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts_regular; 303*74e5a25dSShahed Shaikh } 30481f88049SShahed Shaikh } 30581f88049SShahed Shaikh 30681f88049SShahed Shaikh static void 3072ea6f76aSRasesh Mody qede_alloc_etherdev(struct qede_dev *qdev, struct qed_dev_eth_info *info) 3082ea6f76aSRasesh Mody { 3092ea6f76aSRasesh Mody rte_memcpy(&qdev->dev_info, info, sizeof(*info)); 3102ea6f76aSRasesh Mody qdev->ops = qed_ops; 3112ea6f76aSRasesh Mody } 3122ea6f76aSRasesh Mody 3132ea6f76aSRasesh Mody static void qede_print_adapter_info(struct qede_dev *qdev) 3142ea6f76aSRasesh Mody { 3152ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 3162ea6f76aSRasesh Mody struct qed_dev_info *info = &qdev->dev_info.common; 3177eca78ceSHarish Patil static char ver_str[QEDE_PMD_DRV_VER_STR_SIZE]; 3182ea6f76aSRasesh Mody 3192b5243d7SRasesh Mody DP_INFO(edev, "**************************************************\n"); 3202b5243d7SRasesh Mody DP_INFO(edev, " DPDK version\t\t\t: %s\n", rte_version()); 3212b5243d7SRasesh Mody DP_INFO(edev, " Chip details\t\t\t: %s %c%d\n", 3222ea6f76aSRasesh Mody ECORE_IS_BB(edev) ? "BB" : "AH", 3233818ac22SRasesh Mody 'A' + edev->chip_rev, 3243818ac22SRasesh Mody (int)edev->chip_metal); 3252b5243d7SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 3262b5243d7SRasesh Mody QEDE_PMD_DRV_VERSION); 3272b5243d7SRasesh Mody DP_INFO(edev, " Driver version\t\t\t: %s\n", ver_str); 3282b5243d7SRasesh Mody 3292b5243d7SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 3302b5243d7SRasesh Mody QEDE_PMD_BASE_VERSION); 3312b5243d7SRasesh Mody DP_INFO(edev, " Base version\t\t\t: %s\n", ver_str); 3322b5243d7SRasesh Mody 3332b5243d7SRasesh Mody if (!IS_VF(edev)) 3342b5243d7SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 3352b5243d7SRasesh Mody QEDE_PMD_FW_VERSION); 3362b5243d7SRasesh Mody else 3377eca78ceSHarish Patil snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%d.%d.%d.%d", 3382b5243d7SRasesh Mody info->fw_major, info->fw_minor, 3392b5243d7SRasesh Mody info->fw_rev, info->fw_eng); 3402b5243d7SRasesh Mody DP_INFO(edev, " Firmware version\t\t\t: %s\n", ver_str); 3412ea6f76aSRasesh Mody 3427eca78ceSHarish Patil snprintf(ver_str, MCP_DRV_VER_STR_SIZE, 3437eca78ceSHarish Patil "%d.%d.%d.%d", 3442b5243d7SRasesh Mody (info->mfw_rev & QED_MFW_VERSION_3_MASK) >> 3452b5243d7SRasesh Mody QED_MFW_VERSION_3_OFFSET, 3462b5243d7SRasesh Mody (info->mfw_rev & QED_MFW_VERSION_2_MASK) >> 3472b5243d7SRasesh Mody QED_MFW_VERSION_2_OFFSET, 3482b5243d7SRasesh Mody (info->mfw_rev & QED_MFW_VERSION_1_MASK) >> 3492b5243d7SRasesh Mody QED_MFW_VERSION_1_OFFSET, 3502b5243d7SRasesh Mody (info->mfw_rev & QED_MFW_VERSION_0_MASK) >> 3512b5243d7SRasesh Mody QED_MFW_VERSION_0_OFFSET); 3522b5243d7SRasesh Mody DP_INFO(edev, " Management Firmware version\t: %s\n", ver_str); 3532b5243d7SRasesh Mody DP_INFO(edev, " Firmware file\t\t\t: %s\n", qede_fw_file); 3542b5243d7SRasesh Mody DP_INFO(edev, "**************************************************\n"); 3552ea6f76aSRasesh Mody } 3562ea6f76aSRasesh Mody 357ce26be6eSRasesh Mody static void qede_reset_queue_stats(struct qede_dev *qdev, bool xstats) 358ce26be6eSRasesh Mody { 3598de0c420SShahed Shaikh struct rte_eth_dev *dev = (struct rte_eth_dev *)qdev->ethdev; 360ce26be6eSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 361ce26be6eSRasesh Mody unsigned int i = 0, j = 0, qid; 362ce26be6eSRasesh Mody unsigned int rxq_stat_cntrs, txq_stat_cntrs; 363ce26be6eSRasesh Mody struct qede_tx_queue *txq; 364ce26be6eSRasesh Mody 365ce26be6eSRasesh Mody DP_VERBOSE(edev, ECORE_MSG_DEBUG, "Clearing queue stats\n"); 366ce26be6eSRasesh Mody 3678de0c420SShahed Shaikh rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(dev), 368ce26be6eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 3698de0c420SShahed Shaikh txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(dev), 370ce26be6eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 371ce26be6eSRasesh Mody 3728de0c420SShahed Shaikh for (qid = 0; qid < qdev->num_rx_queues; qid++) { 373ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 374ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rcv_pkts), 0, 375ce26be6eSRasesh Mody sizeof(uint64_t)); 376ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 377ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rx_hw_errors), 0, 378ce26be6eSRasesh Mody sizeof(uint64_t)); 379ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 380ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rx_alloc_errors), 0, 381ce26be6eSRasesh Mody sizeof(uint64_t)); 382ce26be6eSRasesh Mody 383ce26be6eSRasesh Mody if (xstats) 384ce26be6eSRasesh Mody for (j = 0; j < RTE_DIM(qede_rxq_xstats_strings); j++) 385ce26be6eSRasesh Mody OSAL_MEMSET((((char *) 386ce26be6eSRasesh Mody (qdev->fp_array[qid].rxq)) + 387ce26be6eSRasesh Mody qede_rxq_xstats_strings[j].offset), 388ce26be6eSRasesh Mody 0, 389ce26be6eSRasesh Mody sizeof(uint64_t)); 390ce26be6eSRasesh Mody 391ce26be6eSRasesh Mody i++; 392ce26be6eSRasesh Mody if (i == rxq_stat_cntrs) 393ce26be6eSRasesh Mody break; 394ce26be6eSRasesh Mody } 395ce26be6eSRasesh Mody 396ce26be6eSRasesh Mody i = 0; 397ce26be6eSRasesh Mody 3988de0c420SShahed Shaikh for (qid = 0; qid < qdev->num_tx_queues; qid++) { 399ce26be6eSRasesh Mody txq = qdev->fp_array[qid].txq; 400ce26be6eSRasesh Mody 401ce26be6eSRasesh Mody OSAL_MEMSET((uint64_t *)(uintptr_t) 402ce26be6eSRasesh Mody (((uint64_t)(uintptr_t)(txq)) + 403ce26be6eSRasesh Mody offsetof(struct qede_tx_queue, xmit_pkts)), 0, 404ce26be6eSRasesh Mody sizeof(uint64_t)); 405ce26be6eSRasesh Mody 406ce26be6eSRasesh Mody i++; 407ce26be6eSRasesh Mody if (i == txq_stat_cntrs) 408ce26be6eSRasesh Mody break; 409ce26be6eSRasesh Mody } 410ce26be6eSRasesh Mody } 411ce26be6eSRasesh Mody 4129a6d30aeSHarish Patil static int 4139a6d30aeSHarish Patil qede_stop_vport(struct ecore_dev *edev) 4149a6d30aeSHarish Patil { 4159a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 4169a6d30aeSHarish Patil uint8_t vport_id; 4179a6d30aeSHarish Patil int rc; 4189a6d30aeSHarish Patil int i; 4199a6d30aeSHarish Patil 4209a6d30aeSHarish Patil vport_id = 0; 4219a6d30aeSHarish Patil for_each_hwfn(edev, i) { 4229a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 4239a6d30aeSHarish Patil rc = ecore_sp_vport_stop(p_hwfn, p_hwfn->hw_info.opaque_fid, 4249a6d30aeSHarish Patil vport_id); 4259a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 4269a6d30aeSHarish Patil DP_ERR(edev, "Stop V-PORT failed rc = %d\n", rc); 4279a6d30aeSHarish Patil return rc; 4289a6d30aeSHarish Patil } 4299a6d30aeSHarish Patil } 4309a6d30aeSHarish Patil 431dd28bc8cSHarish Patil DP_INFO(edev, "vport stopped\n"); 432dd28bc8cSHarish Patil 433dd28bc8cSHarish Patil return 0; 434dd28bc8cSHarish Patil } 435dd28bc8cSHarish Patil 436dd28bc8cSHarish Patil static int 437dd28bc8cSHarish Patil qede_start_vport(struct qede_dev *qdev, uint16_t mtu) 438dd28bc8cSHarish Patil { 439dd28bc8cSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 440dd28bc8cSHarish Patil struct ecore_sp_vport_start_params params; 441dd28bc8cSHarish Patil struct ecore_hwfn *p_hwfn; 442dd28bc8cSHarish Patil int rc; 443dd28bc8cSHarish Patil int i; 444dd28bc8cSHarish Patil 445dd28bc8cSHarish Patil if (qdev->vport_started) 446dd28bc8cSHarish Patil qede_stop_vport(edev); 447dd28bc8cSHarish Patil 448dd28bc8cSHarish Patil memset(¶ms, 0, sizeof(params)); 449dd28bc8cSHarish Patil params.vport_id = 0; 450dd28bc8cSHarish Patil params.mtu = mtu; 451dd28bc8cSHarish Patil /* @DPDK - Disable FW placement */ 452dd28bc8cSHarish Patil params.zero_placement_offset = 1; 453dd28bc8cSHarish Patil for_each_hwfn(edev, i) { 454dd28bc8cSHarish Patil p_hwfn = &edev->hwfns[i]; 455dd28bc8cSHarish Patil params.concrete_fid = p_hwfn->hw_info.concrete_fid; 456dd28bc8cSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 457dd28bc8cSHarish Patil rc = ecore_sp_vport_start(p_hwfn, ¶ms); 458dd28bc8cSHarish Patil if (rc != ECORE_SUCCESS) { 459dd28bc8cSHarish Patil DP_ERR(edev, "Start V-PORT failed %d\n", rc); 460dd28bc8cSHarish Patil return rc; 461dd28bc8cSHarish Patil } 462dd28bc8cSHarish Patil } 463dd28bc8cSHarish Patil ecore_reset_vport_stats(edev); 464dd28bc8cSHarish Patil qdev->vport_started = true; 465dd28bc8cSHarish Patil DP_INFO(edev, "VPORT started with MTU = %u\n", mtu); 466dd28bc8cSHarish Patil 4679a6d30aeSHarish Patil return 0; 4689a6d30aeSHarish Patil } 4699a6d30aeSHarish Patil 470612ce81bSRasesh Mody #define QEDE_NPAR_TX_SWITCHING "npar_tx_switching" 471612ce81bSRasesh Mody #define QEDE_VF_TX_SWITCHING "vf_tx_switching" 472612ce81bSRasesh Mody 4739a6d30aeSHarish Patil /* Activate or deactivate vport via vport-update */ 4749a6d30aeSHarish Patil int qede_activate_vport(struct rte_eth_dev *eth_dev, bool flg) 4759a6d30aeSHarish Patil { 4769a6d30aeSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 4779a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 4789a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 4799a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 4809a6d30aeSHarish Patil uint8_t i; 4819a6d30aeSHarish Patil int rc = -1; 4829a6d30aeSHarish Patil 4839a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 4849a6d30aeSHarish Patil params.vport_id = 0; 4859a6d30aeSHarish Patil params.update_vport_active_rx_flg = 1; 4869a6d30aeSHarish Patil params.update_vport_active_tx_flg = 1; 4879a6d30aeSHarish Patil params.vport_active_rx_flg = flg; 4889a6d30aeSHarish Patil params.vport_active_tx_flg = flg; 489d0ef40a1SDharmik Thakkar if ((qdev->enable_tx_switching == false) && (flg == true)) { 490f07aa795SHarish Patil params.update_tx_switching_flg = 1; 491f07aa795SHarish Patil params.tx_switching_flg = !flg; 492f64b91b0SRasesh Mody } 4939a6d30aeSHarish Patil for_each_hwfn(edev, i) { 4949a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 4959a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 4969a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 4979a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 4989a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 4999a6d30aeSHarish Patil DP_ERR(edev, "Failed to update vport\n"); 5009a6d30aeSHarish Patil break; 5019a6d30aeSHarish Patil } 5029a6d30aeSHarish Patil } 5031282943aSHarish Patil DP_INFO(edev, "vport is %s\n", flg ? "activated" : "deactivated"); 5041282943aSHarish Patil 5059a6d30aeSHarish Patil return rc; 5069a6d30aeSHarish Patil } 5079a6d30aeSHarish Patil 5089a6d30aeSHarish Patil static void 5099a6d30aeSHarish Patil qede_update_sge_tpa_params(struct ecore_sge_tpa_params *sge_tpa_params, 5109a6d30aeSHarish Patil uint16_t mtu, bool enable) 5119a6d30aeSHarish Patil { 5129a6d30aeSHarish Patil /* Enable LRO in split mode */ 5139a6d30aeSHarish Patil sge_tpa_params->tpa_ipv4_en_flg = enable; 5149a6d30aeSHarish Patil sge_tpa_params->tpa_ipv6_en_flg = enable; 515749d2329SHarish Patil sge_tpa_params->tpa_ipv4_tunn_en_flg = enable; 516749d2329SHarish Patil sge_tpa_params->tpa_ipv6_tunn_en_flg = enable; 5179a6d30aeSHarish Patil /* set if tpa enable changes */ 5189a6d30aeSHarish Patil sge_tpa_params->update_tpa_en_flg = 1; 5199a6d30aeSHarish Patil /* set if tpa parameters should be handled */ 5209a6d30aeSHarish Patil sge_tpa_params->update_tpa_param_flg = enable; 5219a6d30aeSHarish Patil 5229a6d30aeSHarish Patil sge_tpa_params->max_buffers_per_cqe = 20; 5239a6d30aeSHarish Patil /* Enable TPA in split mode. In this mode each TPA segment 5249a6d30aeSHarish Patil * starts on the new BD, so there is one BD per segment. 5259a6d30aeSHarish Patil */ 5269a6d30aeSHarish Patil sge_tpa_params->tpa_pkt_split_flg = 1; 5279a6d30aeSHarish Patil sge_tpa_params->tpa_hdr_data_split_flg = 0; 5289a6d30aeSHarish Patil sge_tpa_params->tpa_gro_consistent_flg = 0; 5299a6d30aeSHarish Patil sge_tpa_params->tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM; 5309a6d30aeSHarish Patil sge_tpa_params->tpa_max_size = 0x7FFF; 5319a6d30aeSHarish Patil sge_tpa_params->tpa_min_size_to_start = mtu / 2; 5329a6d30aeSHarish Patil sge_tpa_params->tpa_min_size_to_cont = mtu / 2; 5339a6d30aeSHarish Patil } 5349a6d30aeSHarish Patil 5359a6d30aeSHarish Patil /* Enable/disable LRO via vport-update */ 5369a6d30aeSHarish Patil int qede_enable_tpa(struct rte_eth_dev *eth_dev, bool flg) 5379a6d30aeSHarish Patil { 5389a6d30aeSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 5399a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 5409a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 5419a6d30aeSHarish Patil struct ecore_sge_tpa_params tpa_params; 5429a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 5439a6d30aeSHarish Patil int rc; 5449a6d30aeSHarish Patil int i; 5459a6d30aeSHarish Patil 5469a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 5479a6d30aeSHarish Patil memset(&tpa_params, 0, sizeof(struct ecore_sge_tpa_params)); 5489a6d30aeSHarish Patil qede_update_sge_tpa_params(&tpa_params, qdev->mtu, flg); 5499a6d30aeSHarish Patil params.vport_id = 0; 5509a6d30aeSHarish Patil params.sge_tpa_params = &tpa_params; 5519a6d30aeSHarish Patil for_each_hwfn(edev, i) { 5529a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 5539a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 5549a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 5559a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 5569a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 5579a6d30aeSHarish Patil DP_ERR(edev, "Failed to update LRO\n"); 5589a6d30aeSHarish Patil return -1; 5599a6d30aeSHarish Patil } 5609a6d30aeSHarish Patil } 561daee4e07SHarish Patil qdev->enable_lro = flg; 562946dfd18SHarish Patil eth_dev->data->lro = flg; 563946dfd18SHarish Patil 5649a6d30aeSHarish Patil DP_INFO(edev, "LRO is %s\n", flg ? "enabled" : "disabled"); 5659a6d30aeSHarish Patil 5669a6d30aeSHarish Patil return 0; 5679a6d30aeSHarish Patil } 5689a6d30aeSHarish Patil 5694c4bdadfSHarish Patil static int 5704c4bdadfSHarish Patil qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev, 5714c4bdadfSHarish Patil enum qed_filter_rx_mode_type type) 5724c4bdadfSHarish Patil { 5734c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 5744c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 5754c4bdadfSHarish Patil struct ecore_filter_accept_flags flags; 5764c4bdadfSHarish Patil 5774c4bdadfSHarish Patil memset(&flags, 0, sizeof(flags)); 5784c4bdadfSHarish Patil 5794c4bdadfSHarish Patil flags.update_rx_mode_config = 1; 5804c4bdadfSHarish Patil flags.update_tx_mode_config = 1; 5814c4bdadfSHarish Patil flags.rx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 5824c4bdadfSHarish Patil ECORE_ACCEPT_MCAST_MATCHED | 5834c4bdadfSHarish Patil ECORE_ACCEPT_BCAST; 5844c4bdadfSHarish Patil 5854c4bdadfSHarish Patil flags.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 5864c4bdadfSHarish Patil ECORE_ACCEPT_MCAST_MATCHED | 5874c4bdadfSHarish Patil ECORE_ACCEPT_BCAST; 5884c4bdadfSHarish Patil 5894c4bdadfSHarish Patil if (type == QED_FILTER_RX_MODE_TYPE_PROMISC) { 5904c4bdadfSHarish Patil flags.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED; 5914c4bdadfSHarish Patil if (IS_VF(edev)) { 5924c4bdadfSHarish Patil flags.tx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED; 5934c4bdadfSHarish Patil DP_INFO(edev, "Enabling Tx unmatched flag for VF\n"); 5944c4bdadfSHarish Patil } 5954c4bdadfSHarish Patil } else if (type == QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC) { 5964c4bdadfSHarish Patil flags.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 5974c4bdadfSHarish Patil } else if (type == (QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC | 5984c4bdadfSHarish Patil QED_FILTER_RX_MODE_TYPE_PROMISC)) { 5994c4bdadfSHarish Patil flags.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED | 6004c4bdadfSHarish Patil ECORE_ACCEPT_MCAST_UNMATCHED; 6014c4bdadfSHarish Patil } 6024c4bdadfSHarish Patil 6034c4bdadfSHarish Patil return ecore_filter_accept_cmd(edev, 0, flags, false, false, 6044c4bdadfSHarish Patil ECORE_SPQ_MODE_CB, NULL); 6054c4bdadfSHarish Patil } 606e0947ed9SHarish Patil 607eb54ba75SShahed Shaikh int 60877fac1b5SHarish Patil qede_ucast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast, 60977fac1b5SHarish Patil bool add) 61077fac1b5SHarish Patil { 61177fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 61277fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 61377fac1b5SHarish Patil struct qede_ucast_entry *tmp = NULL; 61477fac1b5SHarish Patil struct qede_ucast_entry *u; 6156d13ea8eSOlivier Matz struct rte_ether_addr *mac_addr; 61677fac1b5SHarish Patil 6176d13ea8eSOlivier Matz mac_addr = (struct rte_ether_addr *)ucast->mac; 61877fac1b5SHarish Patil if (add) { 61977fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->uc_list_head, list) { 62077fac1b5SHarish Patil if ((memcmp(mac_addr, &tmp->mac, 62135b2d13fSOlivier Matz RTE_ETHER_ADDR_LEN) == 0) && 622d2a2468eSRasesh Mody ucast->vni == tmp->vni && 62377fac1b5SHarish Patil ucast->vlan == tmp->vlan) { 624f8d2581eSShahed Shaikh DP_INFO(edev, "Unicast MAC is already added" 62577fac1b5SHarish Patil " with vlan = %u, vni = %u\n", 62677fac1b5SHarish Patil ucast->vlan, ucast->vni); 627f8d2581eSShahed Shaikh return 0; 62877fac1b5SHarish Patil } 62977fac1b5SHarish Patil } 63077fac1b5SHarish Patil u = rte_malloc(NULL, sizeof(struct qede_ucast_entry), 63177fac1b5SHarish Patil RTE_CACHE_LINE_SIZE); 63277fac1b5SHarish Patil if (!u) { 63377fac1b5SHarish Patil DP_ERR(edev, "Did not allocate memory for ucast\n"); 63477fac1b5SHarish Patil return -ENOMEM; 63577fac1b5SHarish Patil } 636538da7a1SOlivier Matz rte_ether_addr_copy(mac_addr, &u->mac); 63777fac1b5SHarish Patil u->vlan = ucast->vlan; 63852d94b57SHarish Patil u->vni = ucast->vni; 63977fac1b5SHarish Patil SLIST_INSERT_HEAD(&qdev->uc_list_head, u, list); 64077fac1b5SHarish Patil qdev->num_uc_addr++; 64177fac1b5SHarish Patil } else { 64277fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->uc_list_head, list) { 64377fac1b5SHarish Patil if ((memcmp(mac_addr, &tmp->mac, 64435b2d13fSOlivier Matz RTE_ETHER_ADDR_LEN) == 0) && 64552d94b57SHarish Patil ucast->vlan == tmp->vlan && 64652d94b57SHarish Patil ucast->vni == tmp->vni) 64777fac1b5SHarish Patil break; 64877fac1b5SHarish Patil } 64977fac1b5SHarish Patil if (tmp == NULL) { 65077fac1b5SHarish Patil DP_INFO(edev, "Unicast MAC is not found\n"); 65177fac1b5SHarish Patil return -EINVAL; 65277fac1b5SHarish Patil } 65377fac1b5SHarish Patil SLIST_REMOVE(&qdev->uc_list_head, tmp, qede_ucast_entry, list); 65477fac1b5SHarish Patil qdev->num_uc_addr--; 65577fac1b5SHarish Patil } 65677fac1b5SHarish Patil 65777fac1b5SHarish Patil return 0; 65877fac1b5SHarish Patil } 65977fac1b5SHarish Patil 66077fac1b5SHarish Patil static int 6616d13ea8eSOlivier Matz qede_add_mcast_filters(struct rte_eth_dev *eth_dev, 6626d13ea8eSOlivier Matz struct rte_ether_addr *mc_addrs, 663413ecf29SHarish Patil uint32_t mc_addrs_num) 66477fac1b5SHarish Patil { 66577fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 66677fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 667413ecf29SHarish Patil struct ecore_filter_mcast mcast; 668413ecf29SHarish Patil struct qede_mcast_entry *m = NULL; 669413ecf29SHarish Patil uint8_t i; 670413ecf29SHarish Patil int rc; 67177fac1b5SHarish Patil 672413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) { 67377fac1b5SHarish Patil m = rte_malloc(NULL, sizeof(struct qede_mcast_entry), 67477fac1b5SHarish Patil RTE_CACHE_LINE_SIZE); 67577fac1b5SHarish Patil if (!m) { 676413ecf29SHarish Patil DP_ERR(edev, "Did not allocate memory for mcast\n"); 67777fac1b5SHarish Patil return -ENOMEM; 67877fac1b5SHarish Patil } 679538da7a1SOlivier Matz rte_ether_addr_copy(&mc_addrs[i], &m->mac); 68077fac1b5SHarish Patil SLIST_INSERT_HEAD(&qdev->mc_list_head, m, list); 681413ecf29SHarish Patil } 682413ecf29SHarish Patil memset(&mcast, 0, sizeof(mcast)); 683413ecf29SHarish Patil mcast.num_mc_addrs = mc_addrs_num; 684413ecf29SHarish Patil mcast.opcode = ECORE_FILTER_ADD; 685413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) 686538da7a1SOlivier Matz rte_ether_addr_copy(&mc_addrs[i], (struct rte_ether_addr *) 687413ecf29SHarish Patil &mcast.mac[i]); 688413ecf29SHarish Patil rc = ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL); 689413ecf29SHarish Patil if (rc != ECORE_SUCCESS) { 690413ecf29SHarish Patil DP_ERR(edev, "Failed to add multicast filter (rc = %d\n)", rc); 691413ecf29SHarish Patil return -1; 692413ecf29SHarish Patil } 693413ecf29SHarish Patil 694413ecf29SHarish Patil return 0; 695413ecf29SHarish Patil } 696413ecf29SHarish Patil 697413ecf29SHarish Patil static int qede_del_mcast_filters(struct rte_eth_dev *eth_dev) 698413ecf29SHarish Patil { 699413ecf29SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 700413ecf29SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 701413ecf29SHarish Patil struct qede_mcast_entry *tmp = NULL; 702413ecf29SHarish Patil struct ecore_filter_mcast mcast; 703413ecf29SHarish Patil int j; 704413ecf29SHarish Patil int rc; 705413ecf29SHarish Patil 706413ecf29SHarish Patil memset(&mcast, 0, sizeof(mcast)); 707413ecf29SHarish Patil mcast.num_mc_addrs = qdev->num_mc_addr; 708413ecf29SHarish Patil mcast.opcode = ECORE_FILTER_REMOVE; 709413ecf29SHarish Patil j = 0; 71077fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->mc_list_head, list) { 711538da7a1SOlivier Matz rte_ether_addr_copy(&tmp->mac, 7126d13ea8eSOlivier Matz (struct rte_ether_addr *)&mcast.mac[j]); 713413ecf29SHarish Patil j++; 71477fac1b5SHarish Patil } 715413ecf29SHarish Patil rc = ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL); 716413ecf29SHarish Patil if (rc != ECORE_SUCCESS) { 717413ecf29SHarish Patil DP_ERR(edev, "Failed to delete multicast filter\n"); 718413ecf29SHarish Patil return -1; 71977fac1b5SHarish Patil } 720413ecf29SHarish Patil /* Init the list */ 721413ecf29SHarish Patil while (!SLIST_EMPTY(&qdev->mc_list_head)) { 722413ecf29SHarish Patil tmp = SLIST_FIRST(&qdev->mc_list_head); 723413ecf29SHarish Patil SLIST_REMOVE_HEAD(&qdev->mc_list_head, list); 72477fac1b5SHarish Patil } 725413ecf29SHarish Patil SLIST_INIT(&qdev->mc_list_head); 72677fac1b5SHarish Patil 72777fac1b5SHarish Patil return 0; 72877fac1b5SHarish Patil } 72977fac1b5SHarish Patil 730eb54ba75SShahed Shaikh enum _ecore_status_t 73177fac1b5SHarish Patil qede_mac_int_ops(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast, 73277fac1b5SHarish Patil bool add) 73377fac1b5SHarish Patil { 73477fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 73577fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 736413ecf29SHarish Patil enum _ecore_status_t rc = ECORE_INVAL; 73777fac1b5SHarish Patil 738413ecf29SHarish Patil if (add && (qdev->num_uc_addr >= qdev->dev_info.num_mac_filters)) { 739413ecf29SHarish Patil DP_ERR(edev, "Ucast filter table limit exceeded," 74077fac1b5SHarish Patil " Please enable promisc mode\n"); 741413ecf29SHarish Patil return ECORE_INVAL; 74277fac1b5SHarish Patil } 743413ecf29SHarish Patil 74477fac1b5SHarish Patil rc = qede_ucast_filter(eth_dev, ucast, add); 74577fac1b5SHarish Patil if (rc == 0) 74677fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, ucast, 74777fac1b5SHarish Patil ECORE_SPQ_MODE_CB, NULL); 7487e3060a3SShahed Shaikh /* Indicate error only for add filter operation. 7497e3060a3SShahed Shaikh * Delete filter operations are not severe. 7507e3060a3SShahed Shaikh */ 7517e3060a3SShahed Shaikh if ((rc != ECORE_SUCCESS) && add) 75277fac1b5SHarish Patil DP_ERR(edev, "MAC filter failed, rc = %d, op = %d\n", 75377fac1b5SHarish Patil rc, add); 75477fac1b5SHarish Patil 75577fac1b5SHarish Patil return rc; 7562ea6f76aSRasesh Mody } 7572ea6f76aSRasesh Mody 7586d01e580SWei Dai static int 7596d13ea8eSOlivier Matz qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr, 760af785e47SRasesh Mody __rte_unused uint32_t index, __rte_unused uint32_t pool) 7612ea6f76aSRasesh Mody { 76277fac1b5SHarish Patil struct ecore_filter_ucast ucast; 7636d01e580SWei Dai int re; 7642ea6f76aSRasesh Mody 765538da7a1SOlivier Matz if (!rte_is_valid_assigned_ether_addr(mac_addr)) 766c7641841SShahed Shaikh return -EINVAL; 767c7641841SShahed Shaikh 76877fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 769c7641841SShahed Shaikh ucast.opcode = ECORE_FILTER_ADD; 77077fac1b5SHarish Patil ucast.type = ECORE_FILTER_MAC; 771538da7a1SOlivier Matz rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)&ucast.mac); 7726d01e580SWei Dai re = (int)qede_mac_int_ops(eth_dev, &ucast, 1); 7736d01e580SWei Dai return re; 7742ea6f76aSRasesh Mody } 7752ea6f76aSRasesh Mody 7762ea6f76aSRasesh Mody static void 7772ea6f76aSRasesh Mody qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index) 7782ea6f76aSRasesh Mody { 7792ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 7802ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 78177fac1b5SHarish Patil struct ecore_filter_ucast ucast; 7822ea6f76aSRasesh Mody 7832ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 7842ea6f76aSRasesh Mody 7853320ca8cSRasesh Mody if (index >= qdev->dev_info.num_mac_filters) { 7862ea6f76aSRasesh Mody DP_ERR(edev, "Index %u is above MAC filter limit %u\n", 7873320ca8cSRasesh Mody index, qdev->dev_info.num_mac_filters); 7882ea6f76aSRasesh Mody return; 7892ea6f76aSRasesh Mody } 7902ea6f76aSRasesh Mody 791538da7a1SOlivier Matz if (!rte_is_valid_assigned_ether_addr(ð_dev->data->mac_addrs[index])) 792c7641841SShahed Shaikh return; 793c7641841SShahed Shaikh 79477fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 79577fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_REMOVE; 79677fac1b5SHarish Patil ucast.type = ECORE_FILTER_MAC; 79777fac1b5SHarish Patil 7982ea6f76aSRasesh Mody /* Use the index maintained by rte */ 799538da7a1SOlivier Matz rte_ether_addr_copy(ð_dev->data->mac_addrs[index], 8006d13ea8eSOlivier Matz (struct rte_ether_addr *)&ucast.mac); 80177fac1b5SHarish Patil 80283ade1ebSRasesh Mody qede_mac_int_ops(eth_dev, &ucast, false); 8032ea6f76aSRasesh Mody } 8042ea6f76aSRasesh Mody 805caccf8b3SOlivier Matz static int 8066d13ea8eSOlivier Matz qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr) 8072ea6f76aSRasesh Mody { 8082ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 8092ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8102ea6f76aSRasesh Mody 81186a2265eSRasesh Mody if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev), 81286a2265eSRasesh Mody mac_addr->addr_bytes)) { 81386a2265eSRasesh Mody DP_ERR(edev, "Setting MAC address is not allowed\n"); 814caccf8b3SOlivier Matz return -EPERM; 81586a2265eSRasesh Mody } 81686a2265eSRasesh Mody 817c7641841SShahed Shaikh qede_mac_addr_remove(eth_dev, 0); 818c7641841SShahed Shaikh 819c7641841SShahed Shaikh return qede_mac_addr_add(eth_dev, mac_addr, 0, 0); 8202ea6f76aSRasesh Mody } 8212ea6f76aSRasesh Mody 822eb54ba75SShahed Shaikh void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg) 8232ea6f76aSRasesh Mody { 8249a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8259a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 8269a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 8279a6d30aeSHarish Patil uint8_t i; 8282ea6f76aSRasesh Mody int rc; 8292ea6f76aSRasesh Mody 8309a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 8319a6d30aeSHarish Patil params.vport_id = 0; 8329a6d30aeSHarish Patil params.update_accept_any_vlan_flg = 1; 8339a6d30aeSHarish Patil params.accept_any_vlan = flg; 8349a6d30aeSHarish Patil for_each_hwfn(edev, i) { 8359a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 8369a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 8379a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 8389a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 8399a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 8409a6d30aeSHarish Patil DP_ERR(edev, "Failed to configure accept-any-vlan\n"); 8412ea6f76aSRasesh Mody return; 8422ea6f76aSRasesh Mody } 8432ea6f76aSRasesh Mody } 8442ea6f76aSRasesh Mody 8459a6d30aeSHarish Patil DP_INFO(edev, "%s accept-any-vlan\n", flg ? "enabled" : "disabled"); 8469a6d30aeSHarish Patil } 8479a6d30aeSHarish Patil 8489a6d30aeSHarish Patil static int qede_vlan_stripping(struct rte_eth_dev *eth_dev, bool flg) 8492ea6f76aSRasesh Mody { 8502ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 8512ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8529a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 8539a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 8549a6d30aeSHarish Patil uint8_t i; 8552ea6f76aSRasesh Mody int rc; 8562ea6f76aSRasesh Mody 8579a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 8589a6d30aeSHarish Patil params.vport_id = 0; 8599a6d30aeSHarish Patil params.update_inner_vlan_removal_flg = 1; 8609a6d30aeSHarish Patil params.inner_vlan_removal_flg = flg; 8619a6d30aeSHarish Patil for_each_hwfn(edev, i) { 8629a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 8639a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 8649a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 8659a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 8669a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 8679a6d30aeSHarish Patil DP_ERR(edev, "Failed to update vport\n"); 8689a6d30aeSHarish Patil return -1; 8692ea6f76aSRasesh Mody } 8709a6d30aeSHarish Patil } 8712ea6f76aSRasesh Mody 87230b170b4SShahed Shaikh qdev->vlan_strip_flg = flg; 87330b170b4SShahed Shaikh 8749a6d30aeSHarish Patil DP_INFO(edev, "VLAN stripping %s\n", flg ? "enabled" : "disabled"); 8752ea6f76aSRasesh Mody return 0; 8762ea6f76aSRasesh Mody } 8772ea6f76aSRasesh Mody 8782ea6f76aSRasesh Mody static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev, 8792ea6f76aSRasesh Mody uint16_t vlan_id, int on) 8802ea6f76aSRasesh Mody { 8812ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 8822ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8832ea6f76aSRasesh Mody struct qed_dev_eth_info *dev_info = &qdev->dev_info; 884d6cb1753SHarish Patil struct qede_vlan_entry *tmp = NULL; 885d6cb1753SHarish Patil struct qede_vlan_entry *vlan; 88677fac1b5SHarish Patil struct ecore_filter_ucast ucast; 8872ea6f76aSRasesh Mody int rc; 8882ea6f76aSRasesh Mody 889bec02288SSony Chacko if (on) { 890d6cb1753SHarish Patil if (qdev->configured_vlans == dev_info->num_vlan_filters) { 89161a8429fSRasesh Mody DP_ERR(edev, "Reached max VLAN filter limit" 8922ea6f76aSRasesh Mody " enabling accept_any_vlan\n"); 8932ea6f76aSRasesh Mody qede_config_accept_any_vlan(qdev, true); 8942ea6f76aSRasesh Mody return 0; 8952ea6f76aSRasesh Mody } 8962ea6f76aSRasesh Mody 897d6cb1753SHarish Patil SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) { 898d6cb1753SHarish Patil if (tmp->vid == vlan_id) { 899f8d2581eSShahed Shaikh DP_INFO(edev, "VLAN %u already configured\n", 9002ea6f76aSRasesh Mody vlan_id); 901f8d2581eSShahed Shaikh return 0; 902d6cb1753SHarish Patil } 9032ea6f76aSRasesh Mody } 9042ea6f76aSRasesh Mody 905d6cb1753SHarish Patil vlan = rte_malloc(NULL, sizeof(struct qede_vlan_entry), 906d6cb1753SHarish Patil RTE_CACHE_LINE_SIZE); 907d6cb1753SHarish Patil 908d6cb1753SHarish Patil if (!vlan) { 909d6cb1753SHarish Patil DP_ERR(edev, "Did not allocate memory for VLAN\n"); 910d6cb1753SHarish Patil return -ENOMEM; 911d6cb1753SHarish Patil } 912d6cb1753SHarish Patil 91377fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 91477fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_ADD; 91577fac1b5SHarish Patil ucast.type = ECORE_FILTER_VLAN; 91677fac1b5SHarish Patil ucast.vlan = vlan_id; 91777fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, 91877fac1b5SHarish Patil NULL); 91977fac1b5SHarish Patil if (rc != 0) { 920d6cb1753SHarish Patil DP_ERR(edev, "Failed to add VLAN %u rc %d\n", vlan_id, 921d6cb1753SHarish Patil rc); 922d6cb1753SHarish Patil rte_free(vlan); 923d6cb1753SHarish Patil } else { 924d6cb1753SHarish Patil vlan->vid = vlan_id; 925d6cb1753SHarish Patil SLIST_INSERT_HEAD(&qdev->vlan_list_head, vlan, list); 926d6cb1753SHarish Patil qdev->configured_vlans++; 927d6cb1753SHarish Patil DP_INFO(edev, "VLAN %u added, configured_vlans %u\n", 928d6cb1753SHarish Patil vlan_id, qdev->configured_vlans); 929d6cb1753SHarish Patil } 930d6cb1753SHarish Patil } else { 931d6cb1753SHarish Patil SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) { 932d6cb1753SHarish Patil if (tmp->vid == vlan_id) 933d6cb1753SHarish Patil break; 934d6cb1753SHarish Patil } 935d6cb1753SHarish Patil 936d6cb1753SHarish Patil if (!tmp) { 937d6cb1753SHarish Patil if (qdev->configured_vlans == 0) { 938d6cb1753SHarish Patil DP_INFO(edev, 939d6cb1753SHarish Patil "No VLAN filters configured yet\n"); 940d6cb1753SHarish Patil return 0; 941d6cb1753SHarish Patil } 942d6cb1753SHarish Patil 943d6cb1753SHarish Patil DP_ERR(edev, "VLAN %u not configured\n", vlan_id); 944d6cb1753SHarish Patil return -EINVAL; 945d6cb1753SHarish Patil } 946d6cb1753SHarish Patil 947d6cb1753SHarish Patil SLIST_REMOVE(&qdev->vlan_list_head, tmp, qede_vlan_entry, list); 948d6cb1753SHarish Patil 94977fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 95077fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_REMOVE; 95177fac1b5SHarish Patil ucast.type = ECORE_FILTER_VLAN; 95277fac1b5SHarish Patil ucast.vlan = vlan_id; 95377fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, 95477fac1b5SHarish Patil NULL); 95577fac1b5SHarish Patil if (rc != 0) { 956d6cb1753SHarish Patil DP_ERR(edev, "Failed to delete VLAN %u rc %d\n", 957d6cb1753SHarish Patil vlan_id, rc); 958d6cb1753SHarish Patil } else { 959d6cb1753SHarish Patil qdev->configured_vlans--; 960d6cb1753SHarish Patil DP_INFO(edev, "VLAN %u removed configured_vlans %u\n", 961d6cb1753SHarish Patil vlan_id, qdev->configured_vlans); 962d6cb1753SHarish Patil } 963d6cb1753SHarish Patil } 9642ea6f76aSRasesh Mody 9652ea6f76aSRasesh Mody return rc; 9662ea6f76aSRasesh Mody } 9672ea6f76aSRasesh Mody 968289ba0c0SDavid Harton static int qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) 969af785e47SRasesh Mody { 970af785e47SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 971af785e47SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 972946dfd18SHarish Patil uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; 973af785e47SRasesh Mody 974af785e47SRasesh Mody if (mask & ETH_VLAN_STRIP_MASK) { 975946dfd18SHarish Patil if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 976af785e47SRasesh Mody (void)qede_vlan_stripping(eth_dev, 1); 977af785e47SRasesh Mody else 978af785e47SRasesh Mody (void)qede_vlan_stripping(eth_dev, 0); 979af785e47SRasesh Mody } 980af785e47SRasesh Mody 981af785e47SRasesh Mody if (mask & ETH_VLAN_FILTER_MASK) { 982af785e47SRasesh Mody /* VLAN filtering kicks in when a VLAN is added */ 983946dfd18SHarish Patil if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { 984af785e47SRasesh Mody qede_vlan_filter_set(eth_dev, 0, 1); 985af785e47SRasesh Mody } else { 986af785e47SRasesh Mody if (qdev->configured_vlans > 1) { /* Excluding VLAN0 */ 987af785e47SRasesh Mody DP_ERR(edev, 988af785e47SRasesh Mody " Please remove existing VLAN filters" 989af785e47SRasesh Mody " before disabling VLAN filtering\n"); 990af785e47SRasesh Mody /* Signal app that VLAN filtering is still 991af785e47SRasesh Mody * enabled 992af785e47SRasesh Mody */ 993946dfd18SHarish Patil eth_dev->data->dev_conf.rxmode.offloads |= 994946dfd18SHarish Patil DEV_RX_OFFLOAD_VLAN_FILTER; 995af785e47SRasesh Mody } else { 996af785e47SRasesh Mody qede_vlan_filter_set(eth_dev, 0, 0); 997af785e47SRasesh Mody } 998af785e47SRasesh Mody } 999af785e47SRasesh Mody } 1000af785e47SRasesh Mody 1001af785e47SRasesh Mody if (mask & ETH_VLAN_EXTEND_MASK) 1002946dfd18SHarish Patil DP_ERR(edev, "Extend VLAN not supported\n"); 1003af785e47SRasesh Mody 1004dd28bc8cSHarish Patil qdev->vlan_offload_mask = mask; 1005dd28bc8cSHarish Patil 1006946dfd18SHarish Patil DP_INFO(edev, "VLAN offload mask %d\n", mask); 1007289ba0c0SDavid Harton 1008289ba0c0SDavid Harton return 0; 1009af785e47SRasesh Mody } 1010af785e47SRasesh Mody 10117ab35bf6SHarish Patil static void qede_prandom_bytes(uint32_t *buff) 10127ab35bf6SHarish Patil { 10137ab35bf6SHarish Patil uint8_t i; 10147ab35bf6SHarish Patil 10157ab35bf6SHarish Patil srand((unsigned int)time(NULL)); 10167ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_KEY_SIZE; i++) 10177ab35bf6SHarish Patil buff[i] = rand(); 10187ab35bf6SHarish Patil } 10197ab35bf6SHarish Patil 10208130abb3SHarish Patil int qede_config_rss(struct rte_eth_dev *eth_dev) 10217ab35bf6SHarish Patil { 10227ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 10237ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 10247ab35bf6SHarish Patil uint32_t def_rss_key[ECORE_RSS_KEY_SIZE]; 10257ab35bf6SHarish Patil struct rte_eth_rss_reta_entry64 reta_conf[2]; 10267ab35bf6SHarish Patil struct rte_eth_rss_conf rss_conf; 10277ab35bf6SHarish Patil uint32_t i, id, pos, q; 10287ab35bf6SHarish Patil 10297ab35bf6SHarish Patil rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf; 10307ab35bf6SHarish Patil if (!rss_conf.rss_key) { 10317ab35bf6SHarish Patil DP_INFO(edev, "Applying driver default key\n"); 10327ab35bf6SHarish Patil rss_conf.rss_key_len = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); 10337ab35bf6SHarish Patil qede_prandom_bytes(&def_rss_key[0]); 10347ab35bf6SHarish Patil rss_conf.rss_key = (uint8_t *)&def_rss_key[0]; 10357ab35bf6SHarish Patil } 10367ab35bf6SHarish Patil 10377ab35bf6SHarish Patil /* Configure RSS hash */ 10387ab35bf6SHarish Patil if (qede_rss_hash_update(eth_dev, &rss_conf)) 10397ab35bf6SHarish Patil return -EINVAL; 10407ab35bf6SHarish Patil 10417ab35bf6SHarish Patil /* Configure default RETA */ 10427ab35bf6SHarish Patil memset(reta_conf, 0, sizeof(reta_conf)); 10437ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) 10447ab35bf6SHarish Patil reta_conf[i / RTE_RETA_GROUP_SIZE].mask = UINT64_MAX; 10457ab35bf6SHarish Patil 10467ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) { 10477ab35bf6SHarish Patil id = i / RTE_RETA_GROUP_SIZE; 10487ab35bf6SHarish Patil pos = i % RTE_RETA_GROUP_SIZE; 10498de0c420SShahed Shaikh q = i % QEDE_RSS_COUNT(eth_dev); 10507ab35bf6SHarish Patil reta_conf[id].reta[pos] = q; 10517ab35bf6SHarish Patil } 10527ab35bf6SHarish Patil if (qede_rss_reta_update(eth_dev, &reta_conf[0], 10537ab35bf6SHarish Patil ECORE_RSS_IND_TABLE_SIZE)) 10547ab35bf6SHarish Patil return -EINVAL; 10557ab35bf6SHarish Patil 10567ab35bf6SHarish Patil return 0; 10577ab35bf6SHarish Patil } 10587ab35bf6SHarish Patil 10594c4bdadfSHarish Patil static void qede_fastpath_start(struct ecore_dev *edev) 10604c4bdadfSHarish Patil { 10614c4bdadfSHarish Patil struct ecore_hwfn *p_hwfn; 10624c4bdadfSHarish Patil int i; 10634c4bdadfSHarish Patil 10644c4bdadfSHarish Patil for_each_hwfn(edev, i) { 10654c4bdadfSHarish Patil p_hwfn = &edev->hwfns[i]; 10664c4bdadfSHarish Patil ecore_hw_start_fastpath(p_hwfn); 10674c4bdadfSHarish Patil } 10684c4bdadfSHarish Patil } 10694c4bdadfSHarish Patil 10704c4bdadfSHarish Patil static int qede_dev_start(struct rte_eth_dev *eth_dev) 10714c4bdadfSHarish Patil { 10724c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 10734c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1074946dfd18SHarish Patil struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode; 10754c4bdadfSHarish Patil 10764c4bdadfSHarish Patil PMD_INIT_FUNC_TRACE(edev); 10774c4bdadfSHarish Patil 1078d121a6b5SRasesh Mody /* Update MTU only if it has changed */ 107929bb154fSShahed Shaikh if (qdev->new_mtu && qdev->new_mtu != qdev->mtu) { 108029bb154fSShahed Shaikh if (qede_update_mtu(eth_dev, qdev->new_mtu)) 1081d121a6b5SRasesh Mody goto err; 108229bb154fSShahed Shaikh qdev->mtu = qdev->new_mtu; 108329bb154fSShahed Shaikh qdev->new_mtu = 0; 1084d121a6b5SRasesh Mody } 1085d121a6b5SRasesh Mody 1086daee4e07SHarish Patil /* Configure TPA parameters */ 1087946dfd18SHarish Patil if (rxmode->offloads & DEV_RX_OFFLOAD_TCP_LRO) { 10884c4bdadfSHarish Patil if (qede_enable_tpa(eth_dev, true)) 1089daee4e07SHarish Patil return -EINVAL; 1090daee4e07SHarish Patil /* Enable scatter mode for LRO */ 1091946dfd18SHarish Patil if (!eth_dev->data->scattered_rx) 1092946dfd18SHarish Patil rxmode->offloads |= DEV_RX_OFFLOAD_SCATTER; 10934c4bdadfSHarish Patil } 10944c4bdadfSHarish Patil 10954c4bdadfSHarish Patil /* Start queues */ 10964c4bdadfSHarish Patil if (qede_start_queues(eth_dev)) 10974c4bdadfSHarish Patil goto err; 10984c4bdadfSHarish Patil 1099dd28bc8cSHarish Patil if (IS_PF(edev)) 1100dd28bc8cSHarish Patil qede_reset_queue_stats(qdev, true); 1101dd28bc8cSHarish Patil 11024c4bdadfSHarish Patil /* Newer SR-IOV PF driver expects RX/TX queues to be started before 11034c4bdadfSHarish Patil * enabling RSS. Hence RSS configuration is deferred upto this point. 11044c4bdadfSHarish Patil * Also, we would like to retain similar behavior in PF case, so we 11054c4bdadfSHarish Patil * don't do PF/VF specific check here. 11064c4bdadfSHarish Patil */ 1107946dfd18SHarish Patil if (eth_dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) 11084c4bdadfSHarish Patil if (qede_config_rss(eth_dev)) 11094c4bdadfSHarish Patil goto err; 11104c4bdadfSHarish Patil 11114c4bdadfSHarish Patil /* Enable vport*/ 11124c4bdadfSHarish Patil if (qede_activate_vport(eth_dev, true)) 11134c4bdadfSHarish Patil goto err; 11144c4bdadfSHarish Patil 11158aab5d6fSRasesh Mody /* Update link status */ 11168aab5d6fSRasesh Mody qede_link_update(eth_dev, 0); 11178aab5d6fSRasesh Mody 11184c4bdadfSHarish Patil /* Start/resume traffic */ 11194c4bdadfSHarish Patil qede_fastpath_start(edev); 11204c4bdadfSHarish Patil 112181f88049SShahed Shaikh qede_assign_rxtx_handlers(eth_dev); 11224c4bdadfSHarish Patil DP_INFO(edev, "Device started\n"); 11234c4bdadfSHarish Patil 11244c4bdadfSHarish Patil return 0; 11254c4bdadfSHarish Patil err: 11264c4bdadfSHarish Patil DP_ERR(edev, "Device start fails\n"); 11274c4bdadfSHarish Patil return -1; /* common error code is < 0 */ 11284c4bdadfSHarish Patil } 11294c4bdadfSHarish Patil 11304c4bdadfSHarish Patil static void qede_dev_stop(struct rte_eth_dev *eth_dev) 11314c4bdadfSHarish Patil { 11324c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 11334c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 11344c4bdadfSHarish Patil 11354c4bdadfSHarish Patil PMD_INIT_FUNC_TRACE(edev); 11364c4bdadfSHarish Patil 11374c4bdadfSHarish Patil /* Disable vport */ 11384c4bdadfSHarish Patil if (qede_activate_vport(eth_dev, false)) 11394c4bdadfSHarish Patil return; 11404c4bdadfSHarish Patil 11414c4bdadfSHarish Patil if (qdev->enable_lro) 11424c4bdadfSHarish Patil qede_enable_tpa(eth_dev, false); 11434c4bdadfSHarish Patil 11444c4bdadfSHarish Patil /* Stop queues */ 11454c4bdadfSHarish Patil qede_stop_queues(eth_dev); 11464c4bdadfSHarish Patil 11474c4bdadfSHarish Patil /* Disable traffic */ 11484c4bdadfSHarish Patil ecore_hw_stop_fastpath(edev); /* TBD - loop */ 11494c4bdadfSHarish Patil 11504c4bdadfSHarish Patil DP_INFO(edev, "Device is stopped\n"); 11514c4bdadfSHarish Patil } 11524c4bdadfSHarish Patil 1153b74fd6b8SFerruh Yigit static const char * const valid_args[] = { 1154612ce81bSRasesh Mody QEDE_NPAR_TX_SWITCHING, 1155612ce81bSRasesh Mody QEDE_VF_TX_SWITCHING, 1156f64b91b0SRasesh Mody NULL, 1157f64b91b0SRasesh Mody }; 1158f64b91b0SRasesh Mody 1159f64b91b0SRasesh Mody static int qede_args_check(const char *key, const char *val, void *opaque) 1160f64b91b0SRasesh Mody { 1161f64b91b0SRasesh Mody unsigned long tmp; 1162f64b91b0SRasesh Mody int ret = 0; 1163f64b91b0SRasesh Mody struct rte_eth_dev *eth_dev = opaque; 1164f64b91b0SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1165f64b91b0SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1166f64b91b0SRasesh Mody 1167f64b91b0SRasesh Mody errno = 0; 1168f64b91b0SRasesh Mody tmp = strtoul(val, NULL, 0); 1169f64b91b0SRasesh Mody if (errno) { 1170f64b91b0SRasesh Mody DP_INFO(edev, "%s: \"%s\" is not a valid integer", key, val); 1171f64b91b0SRasesh Mody return errno; 1172f64b91b0SRasesh Mody } 1173f64b91b0SRasesh Mody 1174612ce81bSRasesh Mody if ((strcmp(QEDE_NPAR_TX_SWITCHING, key) == 0) || 1175a16aef52SRasesh Mody ((strcmp(QEDE_VF_TX_SWITCHING, key) == 0) && IS_VF(edev))) { 1176f64b91b0SRasesh Mody qdev->enable_tx_switching = !!tmp; 1177a16aef52SRasesh Mody DP_INFO(edev, "Disabling %s tx-switching\n", 1178a16aef52SRasesh Mody strcmp(QEDE_NPAR_TX_SWITCHING, key) ? 1179a16aef52SRasesh Mody "VF" : "NPAR"); 1180a16aef52SRasesh Mody } 1181f64b91b0SRasesh Mody 1182f64b91b0SRasesh Mody return ret; 1183f64b91b0SRasesh Mody } 1184f64b91b0SRasesh Mody 1185f64b91b0SRasesh Mody static int qede_args(struct rte_eth_dev *eth_dev) 1186f64b91b0SRasesh Mody { 1187f64b91b0SRasesh Mody struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device); 1188f64b91b0SRasesh Mody struct rte_kvargs *kvlist; 1189f64b91b0SRasesh Mody struct rte_devargs *devargs; 1190f64b91b0SRasesh Mody int ret; 1191f64b91b0SRasesh Mody int i; 1192f64b91b0SRasesh Mody 1193f64b91b0SRasesh Mody devargs = pci_dev->device.devargs; 1194f64b91b0SRasesh Mody if (!devargs) 1195f64b91b0SRasesh Mody return 0; /* return success */ 1196f64b91b0SRasesh Mody 1197f64b91b0SRasesh Mody kvlist = rte_kvargs_parse(devargs->args, valid_args); 1198f64b91b0SRasesh Mody if (kvlist == NULL) 1199f64b91b0SRasesh Mody return -EINVAL; 1200f64b91b0SRasesh Mody 1201f64b91b0SRasesh Mody /* Process parameters. */ 1202f64b91b0SRasesh Mody for (i = 0; (valid_args[i] != NULL); ++i) { 1203f64b91b0SRasesh Mody if (rte_kvargs_count(kvlist, valid_args[i])) { 1204f64b91b0SRasesh Mody ret = rte_kvargs_process(kvlist, valid_args[i], 1205f64b91b0SRasesh Mody qede_args_check, eth_dev); 1206f64b91b0SRasesh Mody if (ret != ECORE_SUCCESS) { 1207f64b91b0SRasesh Mody rte_kvargs_free(kvlist); 1208f64b91b0SRasesh Mody return ret; 1209f64b91b0SRasesh Mody } 1210f64b91b0SRasesh Mody } 1211f64b91b0SRasesh Mody } 1212f64b91b0SRasesh Mody rte_kvargs_free(kvlist); 1213f64b91b0SRasesh Mody 1214f64b91b0SRasesh Mody return 0; 1215f64b91b0SRasesh Mody } 1216f64b91b0SRasesh Mody 12172ea6f76aSRasesh Mody static int qede_dev_configure(struct rte_eth_dev *eth_dev) 12182ea6f76aSRasesh Mody { 12194c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 12204c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 12212ea6f76aSRasesh Mody struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode; 1222289ba0c0SDavid Harton int ret; 12232ea6f76aSRasesh Mody 12242ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 12252ea6f76aSRasesh Mody 122673fb89ddSAndrew Rybchenko if (rxmode->mq_mode & ETH_MQ_RX_RSS_FLAG) 12278b945a7fSPavan Nikhilesh rxmode->offloads |= DEV_RX_OFFLOAD_RSS_HASH; 12288b945a7fSPavan Nikhilesh 1229e60644c4SHarish Patil /* We need to have min 1 RX queue.There is no min check in 1230e60644c4SHarish Patil * rte_eth_dev_configure(), so we are checking it here. 1231e60644c4SHarish Patil */ 1232e60644c4SHarish Patil if (eth_dev->data->nb_rx_queues == 0) { 1233e60644c4SHarish Patil DP_ERR(edev, "Minimum one RX queue is required\n"); 1234e60644c4SHarish Patil return -EINVAL; 1235e60644c4SHarish Patil } 1236e60644c4SHarish Patil 1237f64b91b0SRasesh Mody /* Enable Tx switching by default */ 1238f64b91b0SRasesh Mody qdev->enable_tx_switching = 1; 1239f64b91b0SRasesh Mody 1240f64b91b0SRasesh Mody /* Parse devargs and fix up rxmode */ 1241f64b91b0SRasesh Mody if (qede_args(eth_dev)) 1242a16aef52SRasesh Mody DP_NOTICE(edev, false, 1243a16aef52SRasesh Mody "Invalid devargs supplied, requested change will not take effect\n"); 1244f64b91b0SRasesh Mody 1245946dfd18SHarish Patil if (!(rxmode->mq_mode == ETH_MQ_RX_NONE || 1246946dfd18SHarish Patil rxmode->mq_mode == ETH_MQ_RX_RSS)) { 12474c4bdadfSHarish Patil DP_ERR(edev, "Unsupported multi-queue mode\n"); 12484c4bdadfSHarish Patil return -ENOTSUP; 124929540be7SHarish Patil } 12504c4bdadfSHarish Patil /* Flow director mode check */ 12514c4bdadfSHarish Patil if (qede_check_fdir_support(eth_dev)) 12524c4bdadfSHarish Patil return -ENOTSUP; 125329540be7SHarish Patil 12544c4bdadfSHarish Patil qede_dealloc_fp_resc(eth_dev); 12558de0c420SShahed Shaikh qdev->num_tx_queues = eth_dev->data->nb_tx_queues * edev->num_hwfns; 12568de0c420SShahed Shaikh qdev->num_rx_queues = eth_dev->data->nb_rx_queues * edev->num_hwfns; 12578de0c420SShahed Shaikh 12584c4bdadfSHarish Patil if (qede_alloc_fp_resc(qdev)) 12594c4bdadfSHarish Patil return -ENOMEM; 12602ea6f76aSRasesh Mody 12619e334305SRasesh Mody /* If jumbo enabled adjust MTU */ 1262946dfd18SHarish Patil if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) 12639e334305SRasesh Mody eth_dev->data->mtu = 12649e334305SRasesh Mody eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - 126535b2d13fSOlivier Matz RTE_ETHER_HDR_LEN - QEDE_ETH_OVERHEAD; 12669e334305SRasesh Mody 1267946dfd18SHarish Patil if (rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) 1268946dfd18SHarish Patil eth_dev->data->scattered_rx = 1; 1269946dfd18SHarish Patil 12709e334305SRasesh Mody if (qede_start_vport(qdev, eth_dev->data->mtu)) 12719a6d30aeSHarish Patil return -1; 1272946dfd18SHarish Patil 12739e334305SRasesh Mody qdev->mtu = eth_dev->data->mtu; 1274dbac54c2SHarish Patil 1275d87246a4SHarish Patil /* Enable VLAN offloads by default */ 1276289ba0c0SDavid Harton ret = qede_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK | 1277c6dd1eb8SRasesh Mody ETH_VLAN_FILTER_MASK); 1278289ba0c0SDavid Harton if (ret) 1279289ba0c0SDavid Harton return ret; 1280d87246a4SHarish Patil 12814c4bdadfSHarish Patil DP_INFO(edev, "Device configured with RSS=%d TSS=%d\n", 12828de0c420SShahed Shaikh QEDE_RSS_COUNT(eth_dev), QEDE_TSS_COUNT(eth_dev)); 12838de0c420SShahed Shaikh 12848de0c420SShahed Shaikh if (ECORE_IS_CMT(edev)) 12858de0c420SShahed Shaikh DP_INFO(edev, "Actual HW queues for CMT mode - RX = %d TX = %d\n", 12868de0c420SShahed Shaikh qdev->num_rx_queues, qdev->num_tx_queues); 12878de0c420SShahed Shaikh 12889c5d0a66SHarish Patil 12892ea6f76aSRasesh Mody return 0; 12902ea6f76aSRasesh Mody } 12912ea6f76aSRasesh Mody 12922ea6f76aSRasesh Mody /* Info about HW descriptor ring limitations */ 12932ea6f76aSRasesh Mody static const struct rte_eth_desc_lim qede_rx_desc_lim = { 1294c008e17bSHarish Patil .nb_max = 0x8000, /* 32K */ 12952ea6f76aSRasesh Mody .nb_min = 128, 12962ea6f76aSRasesh Mody .nb_align = 128 /* lowest common multiple */ 12972ea6f76aSRasesh Mody }; 12982ea6f76aSRasesh Mody 12992ea6f76aSRasesh Mody static const struct rte_eth_desc_lim qede_tx_desc_lim = { 1300c008e17bSHarish Patil .nb_max = 0x8000, /* 32K */ 13012ea6f76aSRasesh Mody .nb_min = 256, 130229540be7SHarish Patil .nb_align = 256, 130329540be7SHarish Patil .nb_seg_max = ETH_TX_MAX_BDS_PER_LSO_PACKET, 130429540be7SHarish Patil .nb_mtu_seg_max = ETH_TX_MAX_BDS_PER_NON_LSO_PACKET 13052ea6f76aSRasesh Mody }; 13062ea6f76aSRasesh Mody 1307bdad90d1SIvan Ilchenko static int 13082ea6f76aSRasesh Mody qede_dev_info_get(struct rte_eth_dev *eth_dev, 13092ea6f76aSRasesh Mody struct rte_eth_dev_info *dev_info) 13102ea6f76aSRasesh Mody { 13112ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 13122ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 131364c239b7SHarish Patil struct qed_link_output link; 13141ea56b80SHarish Patil uint32_t speed_cap = 0; 13152ea6f76aSRasesh Mody 13162ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 13172ea6f76aSRasesh Mody 1318f6033f24SHarish Patil dev_info->min_rx_bufsize = (uint32_t)QEDE_MIN_RX_BUFF_SIZE; 13192ea6f76aSRasesh Mody dev_info->max_rx_pktlen = (uint32_t)ETH_TX_MAX_NON_LSO_PKT_LEN; 13202ea6f76aSRasesh Mody dev_info->rx_desc_lim = qede_rx_desc_lim; 13212ea6f76aSRasesh Mody dev_info->tx_desc_lim = qede_tx_desc_lim; 1322528fcfabSHarish Patil 1323528fcfabSHarish Patil if (IS_PF(edev)) 1324528fcfabSHarish Patil dev_info->max_rx_queues = (uint16_t)RTE_MIN( 1325528fcfabSHarish Patil QEDE_MAX_RSS_CNT(qdev), QEDE_PF_NUM_CONNS / 2); 1326528fcfabSHarish Patil else 1327528fcfabSHarish Patil dev_info->max_rx_queues = (uint16_t)RTE_MIN( 1328528fcfabSHarish Patil QEDE_MAX_RSS_CNT(qdev), ECORE_MAX_VF_CHAINS_PER_PF); 13298de0c420SShahed Shaikh /* Since CMT mode internally doubles the number of queues */ 13308de0c420SShahed Shaikh if (ECORE_IS_CMT(edev)) 13318de0c420SShahed Shaikh dev_info->max_rx_queues = dev_info->max_rx_queues / 2; 13328de0c420SShahed Shaikh 13332ea6f76aSRasesh Mody dev_info->max_tx_queues = dev_info->max_rx_queues; 1334528fcfabSHarish Patil 13353320ca8cSRasesh Mody dev_info->max_mac_addrs = qdev->dev_info.num_mac_filters; 133686a2265eSRasesh Mody dev_info->max_vfs = 0; 13375cdd769aSRasesh Mody dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE; 13387ab35bf6SHarish Patil dev_info->hash_key_size = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); 13392ea6f76aSRasesh Mody dev_info->flow_type_rss_offloads = (uint64_t)QEDE_RSS_OFFLOAD_ALL; 1340946dfd18SHarish Patil dev_info->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM | 13412ea6f76aSRasesh Mody DEV_RX_OFFLOAD_UDP_CKSUM | 13423d4bb441SHarish Patil DEV_RX_OFFLOAD_TCP_CKSUM | 134329540be7SHarish Patil DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | 1344946dfd18SHarish Patil DEV_RX_OFFLOAD_TCP_LRO | 134570815c9eSFerruh Yigit DEV_RX_OFFLOAD_KEEP_CRC | 1346946dfd18SHarish Patil DEV_RX_OFFLOAD_SCATTER | 1347946dfd18SHarish Patil DEV_RX_OFFLOAD_JUMBO_FRAME | 1348946dfd18SHarish Patil DEV_RX_OFFLOAD_VLAN_FILTER | 13498b945a7fSPavan Nikhilesh DEV_RX_OFFLOAD_VLAN_STRIP | 13508b945a7fSPavan Nikhilesh DEV_RX_OFFLOAD_RSS_HASH); 1351946dfd18SHarish Patil dev_info->rx_queue_offload_capa = 0; 135229540be7SHarish Patil 1353946dfd18SHarish Patil /* TX offloads are on a per-packet basis, so it is applicable 1354946dfd18SHarish Patil * to both at port and queue levels. 1355946dfd18SHarish Patil */ 13562ea6f76aSRasesh Mody dev_info->tx_offload_capa = (DEV_TX_OFFLOAD_VLAN_INSERT | 13572ea6f76aSRasesh Mody DEV_TX_OFFLOAD_IPV4_CKSUM | 13582ea6f76aSRasesh Mody DEV_TX_OFFLOAD_UDP_CKSUM | 13593d4bb441SHarish Patil DEV_TX_OFFLOAD_TCP_CKSUM | 136029540be7SHarish Patil DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | 1361946dfd18SHarish Patil DEV_TX_OFFLOAD_MULTI_SEGS | 136229540be7SHarish Patil DEV_TX_OFFLOAD_TCP_TSO | 1363d378cefaSShahed Shaikh DEV_TX_OFFLOAD_VXLAN_TNL_TSO | 1364d378cefaSShahed Shaikh DEV_TX_OFFLOAD_GENEVE_TNL_TSO); 1365946dfd18SHarish Patil dev_info->tx_queue_offload_capa = dev_info->tx_offload_capa; 1366946dfd18SHarish Patil 1367946dfd18SHarish Patil dev_info->default_txconf = (struct rte_eth_txconf) { 136803803462SRasesh Mody .offloads = DEV_TX_OFFLOAD_MULTI_SEGS, 1369946dfd18SHarish Patil }; 1370946dfd18SHarish Patil 1371946dfd18SHarish Patil dev_info->default_rxconf = (struct rte_eth_rxconf) { 1372946dfd18SHarish Patil /* Packets are always dropped if no descriptors are available */ 1373946dfd18SHarish Patil .rx_drop_en = 1, 1374048a68edSShahed Shaikh .offloads = 0, 1375946dfd18SHarish Patil }; 13762ea6f76aSRasesh Mody 137764c239b7SHarish Patil memset(&link, 0, sizeof(struct qed_link_output)); 137864c239b7SHarish Patil qdev->ops->common->get_link(edev, &link); 13791ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) 13801ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_1G; 13811ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) 13821ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_10G; 13831ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) 13841ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_25G; 13851ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) 13861ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_40G; 13871ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) 13881ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_50G; 13891ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) 13901ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_100G; 13911ea56b80SHarish Patil dev_info->speed_capa = speed_cap; 1392bdad90d1SIvan Ilchenko 1393bdad90d1SIvan Ilchenko return 0; 13942ea6f76aSRasesh Mody } 13952ea6f76aSRasesh Mody 13962ea6f76aSRasesh Mody /* return 0 means link status changed, -1 means not changed */ 13978aab5d6fSRasesh Mody int 13982ea6f76aSRasesh Mody qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete) 13992ea6f76aSRasesh Mody { 14002ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 14012ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 1402c6034a20SShahed Shaikh struct qed_link_output q_link; 1403c6034a20SShahed Shaikh struct rte_eth_link link; 14042ea6f76aSRasesh Mody uint16_t link_duplex; 14052ea6f76aSRasesh Mody 1406c6034a20SShahed Shaikh memset(&q_link, 0, sizeof(q_link)); 1407c6034a20SShahed Shaikh memset(&link, 0, sizeof(link)); 1408c6034a20SShahed Shaikh 1409c6034a20SShahed Shaikh qdev->ops->common->get_link(edev, &q_link); 14102ea6f76aSRasesh Mody 14112ea6f76aSRasesh Mody /* Link Speed */ 1412c6034a20SShahed Shaikh link.link_speed = q_link.speed; 14132ea6f76aSRasesh Mody 14142ea6f76aSRasesh Mody /* Link Mode */ 1415c6034a20SShahed Shaikh switch (q_link.duplex) { 14162ea6f76aSRasesh Mody case QEDE_DUPLEX_HALF: 14172ea6f76aSRasesh Mody link_duplex = ETH_LINK_HALF_DUPLEX; 14182ea6f76aSRasesh Mody break; 14192ea6f76aSRasesh Mody case QEDE_DUPLEX_FULL: 14202ea6f76aSRasesh Mody link_duplex = ETH_LINK_FULL_DUPLEX; 14212ea6f76aSRasesh Mody break; 14222ea6f76aSRasesh Mody case QEDE_DUPLEX_UNKNOWN: 14232ea6f76aSRasesh Mody default: 14242ea6f76aSRasesh Mody link_duplex = -1; 14252ea6f76aSRasesh Mody } 1426c6034a20SShahed Shaikh link.link_duplex = link_duplex; 14272ea6f76aSRasesh Mody 14282ea6f76aSRasesh Mody /* Link Status */ 1429c6034a20SShahed Shaikh link.link_status = q_link.link_up ? ETH_LINK_UP : ETH_LINK_DOWN; 14302ea6f76aSRasesh Mody 14312ea6f76aSRasesh Mody /* AN */ 1432c6034a20SShahed Shaikh link.link_autoneg = (q_link.supported_caps & QEDE_SUPPORTED_AUTONEG) ? 14332ea6f76aSRasesh Mody ETH_LINK_AUTONEG : ETH_LINK_FIXED; 14342ea6f76aSRasesh Mody 14352ea6f76aSRasesh Mody DP_INFO(edev, "Link - Speed %u Mode %u AN %u Status %u\n", 1436c6034a20SShahed Shaikh link.link_speed, link.link_duplex, 1437c6034a20SShahed Shaikh link.link_autoneg, link.link_status); 14382ea6f76aSRasesh Mody 1439c6034a20SShahed Shaikh return rte_eth_linkstatus_set(eth_dev, &link); 14402ea6f76aSRasesh Mody } 14412ea6f76aSRasesh Mody 14429039c812SAndrew Rybchenko static int qede_promiscuous_enable(struct rte_eth_dev *eth_dev) 14432ea6f76aSRasesh Mody { 14442ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 14452ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 1446dcf3d57fSStephen Hemminger enum qed_filter_rx_mode_type type = QED_FILTER_RX_MODE_TYPE_PROMISC; 14479039c812SAndrew Rybchenko enum _ecore_status_t ecore_status; 14482ea6f76aSRasesh Mody 14492ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 14502ea6f76aSRasesh Mody 14512ea6f76aSRasesh Mody if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1) 14522ea6f76aSRasesh Mody type |= QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC; 14532ea6f76aSRasesh Mody 14549039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, type); 14559039c812SAndrew Rybchenko 14569039c812SAndrew Rybchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 14572ea6f76aSRasesh Mody } 14582ea6f76aSRasesh Mody 14599039c812SAndrew Rybchenko static int qede_promiscuous_disable(struct rte_eth_dev *eth_dev) 14602ea6f76aSRasesh Mody { 14612ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 14622ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 14639039c812SAndrew Rybchenko enum _ecore_status_t ecore_status; 14642ea6f76aSRasesh Mody 14652ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 14662ea6f76aSRasesh Mody 14672ea6f76aSRasesh Mody if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1) 14689039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 14692ea6f76aSRasesh Mody QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC); 14702ea6f76aSRasesh Mody else 14719039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 147277fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_REGULAR); 14739039c812SAndrew Rybchenko 14749039c812SAndrew Rybchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 14752ea6f76aSRasesh Mody } 14762ea6f76aSRasesh Mody 14772af14ca7SHarish Patil static void qede_poll_sp_sb_cb(void *param) 14782af14ca7SHarish Patil { 14792af14ca7SHarish Patil struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 14802af14ca7SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 14812af14ca7SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 14822af14ca7SHarish Patil int rc; 14832af14ca7SHarish Patil 14842af14ca7SHarish Patil qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 14852af14ca7SHarish Patil qede_interrupt_action(&edev->hwfns[1]); 14862af14ca7SHarish Patil 14870833120fSShahed Shaikh rc = rte_eal_alarm_set(QEDE_SP_TIMER_PERIOD, 14882af14ca7SHarish Patil qede_poll_sp_sb_cb, 14892af14ca7SHarish Patil (void *)eth_dev); 14902af14ca7SHarish Patil if (rc != 0) { 14912af14ca7SHarish Patil DP_ERR(edev, "Unable to start periodic" 14922af14ca7SHarish Patil " timer rc %d\n", rc); 14932af14ca7SHarish Patil } 14942af14ca7SHarish Patil } 14952af14ca7SHarish Patil 14962ea6f76aSRasesh Mody static void qede_dev_close(struct rte_eth_dev *eth_dev) 14972ea6f76aSRasesh Mody { 1498c0802544SFerruh Yigit struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 1499dbac54c2SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1500dbac54c2SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 15012ea6f76aSRasesh Mody 15022ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 15032ea6f76aSRasesh Mody 15042ea6f76aSRasesh Mody /* dev_stop() shall cleanup fp resources in hw but without releasing 15052ea6f76aSRasesh Mody * dma memories and sw structures so that dev_start() can be called 15062ea6f76aSRasesh Mody * by the app without reconfiguration. However, in dev_close() we 15072ea6f76aSRasesh Mody * can release all the resources and device can be brought up newly 15082ea6f76aSRasesh Mody */ 15094c4bdadfSHarish Patil if (eth_dev->data->dev_started) 15102ea6f76aSRasesh Mody qede_dev_stop(eth_dev); 15112ea6f76aSRasesh Mody 15129a6d30aeSHarish Patil qede_stop_vport(edev); 1513dd28bc8cSHarish Patil qdev->vport_started = false; 15144c4bdadfSHarish Patil qede_fdir_dealloc_resc(eth_dev); 1515dbac54c2SHarish Patil qede_dealloc_fp_resc(eth_dev); 15162ea6f76aSRasesh Mody 15174c4bdadfSHarish Patil eth_dev->data->nb_rx_queues = 0; 15184c4bdadfSHarish Patil eth_dev->data->nb_tx_queues = 0; 15194c4bdadfSHarish Patil 1520dd28bc8cSHarish Patil /* Bring the link down */ 1521dd28bc8cSHarish Patil qede_dev_set_link_state(eth_dev, false); 15222ea6f76aSRasesh Mody qdev->ops->common->slowpath_stop(edev); 15232ea6f76aSRasesh Mody qdev->ops->common->remove(edev); 1524d4b7f673SJan Blunck rte_intr_disable(&pci_dev->intr_handle); 15254eee1bbfSShahed Shaikh 15264eee1bbfSShahed Shaikh switch (pci_dev->intr_handle.type) { 15274eee1bbfSShahed Shaikh case RTE_INTR_HANDLE_UIO_INTX: 15284eee1bbfSShahed Shaikh case RTE_INTR_HANDLE_VFIO_LEGACY: 1529d4b7f673SJan Blunck rte_intr_callback_unregister(&pci_dev->intr_handle, 15304eee1bbfSShahed Shaikh qede_interrupt_handler_intx, 15314eee1bbfSShahed Shaikh (void *)eth_dev); 15324eee1bbfSShahed Shaikh break; 15334eee1bbfSShahed Shaikh default: 15344eee1bbfSShahed Shaikh rte_intr_callback_unregister(&pci_dev->intr_handle, 15354eee1bbfSShahed Shaikh qede_interrupt_handler, 15364eee1bbfSShahed Shaikh (void *)eth_dev); 15374eee1bbfSShahed Shaikh } 15384eee1bbfSShahed Shaikh 1539c0845c33SRasesh Mody if (ECORE_IS_CMT(edev)) 15402af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, (void *)eth_dev); 15412ea6f76aSRasesh Mody } 15422ea6f76aSRasesh Mody 1543d5b0924bSMatan Azrad static int 15442ea6f76aSRasesh Mody qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats) 15452ea6f76aSRasesh Mody { 15462ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 15472ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 15482ea6f76aSRasesh Mody struct ecore_eth_stats stats; 15490aa3e7b9SShahed Shaikh unsigned int i = 0, j = 0, qid, idx, hw_fn; 155006e83c4eSRasesh Mody unsigned int rxq_stat_cntrs, txq_stat_cntrs; 15517634c5f9SRasesh Mody struct qede_tx_queue *txq; 15522ea6f76aSRasesh Mody 15534c4bdadfSHarish Patil ecore_get_vport_stats(edev, &stats); 15542ea6f76aSRasesh Mody 15552ea6f76aSRasesh Mody /* RX Stats */ 15569c1aa3e1SRasesh Mody eth_stats->ipackets = stats.common.rx_ucast_pkts + 15579c1aa3e1SRasesh Mody stats.common.rx_mcast_pkts + stats.common.rx_bcast_pkts; 15582ea6f76aSRasesh Mody 15599c1aa3e1SRasesh Mody eth_stats->ibytes = stats.common.rx_ucast_bytes + 15609c1aa3e1SRasesh Mody stats.common.rx_mcast_bytes + stats.common.rx_bcast_bytes; 15612ea6f76aSRasesh Mody 15629c1aa3e1SRasesh Mody eth_stats->ierrors = stats.common.rx_crc_errors + 15639c1aa3e1SRasesh Mody stats.common.rx_align_errors + 15649c1aa3e1SRasesh Mody stats.common.rx_carrier_errors + 15659c1aa3e1SRasesh Mody stats.common.rx_oversize_packets + 15669c1aa3e1SRasesh Mody stats.common.rx_jabbers + stats.common.rx_undersize_packets; 15672ea6f76aSRasesh Mody 15689c1aa3e1SRasesh Mody eth_stats->rx_nombuf = stats.common.no_buff_discards; 15692ea6f76aSRasesh Mody 15709c1aa3e1SRasesh Mody eth_stats->imissed = stats.common.mftag_filter_discards + 15719c1aa3e1SRasesh Mody stats.common.mac_filter_discards + 15729c1aa3e1SRasesh Mody stats.common.no_buff_discards + 15739c1aa3e1SRasesh Mody stats.common.brb_truncates + stats.common.brb_discards; 15742ea6f76aSRasesh Mody 15752ea6f76aSRasesh Mody /* TX stats */ 15769c1aa3e1SRasesh Mody eth_stats->opackets = stats.common.tx_ucast_pkts + 15779c1aa3e1SRasesh Mody stats.common.tx_mcast_pkts + stats.common.tx_bcast_pkts; 15782ea6f76aSRasesh Mody 15799c1aa3e1SRasesh Mody eth_stats->obytes = stats.common.tx_ucast_bytes + 15809c1aa3e1SRasesh Mody stats.common.tx_mcast_bytes + stats.common.tx_bcast_bytes; 15812ea6f76aSRasesh Mody 15829c1aa3e1SRasesh Mody eth_stats->oerrors = stats.common.tx_err_drop_pkts; 15837634c5f9SRasesh Mody 15847634c5f9SRasesh Mody /* Queue stats */ 15858de0c420SShahed Shaikh rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(eth_dev), 158606e83c4eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 15878de0c420SShahed Shaikh txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(eth_dev), 158806e83c4eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 15898de0c420SShahed Shaikh if (rxq_stat_cntrs != (unsigned int)QEDE_RSS_COUNT(eth_dev) || 15908de0c420SShahed Shaikh txq_stat_cntrs != (unsigned int)QEDE_TSS_COUNT(eth_dev)) 159106e83c4eSRasesh Mody DP_VERBOSE(edev, ECORE_MSG_DEBUG, 159206e83c4eSRasesh Mody "Not all the queue stats will be displayed. Set" 159306e83c4eSRasesh Mody " RTE_ETHDEV_QUEUE_STAT_CNTRS config param" 159406e83c4eSRasesh Mody " appropriately and retry.\n"); 159506e83c4eSRasesh Mody 15968de0c420SShahed Shaikh for (qid = 0; qid < eth_dev->data->nb_rx_queues; qid++) { 15970aa3e7b9SShahed Shaikh eth_stats->q_ipackets[i] = 0; 15980aa3e7b9SShahed Shaikh eth_stats->q_errors[i] = 0; 15990aa3e7b9SShahed Shaikh 16000aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 16010aa3e7b9SShahed Shaikh idx = qid * edev->num_hwfns + hw_fn; 16020aa3e7b9SShahed Shaikh 16030aa3e7b9SShahed Shaikh eth_stats->q_ipackets[i] += 16040aa3e7b9SShahed Shaikh *(uint64_t *) 16050aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16067634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16077634c5f9SRasesh Mody rcv_pkts)); 16080aa3e7b9SShahed Shaikh eth_stats->q_errors[i] += 16090aa3e7b9SShahed Shaikh *(uint64_t *) 16100aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16117634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16127634c5f9SRasesh Mody rx_hw_errors)) + 16130aa3e7b9SShahed Shaikh *(uint64_t *) 16140aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16157634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16167634c5f9SRasesh Mody rx_alloc_errors)); 16170aa3e7b9SShahed Shaikh } 16180aa3e7b9SShahed Shaikh 16197634c5f9SRasesh Mody i++; 162006e83c4eSRasesh Mody if (i == rxq_stat_cntrs) 162106e83c4eSRasesh Mody break; 162206e83c4eSRasesh Mody } 16237634c5f9SRasesh Mody 16248de0c420SShahed Shaikh for (qid = 0; qid < eth_dev->data->nb_tx_queues; qid++) { 16250aa3e7b9SShahed Shaikh eth_stats->q_opackets[j] = 0; 16260aa3e7b9SShahed Shaikh 16270aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 16280aa3e7b9SShahed Shaikh idx = qid * edev->num_hwfns + hw_fn; 16290aa3e7b9SShahed Shaikh 16300aa3e7b9SShahed Shaikh txq = qdev->fp_array[idx].txq; 16310aa3e7b9SShahed Shaikh eth_stats->q_opackets[j] += 16327634c5f9SRasesh Mody *((uint64_t *)(uintptr_t) 16337634c5f9SRasesh Mody (((uint64_t)(uintptr_t)(txq)) + 16347634c5f9SRasesh Mody offsetof(struct qede_tx_queue, 16357634c5f9SRasesh Mody xmit_pkts))); 16360aa3e7b9SShahed Shaikh } 16370aa3e7b9SShahed Shaikh 16387634c5f9SRasesh Mody j++; 163906e83c4eSRasesh Mody if (j == txq_stat_cntrs) 164006e83c4eSRasesh Mody break; 16417634c5f9SRasesh Mody } 1642d5b0924bSMatan Azrad 1643d5b0924bSMatan Azrad return 0; 16447634c5f9SRasesh Mody } 16457634c5f9SRasesh Mody 16467634c5f9SRasesh Mody static unsigned 16477634c5f9SRasesh Mody qede_get_xstats_count(struct qede_dev *qdev) { 16488de0c420SShahed Shaikh struct rte_eth_dev *dev = (struct rte_eth_dev *)qdev->ethdev; 16498de0c420SShahed Shaikh 16509c1aa3e1SRasesh Mody if (ECORE_IS_BB(&qdev->edev)) 16517634c5f9SRasesh Mody return RTE_DIM(qede_xstats_strings) + 16529c1aa3e1SRasesh Mody RTE_DIM(qede_bb_xstats_strings) + 16539c1aa3e1SRasesh Mody (RTE_DIM(qede_rxq_xstats_strings) * 16548de0c420SShahed Shaikh QEDE_RSS_COUNT(dev) * qdev->edev.num_hwfns); 16559c1aa3e1SRasesh Mody else 16569c1aa3e1SRasesh Mody return RTE_DIM(qede_xstats_strings) + 16579c1aa3e1SRasesh Mody RTE_DIM(qede_ah_xstats_strings) + 165806e83c4eSRasesh Mody (RTE_DIM(qede_rxq_xstats_strings) * 16598de0c420SShahed Shaikh QEDE_RSS_COUNT(dev)); 1660d1216e22SRasesh Mody } 16612ea6f76aSRasesh Mody 1662d1216e22SRasesh Mody static int 1663dd2c630aSFerruh Yigit qede_get_xstats_names(struct rte_eth_dev *dev, 1664af785e47SRasesh Mody struct rte_eth_xstat_name *xstats_names, 1665af785e47SRasesh Mody __rte_unused unsigned int limit) 1666d1216e22SRasesh Mody { 16677634c5f9SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 16689c1aa3e1SRasesh Mody struct ecore_dev *edev = &qdev->edev; 16697634c5f9SRasesh Mody const unsigned int stat_cnt = qede_get_xstats_count(qdev); 16700aa3e7b9SShahed Shaikh unsigned int i, qid, hw_fn, stat_idx = 0; 1671d1216e22SRasesh Mody 16720aa3e7b9SShahed Shaikh if (xstats_names == NULL) 16730aa3e7b9SShahed Shaikh return stat_cnt; 16740aa3e7b9SShahed Shaikh 16757634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) { 16766723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 16776723c0fcSBruce Richardson qede_xstats_strings[i].name, 16786723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 16797634c5f9SRasesh Mody stat_idx++; 16807634c5f9SRasesh Mody } 16817634c5f9SRasesh Mody 16829c1aa3e1SRasesh Mody if (ECORE_IS_BB(edev)) { 16839c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_bb_xstats_strings); i++) { 16846723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 16856723c0fcSBruce Richardson qede_bb_xstats_strings[i].name, 16866723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 16879c1aa3e1SRasesh Mody stat_idx++; 16889c1aa3e1SRasesh Mody } 16899c1aa3e1SRasesh Mody } else { 16909c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_ah_xstats_strings); i++) { 16916723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 16926723c0fcSBruce Richardson qede_ah_xstats_strings[i].name, 16936723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 16949c1aa3e1SRasesh Mody stat_idx++; 16959c1aa3e1SRasesh Mody } 16969c1aa3e1SRasesh Mody } 16979c1aa3e1SRasesh Mody 16980aa3e7b9SShahed Shaikh for (qid = 0; qid < QEDE_RSS_COUNT(dev); qid++) { 16990aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 17007634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) { 17017634c5f9SRasesh Mody snprintf(xstats_names[stat_idx].name, 17020aa3e7b9SShahed Shaikh RTE_ETH_XSTATS_NAME_SIZE, 17030aa3e7b9SShahed Shaikh "%.4s%d.%d%s", 17040aa3e7b9SShahed Shaikh qede_rxq_xstats_strings[i].name, 17050aa3e7b9SShahed Shaikh hw_fn, qid, 17067634c5f9SRasesh Mody qede_rxq_xstats_strings[i].name + 4); 17077634c5f9SRasesh Mody stat_idx++; 17087634c5f9SRasesh Mody } 17097634c5f9SRasesh Mody } 17107634c5f9SRasesh Mody } 1711d1216e22SRasesh Mody 1712d1216e22SRasesh Mody return stat_cnt; 1713d1216e22SRasesh Mody } 1714d1216e22SRasesh Mody 1715d1216e22SRasesh Mody static int 1716d1216e22SRasesh Mody qede_get_xstats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, 1717d1216e22SRasesh Mody unsigned int n) 1718d1216e22SRasesh Mody { 1719d1216e22SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 1720d1216e22SRasesh Mody struct ecore_dev *edev = &qdev->edev; 1721d1216e22SRasesh Mody struct ecore_eth_stats stats; 17227634c5f9SRasesh Mody const unsigned int num = qede_get_xstats_count(qdev); 17230aa3e7b9SShahed Shaikh unsigned int i, qid, hw_fn, fpidx, stat_idx = 0; 1724d1216e22SRasesh Mody 1725d1216e22SRasesh Mody if (n < num) 1726d1216e22SRasesh Mody return num; 1727d1216e22SRasesh Mody 17284c4bdadfSHarish Patil ecore_get_vport_stats(edev, &stats); 1729d1216e22SRasesh Mody 17307634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) { 17317634c5f9SRasesh Mody xstats[stat_idx].value = *(uint64_t *)(((char *)&stats) + 17327634c5f9SRasesh Mody qede_xstats_strings[i].offset); 1733513c78aeSOlivier Matz xstats[stat_idx].id = stat_idx; 17347634c5f9SRasesh Mody stat_idx++; 17357634c5f9SRasesh Mody } 1736d1216e22SRasesh Mody 17379c1aa3e1SRasesh Mody if (ECORE_IS_BB(edev)) { 17389c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_bb_xstats_strings); i++) { 17399c1aa3e1SRasesh Mody xstats[stat_idx].value = 17409c1aa3e1SRasesh Mody *(uint64_t *)(((char *)&stats) + 17419c1aa3e1SRasesh Mody qede_bb_xstats_strings[i].offset); 17429c1aa3e1SRasesh Mody xstats[stat_idx].id = stat_idx; 17439c1aa3e1SRasesh Mody stat_idx++; 17449c1aa3e1SRasesh Mody } 17459c1aa3e1SRasesh Mody } else { 17469c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_ah_xstats_strings); i++) { 17479c1aa3e1SRasesh Mody xstats[stat_idx].value = 17489c1aa3e1SRasesh Mody *(uint64_t *)(((char *)&stats) + 17499c1aa3e1SRasesh Mody qede_ah_xstats_strings[i].offset); 17509c1aa3e1SRasesh Mody xstats[stat_idx].id = stat_idx; 17519c1aa3e1SRasesh Mody stat_idx++; 17529c1aa3e1SRasesh Mody } 17539c1aa3e1SRasesh Mody } 17549c1aa3e1SRasesh Mody 17550aa3e7b9SShahed Shaikh for (qid = 0; qid < dev->data->nb_rx_queues; qid++) { 17560aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 17577634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) { 17580aa3e7b9SShahed Shaikh fpidx = qid * edev->num_hwfns + hw_fn; 17598de0c420SShahed Shaikh xstats[stat_idx].value = *(uint64_t *) 17600aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[fpidx].rxq)) + 17617634c5f9SRasesh Mody qede_rxq_xstats_strings[i].offset); 1762513c78aeSOlivier Matz xstats[stat_idx].id = stat_idx; 17637634c5f9SRasesh Mody stat_idx++; 17647634c5f9SRasesh Mody } 17650aa3e7b9SShahed Shaikh 17660aa3e7b9SShahed Shaikh } 17677634c5f9SRasesh Mody } 17687634c5f9SRasesh Mody 17697634c5f9SRasesh Mody return stat_idx; 1770d1216e22SRasesh Mody } 1771d1216e22SRasesh Mody 17729970a9adSIgor Romanov static int 1773d1216e22SRasesh Mody qede_reset_xstats(struct rte_eth_dev *dev) 1774d1216e22SRasesh Mody { 1775d1216e22SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 1776d1216e22SRasesh Mody struct ecore_dev *edev = &qdev->edev; 1777d1216e22SRasesh Mody 1778d1216e22SRasesh Mody ecore_reset_vport_stats(edev); 1779ce26be6eSRasesh Mody qede_reset_queue_stats(qdev, true); 17809970a9adSIgor Romanov 17819970a9adSIgor Romanov return 0; 17822ea6f76aSRasesh Mody } 17832ea6f76aSRasesh Mody 17842ea6f76aSRasesh Mody int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up) 17852ea6f76aSRasesh Mody { 17862ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 17872ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 17882ea6f76aSRasesh Mody struct qed_link_params link_params; 17892ea6f76aSRasesh Mody int rc; 17902ea6f76aSRasesh Mody 17912ea6f76aSRasesh Mody DP_INFO(edev, "setting link state %d\n", link_up); 17922ea6f76aSRasesh Mody memset(&link_params, 0, sizeof(link_params)); 17932ea6f76aSRasesh Mody link_params.link_up = link_up; 17942ea6f76aSRasesh Mody rc = qdev->ops->common->set_link(edev, &link_params); 17952ea6f76aSRasesh Mody if (rc != ECORE_SUCCESS) 17962ea6f76aSRasesh Mody DP_ERR(edev, "Unable to set link state %d\n", link_up); 17972ea6f76aSRasesh Mody 17982ea6f76aSRasesh Mody return rc; 17992ea6f76aSRasesh Mody } 18002ea6f76aSRasesh Mody 18012ea6f76aSRasesh Mody static int qede_dev_set_link_up(struct rte_eth_dev *eth_dev) 18022ea6f76aSRasesh Mody { 18032ea6f76aSRasesh Mody return qede_dev_set_link_state(eth_dev, true); 18042ea6f76aSRasesh Mody } 18052ea6f76aSRasesh Mody 18062ea6f76aSRasesh Mody static int qede_dev_set_link_down(struct rte_eth_dev *eth_dev) 18072ea6f76aSRasesh Mody { 18082ea6f76aSRasesh Mody return qede_dev_set_link_state(eth_dev, false); 18092ea6f76aSRasesh Mody } 18102ea6f76aSRasesh Mody 18119970a9adSIgor Romanov static int qede_reset_stats(struct rte_eth_dev *eth_dev) 18125cdd769aSRasesh Mody { 18135cdd769aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 18145cdd769aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 18155cdd769aSRasesh Mody 18165cdd769aSRasesh Mody ecore_reset_vport_stats(edev); 1817ce26be6eSRasesh Mody qede_reset_queue_stats(qdev, false); 18189970a9adSIgor Romanov 18199970a9adSIgor Romanov return 0; 18205cdd769aSRasesh Mody } 18215cdd769aSRasesh Mody 1822ca041cd4SIvan Ilchenko static int qede_allmulticast_enable(struct rte_eth_dev *eth_dev) 18232ea6f76aSRasesh Mody { 18242ea6f76aSRasesh Mody enum qed_filter_rx_mode_type type = 18252ea6f76aSRasesh Mody QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC; 1826ca041cd4SIvan Ilchenko enum _ecore_status_t ecore_status; 18272ea6f76aSRasesh Mody 18282ea6f76aSRasesh Mody if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1) 18292ea6f76aSRasesh Mody type |= QED_FILTER_RX_MODE_TYPE_PROMISC; 18302ea6f76aSRasesh Mody 1831ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, type); 1832ca041cd4SIvan Ilchenko 1833ca041cd4SIvan Ilchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 18342ea6f76aSRasesh Mody } 18352ea6f76aSRasesh Mody 1836ca041cd4SIvan Ilchenko static int qede_allmulticast_disable(struct rte_eth_dev *eth_dev) 18372ea6f76aSRasesh Mody { 1838ca041cd4SIvan Ilchenko enum _ecore_status_t ecore_status; 1839ca041cd4SIvan Ilchenko 18402ea6f76aSRasesh Mody if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1) 1841ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 184277fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_PROMISC); 18432ea6f76aSRasesh Mody else 1844ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 184577fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_REGULAR); 1846ca041cd4SIvan Ilchenko 1847ca041cd4SIvan Ilchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 18482ea6f76aSRasesh Mody } 18492ea6f76aSRasesh Mody 1850413ecf29SHarish Patil static int 18516d13ea8eSOlivier Matz qede_set_mc_addr_list(struct rte_eth_dev *eth_dev, 18526d13ea8eSOlivier Matz struct rte_ether_addr *mc_addrs, 1853413ecf29SHarish Patil uint32_t mc_addrs_num) 1854413ecf29SHarish Patil { 1855413ecf29SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1856413ecf29SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1857413ecf29SHarish Patil uint8_t i; 1858413ecf29SHarish Patil 1859413ecf29SHarish Patil if (mc_addrs_num > ECORE_MAX_MC_ADDRS) { 1860413ecf29SHarish Patil DP_ERR(edev, "Reached max multicast filters limit," 1861413ecf29SHarish Patil "Please enable multicast promisc mode\n"); 1862413ecf29SHarish Patil return -ENOSPC; 1863413ecf29SHarish Patil } 1864413ecf29SHarish Patil 1865413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) { 1866538da7a1SOlivier Matz if (!rte_is_multicast_ether_addr(&mc_addrs[i])) { 1867413ecf29SHarish Patil DP_ERR(edev, "Not a valid multicast MAC\n"); 1868413ecf29SHarish Patil return -EINVAL; 1869413ecf29SHarish Patil } 1870413ecf29SHarish Patil } 1871413ecf29SHarish Patil 1872413ecf29SHarish Patil /* Flush all existing entries */ 1873413ecf29SHarish Patil if (qede_del_mcast_filters(eth_dev)) 1874413ecf29SHarish Patil return -1; 1875413ecf29SHarish Patil 1876413ecf29SHarish Patil /* Set new mcast list */ 1877413ecf29SHarish Patil return qede_add_mcast_filters(eth_dev, mc_addrs, mc_addrs_num); 1878413ecf29SHarish Patil } 1879413ecf29SHarish Patil 1880d121a6b5SRasesh Mody /* Update MTU via vport-update without doing port restart. 1881d121a6b5SRasesh Mody * The vport must be deactivated before calling this API. 1882d121a6b5SRasesh Mody */ 1883d121a6b5SRasesh Mody int qede_update_mtu(struct rte_eth_dev *eth_dev, uint16_t mtu) 1884d121a6b5SRasesh Mody { 1885d121a6b5SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1886d121a6b5SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1887d121a6b5SRasesh Mody struct ecore_hwfn *p_hwfn; 1888d121a6b5SRasesh Mody int rc; 1889d121a6b5SRasesh Mody int i; 1890d121a6b5SRasesh Mody 1891d121a6b5SRasesh Mody if (IS_PF(edev)) { 1892d121a6b5SRasesh Mody struct ecore_sp_vport_update_params params; 1893d121a6b5SRasesh Mody 1894d121a6b5SRasesh Mody memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 1895d121a6b5SRasesh Mody params.vport_id = 0; 1896d121a6b5SRasesh Mody params.mtu = mtu; 1897d121a6b5SRasesh Mody params.vport_id = 0; 1898d121a6b5SRasesh Mody for_each_hwfn(edev, i) { 1899d121a6b5SRasesh Mody p_hwfn = &edev->hwfns[i]; 1900d121a6b5SRasesh Mody params.opaque_fid = p_hwfn->hw_info.opaque_fid; 1901d121a6b5SRasesh Mody rc = ecore_sp_vport_update(p_hwfn, ¶ms, 1902d121a6b5SRasesh Mody ECORE_SPQ_MODE_EBLOCK, NULL); 1903d121a6b5SRasesh Mody if (rc != ECORE_SUCCESS) 1904d121a6b5SRasesh Mody goto err; 1905d121a6b5SRasesh Mody } 1906d121a6b5SRasesh Mody } else { 1907d121a6b5SRasesh Mody for_each_hwfn(edev, i) { 1908d121a6b5SRasesh Mody p_hwfn = &edev->hwfns[i]; 1909d121a6b5SRasesh Mody rc = ecore_vf_pf_update_mtu(p_hwfn, mtu); 1910d121a6b5SRasesh Mody if (rc == ECORE_INVAL) { 1911d121a6b5SRasesh Mody DP_INFO(edev, "VF MTU Update TLV not supported\n"); 1912d121a6b5SRasesh Mody /* Recreate vport */ 1913d121a6b5SRasesh Mody rc = qede_start_vport(qdev, mtu); 1914d121a6b5SRasesh Mody if (rc != ECORE_SUCCESS) 1915d121a6b5SRasesh Mody goto err; 1916d121a6b5SRasesh Mody 1917d121a6b5SRasesh Mody /* Restore config lost due to vport stop */ 1918d121a6b5SRasesh Mody if (eth_dev->data->promiscuous) 1919d121a6b5SRasesh Mody qede_promiscuous_enable(eth_dev); 1920d121a6b5SRasesh Mody else 1921d121a6b5SRasesh Mody qede_promiscuous_disable(eth_dev); 1922d121a6b5SRasesh Mody 1923d121a6b5SRasesh Mody if (eth_dev->data->all_multicast) 1924d121a6b5SRasesh Mody qede_allmulticast_enable(eth_dev); 1925d121a6b5SRasesh Mody else 1926d121a6b5SRasesh Mody qede_allmulticast_disable(eth_dev); 1927d121a6b5SRasesh Mody 1928d121a6b5SRasesh Mody qede_vlan_offload_set(eth_dev, 1929d121a6b5SRasesh Mody qdev->vlan_offload_mask); 1930d121a6b5SRasesh Mody } else if (rc != ECORE_SUCCESS) { 1931d121a6b5SRasesh Mody goto err; 1932d121a6b5SRasesh Mody } 1933d121a6b5SRasesh Mody } 1934d121a6b5SRasesh Mody } 1935d121a6b5SRasesh Mody DP_INFO(edev, "%s MTU updated to %u\n", IS_PF(edev) ? "PF" : "VF", mtu); 1936d121a6b5SRasesh Mody 1937d121a6b5SRasesh Mody return 0; 1938d121a6b5SRasesh Mody 1939d121a6b5SRasesh Mody err: 1940d121a6b5SRasesh Mody DP_ERR(edev, "Failed to update MTU\n"); 1941d121a6b5SRasesh Mody return -1; 1942d121a6b5SRasesh Mody } 1943d121a6b5SRasesh Mody 19442ea6f76aSRasesh Mody static int qede_flow_ctrl_set(struct rte_eth_dev *eth_dev, 19452ea6f76aSRasesh Mody struct rte_eth_fc_conf *fc_conf) 19462ea6f76aSRasesh Mody { 19472ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 19482ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 19492ea6f76aSRasesh Mody struct qed_link_output current_link; 19502ea6f76aSRasesh Mody struct qed_link_params params; 19512ea6f76aSRasesh Mody 19522ea6f76aSRasesh Mody memset(¤t_link, 0, sizeof(current_link)); 19532ea6f76aSRasesh Mody qdev->ops->common->get_link(edev, ¤t_link); 19542ea6f76aSRasesh Mody 19552ea6f76aSRasesh Mody memset(¶ms, 0, sizeof(params)); 19562ea6f76aSRasesh Mody params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG; 19572ea6f76aSRasesh Mody if (fc_conf->autoneg) { 19582ea6f76aSRasesh Mody if (!(current_link.supported_caps & QEDE_SUPPORTED_AUTONEG)) { 19592ea6f76aSRasesh Mody DP_ERR(edev, "Autoneg not supported\n"); 19602ea6f76aSRasesh Mody return -EINVAL; 19612ea6f76aSRasesh Mody } 19622ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE; 19632ea6f76aSRasesh Mody } 19642ea6f76aSRasesh Mody 19652ea6f76aSRasesh Mody /* Pause is assumed to be supported (SUPPORTED_Pause) */ 19662ea6f76aSRasesh Mody if (fc_conf->mode == RTE_FC_FULL) 19672ea6f76aSRasesh Mody params.pause_config |= (QED_LINK_PAUSE_TX_ENABLE | 19682ea6f76aSRasesh Mody QED_LINK_PAUSE_RX_ENABLE); 19692ea6f76aSRasesh Mody if (fc_conf->mode == RTE_FC_TX_PAUSE) 19702ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_TX_ENABLE; 19712ea6f76aSRasesh Mody if (fc_conf->mode == RTE_FC_RX_PAUSE) 19722ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_RX_ENABLE; 19732ea6f76aSRasesh Mody 19742ea6f76aSRasesh Mody params.link_up = true; 19752ea6f76aSRasesh Mody (void)qdev->ops->common->set_link(edev, ¶ms); 19762ea6f76aSRasesh Mody 19772ea6f76aSRasesh Mody return 0; 19782ea6f76aSRasesh Mody } 19792ea6f76aSRasesh Mody 19802ea6f76aSRasesh Mody static int qede_flow_ctrl_get(struct rte_eth_dev *eth_dev, 19812ea6f76aSRasesh Mody struct rte_eth_fc_conf *fc_conf) 19822ea6f76aSRasesh Mody { 19832ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 19842ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 19852ea6f76aSRasesh Mody struct qed_link_output current_link; 19862ea6f76aSRasesh Mody 19872ea6f76aSRasesh Mody memset(¤t_link, 0, sizeof(current_link)); 19882ea6f76aSRasesh Mody qdev->ops->common->get_link(edev, ¤t_link); 19892ea6f76aSRasesh Mody 19902ea6f76aSRasesh Mody if (current_link.pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE) 19912ea6f76aSRasesh Mody fc_conf->autoneg = true; 19922ea6f76aSRasesh Mody 19932ea6f76aSRasesh Mody if (current_link.pause_config & (QED_LINK_PAUSE_RX_ENABLE | 19942ea6f76aSRasesh Mody QED_LINK_PAUSE_TX_ENABLE)) 19952ea6f76aSRasesh Mody fc_conf->mode = RTE_FC_FULL; 19962ea6f76aSRasesh Mody else if (current_link.pause_config & QED_LINK_PAUSE_RX_ENABLE) 19972ea6f76aSRasesh Mody fc_conf->mode = RTE_FC_RX_PAUSE; 19982ea6f76aSRasesh Mody else if (current_link.pause_config & QED_LINK_PAUSE_TX_ENABLE) 19992ea6f76aSRasesh Mody fc_conf->mode = RTE_FC_TX_PAUSE; 20002ea6f76aSRasesh Mody else 20012ea6f76aSRasesh Mody fc_conf->mode = RTE_FC_NONE; 20022ea6f76aSRasesh Mody 20032ea6f76aSRasesh Mody return 0; 20042ea6f76aSRasesh Mody } 20052ea6f76aSRasesh Mody 20062ea6f76aSRasesh Mody static const uint32_t * 20072ea6f76aSRasesh Mody qede_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev) 20082ea6f76aSRasesh Mody { 20092ea6f76aSRasesh Mody static const uint32_t ptypes[] = { 2010fb88acb5SHarish Patil RTE_PTYPE_L2_ETHER, 2011fb88acb5SHarish Patil RTE_PTYPE_L2_ETHER_VLAN, 20122ea6f76aSRasesh Mody RTE_PTYPE_L3_IPV4, 20132ea6f76aSRasesh Mody RTE_PTYPE_L3_IPV6, 2014fb88acb5SHarish Patil RTE_PTYPE_L4_TCP, 2015fb88acb5SHarish Patil RTE_PTYPE_L4_UDP, 2016fb88acb5SHarish Patil RTE_PTYPE_TUNNEL_VXLAN, 2017fb88acb5SHarish Patil RTE_PTYPE_L4_FRAG, 2018d378cefaSShahed Shaikh RTE_PTYPE_TUNNEL_GENEVE, 2019e1e38962SHarish Patil RTE_PTYPE_TUNNEL_GRE, 2020fb88acb5SHarish Patil /* Inner */ 2021fb88acb5SHarish Patil RTE_PTYPE_INNER_L2_ETHER, 2022fb88acb5SHarish Patil RTE_PTYPE_INNER_L2_ETHER_VLAN, 2023fb88acb5SHarish Patil RTE_PTYPE_INNER_L3_IPV4, 2024fb88acb5SHarish Patil RTE_PTYPE_INNER_L3_IPV6, 2025fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_TCP, 2026fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_UDP, 2027fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_FRAG, 20282ea6f76aSRasesh Mody RTE_PTYPE_UNKNOWN 20292ea6f76aSRasesh Mody }; 20302ea6f76aSRasesh Mody 20318de0c420SShahed Shaikh if (eth_dev->rx_pkt_burst == qede_recv_pkts || 203281f88049SShahed Shaikh eth_dev->rx_pkt_burst == qede_recv_pkts_regular || 20338de0c420SShahed Shaikh eth_dev->rx_pkt_burst == qede_recv_pkts_cmt) 20342ea6f76aSRasesh Mody return ptypes; 20352ea6f76aSRasesh Mody 20362ea6f76aSRasesh Mody return NULL; 20372ea6f76aSRasesh Mody } 20382ea6f76aSRasesh Mody 20397ab35bf6SHarish Patil static void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf) 20409c5d0a66SHarish Patil { 20419c5d0a66SHarish Patil *rss_caps = 0; 20429c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_IPV4) ? ECORE_RSS_IPV4 : 0; 20439c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_IPV6) ? ECORE_RSS_IPV6 : 0; 20449c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_IPV6_EX) ? ECORE_RSS_IPV6 : 0; 20459c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP) ? ECORE_RSS_IPV4_TCP : 0; 20469c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP) ? ECORE_RSS_IPV6_TCP : 0; 20479c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX) ? ECORE_RSS_IPV6_TCP : 0; 204882bd0987SHarish Patil *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_UDP) ? ECORE_RSS_IPV4_UDP : 0; 204982bd0987SHarish Patil *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_UDP) ? ECORE_RSS_IPV6_UDP : 0; 20509c5d0a66SHarish Patil } 20519c5d0a66SHarish Patil 2052af785e47SRasesh Mody int qede_rss_hash_update(struct rte_eth_dev *eth_dev, 20534c98f276SSony Chacko struct rte_eth_rss_conf *rss_conf) 20544c98f276SSony Chacko { 20557ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 20567ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 20577ab35bf6SHarish Patil struct ecore_sp_vport_update_params vport_update_params; 20587ab35bf6SHarish Patil struct ecore_rss_params rss_params; 20597ab35bf6SHarish Patil struct ecore_hwfn *p_hwfn; 20604c98f276SSony Chacko uint32_t *key = (uint32_t *)rss_conf->rss_key; 20614c98f276SSony Chacko uint64_t hf = rss_conf->rss_hf; 20627ab35bf6SHarish Patil uint8_t len = rss_conf->rss_key_len; 2063235cbe4cSShahed Shaikh uint8_t idx, i, j, fpidx; 20647ab35bf6SHarish Patil int rc; 20654c98f276SSony Chacko 20664c98f276SSony Chacko memset(&vport_update_params, 0, sizeof(vport_update_params)); 20677ab35bf6SHarish Patil memset(&rss_params, 0, sizeof(rss_params)); 20687ab35bf6SHarish Patil 20697ab35bf6SHarish Patil DP_INFO(edev, "RSS hf = 0x%lx len = %u key = %p\n", 20707ab35bf6SHarish Patil (unsigned long)hf, len, key); 20714c98f276SSony Chacko 20729c5d0a66SHarish Patil if (hf != 0) { 20737ab35bf6SHarish Patil /* Enabling RSS */ 20747ab35bf6SHarish Patil DP_INFO(edev, "Enabling rss\n"); 20759c5d0a66SHarish Patil 20767ab35bf6SHarish Patil /* RSS caps */ 20777ab35bf6SHarish Patil qede_init_rss_caps(&rss_params.rss_caps, hf); 20787ab35bf6SHarish Patil rss_params.update_rss_capabilities = 1; 20797ab35bf6SHarish Patil 20807ab35bf6SHarish Patil /* RSS hash key */ 20817ab35bf6SHarish Patil if (key) { 20827ab35bf6SHarish Patil if (len > (ECORE_RSS_KEY_SIZE * sizeof(uint32_t))) { 20837ab35bf6SHarish Patil DP_ERR(edev, "RSS key length exceeds limit\n"); 20849c5d0a66SHarish Patil return -EINVAL; 20857ab35bf6SHarish Patil } 20867ab35bf6SHarish Patil DP_INFO(edev, "Applying user supplied hash key\n"); 20877ab35bf6SHarish Patil rss_params.update_rss_key = 1; 20887ab35bf6SHarish Patil memcpy(&rss_params.rss_key, key, len); 20897ab35bf6SHarish Patil } 20907ab35bf6SHarish Patil rss_params.rss_enable = 1; 20914c98f276SSony Chacko } 20924c98f276SSony Chacko 20937ab35bf6SHarish Patil rss_params.update_rss_config = 1; 20947ab35bf6SHarish Patil /* tbl_size has to be set with capabilities */ 20957ab35bf6SHarish Patil rss_params.rss_table_size_log = 7; 20967ab35bf6SHarish Patil vport_update_params.vport_id = 0; 20977ab35bf6SHarish Patil 20987ab35bf6SHarish Patil for_each_hwfn(edev, i) { 2099235cbe4cSShahed Shaikh /* pass the L2 handles instead of qids */ 2100235cbe4cSShahed Shaikh for (j = 0 ; j < ECORE_RSS_IND_TABLE_SIZE ; j++) { 2101235cbe4cSShahed Shaikh idx = j % QEDE_RSS_COUNT(eth_dev); 2102235cbe4cSShahed Shaikh fpidx = idx * edev->num_hwfns + i; 2103235cbe4cSShahed Shaikh rss_params.rss_ind_table[j] = 2104235cbe4cSShahed Shaikh qdev->fp_array[fpidx].rxq->handle; 2105235cbe4cSShahed Shaikh } 2106235cbe4cSShahed Shaikh 2107235cbe4cSShahed Shaikh vport_update_params.rss_params = &rss_params; 2108235cbe4cSShahed Shaikh 21097ab35bf6SHarish Patil p_hwfn = &edev->hwfns[i]; 21107ab35bf6SHarish Patil vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid; 21117ab35bf6SHarish Patil rc = ecore_sp_vport_update(p_hwfn, &vport_update_params, 21127ab35bf6SHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 21137ab35bf6SHarish Patil if (rc) { 21147ab35bf6SHarish Patil DP_ERR(edev, "vport-update for RSS failed\n"); 21157ab35bf6SHarish Patil return rc; 21167ab35bf6SHarish Patil } 21177ab35bf6SHarish Patil } 21187ab35bf6SHarish Patil qdev->rss_enable = rss_params.rss_enable; 21197ab35bf6SHarish Patil 21207ab35bf6SHarish Patil /* Update local structure for hash query */ 21217ab35bf6SHarish Patil qdev->rss_conf.rss_hf = hf; 21227ab35bf6SHarish Patil qdev->rss_conf.rss_key_len = len; 21237ab35bf6SHarish Patil if (qdev->rss_enable) { 21247ab35bf6SHarish Patil if (qdev->rss_conf.rss_key == NULL) { 21257ab35bf6SHarish Patil qdev->rss_conf.rss_key = (uint8_t *)malloc(len); 21267ab35bf6SHarish Patil if (qdev->rss_conf.rss_key == NULL) { 21277ab35bf6SHarish Patil DP_ERR(edev, "No memory to store RSS key\n"); 21287ab35bf6SHarish Patil return -ENOMEM; 21297ab35bf6SHarish Patil } 21307ab35bf6SHarish Patil } 21317ab35bf6SHarish Patil if (key && len) { 21327ab35bf6SHarish Patil DP_INFO(edev, "Storing RSS key\n"); 21337ab35bf6SHarish Patil memcpy(qdev->rss_conf.rss_key, key, len); 21347ab35bf6SHarish Patil } 21357ab35bf6SHarish Patil } else if (!qdev->rss_enable && len == 0) { 21367ab35bf6SHarish Patil if (qdev->rss_conf.rss_key) { 21377ab35bf6SHarish Patil free(qdev->rss_conf.rss_key); 21387ab35bf6SHarish Patil qdev->rss_conf.rss_key = NULL; 21397ab35bf6SHarish Patil DP_INFO(edev, "Free RSS key\n"); 21407ab35bf6SHarish Patil } 21417ab35bf6SHarish Patil } 21427ab35bf6SHarish Patil 21437ab35bf6SHarish Patil return 0; 21447ab35bf6SHarish Patil } 21457ab35bf6SHarish Patil 21467ab35bf6SHarish Patil static int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev, 21476d9e26c4SSony Chacko struct rte_eth_rss_conf *rss_conf) 21486d9e26c4SSony Chacko { 21497ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 21506d9e26c4SSony Chacko 21517ab35bf6SHarish Patil rss_conf->rss_hf = qdev->rss_conf.rss_hf; 21527ab35bf6SHarish Patil rss_conf->rss_key_len = qdev->rss_conf.rss_key_len; 21536d9e26c4SSony Chacko 21547ab35bf6SHarish Patil if (rss_conf->rss_key && qdev->rss_conf.rss_key) 21557ab35bf6SHarish Patil memcpy(rss_conf->rss_key, qdev->rss_conf.rss_key, 21567ab35bf6SHarish Patil rss_conf->rss_key_len); 21576d9e26c4SSony Chacko return 0; 21586d9e26c4SSony Chacko } 21596d9e26c4SSony Chacko 2160af785e47SRasesh Mody int qede_rss_reta_update(struct rte_eth_dev *eth_dev, 2161e8876556SSony Chacko struct rte_eth_rss_reta_entry64 *reta_conf, 2162e8876556SSony Chacko uint16_t reta_size) 2163e8876556SSony Chacko { 21647ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 21657ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 21667ab35bf6SHarish Patil struct ecore_sp_vport_update_params vport_update_params; 21678b3ee85eSRasesh Mody struct ecore_rss_params *params; 2168235cbe4cSShahed Shaikh uint16_t i, j, idx, fid, shift; 21697ab35bf6SHarish Patil struct ecore_hwfn *p_hwfn; 21707ab35bf6SHarish Patil uint8_t entry; 21718b3ee85eSRasesh Mody int rc = 0; 2172e8876556SSony Chacko 2173e8876556SSony Chacko if (reta_size > ETH_RSS_RETA_SIZE_128) { 2174e8876556SSony Chacko DP_ERR(edev, "reta_size %d is not supported by hardware\n", 2175e8876556SSony Chacko reta_size); 2176e8876556SSony Chacko return -EINVAL; 2177e8876556SSony Chacko } 2178e8876556SSony Chacko 2179e8876556SSony Chacko memset(&vport_update_params, 0, sizeof(vport_update_params)); 2180235cbe4cSShahed Shaikh params = rte_zmalloc("qede_rss", sizeof(*params), RTE_CACHE_LINE_SIZE); 2181ef86e67aSRongQiang Xie if (params == NULL) { 2182ef86e67aSRongQiang Xie DP_ERR(edev, "failed to allocate memory\n"); 2183ef86e67aSRongQiang Xie return -ENOMEM; 2184ef86e67aSRongQiang Xie } 2185e8876556SSony Chacko 21868b3ee85eSRasesh Mody params->update_rss_ind_table = 1; 21878b3ee85eSRasesh Mody params->rss_table_size_log = 7; 21888b3ee85eSRasesh Mody params->update_rss_config = 1; 21898b3ee85eSRasesh Mody 2190e8876556SSony Chacko vport_update_params.vport_id = 0; 21917ab35bf6SHarish Patil /* Use the current value of rss_enable */ 21928b3ee85eSRasesh Mody params->rss_enable = qdev->rss_enable; 21938b3ee85eSRasesh Mody vport_update_params.rss_params = params; 2194e8876556SSony Chacko 21957ab35bf6SHarish Patil for_each_hwfn(edev, i) { 2196235cbe4cSShahed Shaikh for (j = 0; j < reta_size; j++) { 2197235cbe4cSShahed Shaikh idx = j / RTE_RETA_GROUP_SIZE; 2198235cbe4cSShahed Shaikh shift = j % RTE_RETA_GROUP_SIZE; 2199235cbe4cSShahed Shaikh if (reta_conf[idx].mask & (1ULL << shift)) { 2200235cbe4cSShahed Shaikh entry = reta_conf[idx].reta[shift]; 2201235cbe4cSShahed Shaikh fid = entry * edev->num_hwfns + i; 2202235cbe4cSShahed Shaikh /* Pass rxq handles to ecore */ 2203235cbe4cSShahed Shaikh params->rss_ind_table[j] = 2204235cbe4cSShahed Shaikh qdev->fp_array[fid].rxq->handle; 2205235cbe4cSShahed Shaikh /* Update the local copy for RETA query cmd */ 2206235cbe4cSShahed Shaikh qdev->rss_ind_table[j] = entry; 2207235cbe4cSShahed Shaikh } 2208235cbe4cSShahed Shaikh } 2209235cbe4cSShahed Shaikh 22107ab35bf6SHarish Patil p_hwfn = &edev->hwfns[i]; 22117ab35bf6SHarish Patil vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid; 22127ab35bf6SHarish Patil rc = ecore_sp_vport_update(p_hwfn, &vport_update_params, 22137ab35bf6SHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 22147ab35bf6SHarish Patil if (rc) { 22157ab35bf6SHarish Patil DP_ERR(edev, "vport-update for RSS failed\n"); 22168b3ee85eSRasesh Mody goto out; 22177ab35bf6SHarish Patil } 2218e8876556SSony Chacko } 2219e8876556SSony Chacko 22208b3ee85eSRasesh Mody out: 22218b3ee85eSRasesh Mody rte_free(params); 22228b3ee85eSRasesh Mody return rc; 22237ab35bf6SHarish Patil } 22247ab35bf6SHarish Patil 22257ab35bf6SHarish Patil static int qede_rss_reta_query(struct rte_eth_dev *eth_dev, 22263dadf73eSSony Chacko struct rte_eth_rss_reta_entry64 *reta_conf, 22273dadf73eSSony Chacko uint16_t reta_size) 22283dadf73eSSony Chacko { 22293dadf73eSSony Chacko struct qede_dev *qdev = eth_dev->data->dev_private; 22307ab35bf6SHarish Patil struct ecore_dev *edev = &qdev->edev; 22313dadf73eSSony Chacko uint16_t i, idx, shift; 22327ab35bf6SHarish Patil uint8_t entry; 22333dadf73eSSony Chacko 22343dadf73eSSony Chacko if (reta_size > ETH_RSS_RETA_SIZE_128) { 22353dadf73eSSony Chacko DP_ERR(edev, "reta_size %d is not supported\n", 22363dadf73eSSony Chacko reta_size); 22377ab35bf6SHarish Patil return -EINVAL; 22383dadf73eSSony Chacko } 22393dadf73eSSony Chacko 22403dadf73eSSony Chacko for (i = 0; i < reta_size; i++) { 22413dadf73eSSony Chacko idx = i / RTE_RETA_GROUP_SIZE; 22423dadf73eSSony Chacko shift = i % RTE_RETA_GROUP_SIZE; 22433dadf73eSSony Chacko if (reta_conf[idx].mask & (1ULL << shift)) { 22447ab35bf6SHarish Patil entry = qdev->rss_ind_table[i]; 22453dadf73eSSony Chacko reta_conf[idx].reta[shift] = entry; 22463dadf73eSSony Chacko } 22473dadf73eSSony Chacko } 22483dadf73eSSony Chacko 22493dadf73eSSony Chacko return 0; 22503dadf73eSSony Chacko } 22513dadf73eSSony Chacko 22524c4bdadfSHarish Patil 22534c4bdadfSHarish Patil 2254af785e47SRasesh Mody static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 2255200645acSSony Chacko { 22561ef4c3a5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(dev); 22571ef4c3a5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 2258200645acSSony Chacko struct rte_eth_dev_info dev_info = {0}; 22591ef4c3a5SHarish Patil struct qede_fastpath *fp; 22609e334305SRasesh Mody uint32_t max_rx_pkt_len; 22611ef4c3a5SHarish Patil uint32_t frame_size; 22621ef4c3a5SHarish Patil uint16_t bufsz; 22639e334305SRasesh Mody bool restart = false; 2264318d7da3SShahed Shaikh int i, rc; 2265200645acSSony Chacko 22661ef4c3a5SHarish Patil PMD_INIT_FUNC_TRACE(edev); 2267bdad90d1SIvan Ilchenko rc = qede_dev_info_get(dev, &dev_info); 2268bdad90d1SIvan Ilchenko if (rc != 0) { 2269bdad90d1SIvan Ilchenko DP_ERR(edev, "Error during getting ethernet device info\n"); 2270bdad90d1SIvan Ilchenko return rc; 2271bdad90d1SIvan Ilchenko } 2272318d7da3SShahed Shaikh max_rx_pkt_len = mtu + QEDE_MAX_ETHER_HDR_LEN; 2273318d7da3SShahed Shaikh frame_size = max_rx_pkt_len; 227435b2d13fSOlivier Matz if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen) { 22759e334305SRasesh Mody DP_ERR(edev, "MTU %u out of range, %u is maximum allowable\n", 227635b2d13fSOlivier Matz mtu, dev_info.max_rx_pktlen - RTE_ETHER_HDR_LEN - 2277318d7da3SShahed Shaikh QEDE_ETH_OVERHEAD); 2278200645acSSony Chacko return -EINVAL; 22791ef4c3a5SHarish Patil } 2280200645acSSony Chacko if (!dev->data->scattered_rx && 22811ef4c3a5SHarish Patil frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) { 22821ef4c3a5SHarish Patil DP_INFO(edev, "MTU greater than minimum RX buffer size of %u\n", 22831ef4c3a5SHarish Patil dev->data->min_rx_buf_size); 2284200645acSSony Chacko return -EINVAL; 22851ef4c3a5SHarish Patil } 22861ef4c3a5SHarish Patil /* Temporarily replace I/O functions with dummy ones. It cannot 22871ef4c3a5SHarish Patil * be set to NULL because rte_eth_rx_burst() doesn't check for NULL. 22881ef4c3a5SHarish Patil */ 22891ef4c3a5SHarish Patil dev->rx_pkt_burst = qede_rxtx_pkts_dummy; 22901ef4c3a5SHarish Patil dev->tx_pkt_burst = qede_rxtx_pkts_dummy; 22919e334305SRasesh Mody if (dev->data->dev_started) { 22929e334305SRasesh Mody dev->data->dev_started = 0; 22931ef4c3a5SHarish Patil qede_dev_stop(dev); 22949e334305SRasesh Mody restart = true; 22959e334305SRasesh Mody } 22961ef4c3a5SHarish Patil rte_delay_ms(1000); 229729bb154fSShahed Shaikh qdev->new_mtu = mtu; 2298dd28bc8cSHarish Patil 22991ef4c3a5SHarish Patil /* Fix up RX buf size for all queues of the port */ 23008de0c420SShahed Shaikh for (i = 0; i < qdev->num_rx_queues; i++) { 23011ef4c3a5SHarish Patil fp = &qdev->fp_array[i]; 23029e334305SRasesh Mody if (fp->rxq != NULL) { 23031ef4c3a5SHarish Patil bufsz = (uint16_t)rte_pktmbuf_data_room_size( 23041ef4c3a5SHarish Patil fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM; 2305318d7da3SShahed Shaikh /* cache align the mbuf size to simplfy rx_buf_size 2306318d7da3SShahed Shaikh * calculation 2307318d7da3SShahed Shaikh */ 2308318d7da3SShahed Shaikh bufsz = QEDE_FLOOR_TO_CACHE_LINE_SIZE(bufsz); 2309318d7da3SShahed Shaikh rc = qede_calc_rx_buf_size(dev, bufsz, frame_size); 2310318d7da3SShahed Shaikh if (rc < 0) 2311318d7da3SShahed Shaikh return rc; 2312318d7da3SShahed Shaikh 2313318d7da3SShahed Shaikh fp->rxq->rx_buf_size = rc; 23141ef4c3a5SHarish Patil } 23159e334305SRasesh Mody } 231635b2d13fSOlivier Matz if (max_rx_pkt_len > RTE_ETHER_MAX_LEN) 2317ab3ce1e0SFerruh Yigit dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; 2318200645acSSony Chacko else 2319ab3ce1e0SFerruh Yigit dev->data->dev_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; 2320dd28bc8cSHarish Patil 23219e334305SRasesh Mody if (!dev->data->dev_started && restart) { 23229e334305SRasesh Mody qede_dev_start(dev); 23239e334305SRasesh Mody dev->data->dev_started = 1; 23249e334305SRasesh Mody } 2325dd28bc8cSHarish Patil 2326200645acSSony Chacko /* update max frame size */ 23279e334305SRasesh Mody dev->data->dev_conf.rxmode.max_rx_pkt_len = max_rx_pkt_len; 232881f88049SShahed Shaikh 23291ef4c3a5SHarish Patil /* Reassign back */ 233081f88049SShahed Shaikh qede_assign_rxtx_handlers(dev); 23318de0c420SShahed Shaikh if (ECORE_IS_CMT(edev)) { 23328de0c420SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts_cmt; 23338de0c420SShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts_cmt; 23348de0c420SShahed Shaikh } else { 23351ef4c3a5SHarish Patil dev->rx_pkt_burst = qede_recv_pkts; 23361ef4c3a5SHarish Patil dev->tx_pkt_burst = qede_xmit_pkts; 23378de0c420SShahed Shaikh } 2338200645acSSony Chacko return 0; 2339200645acSSony Chacko } 2340200645acSSony Chacko 2341ad4d092bSShahed Shaikh static int 2342ad4d092bSShahed Shaikh qede_dev_reset(struct rte_eth_dev *dev) 2343ad4d092bSShahed Shaikh { 2344ad4d092bSShahed Shaikh int ret; 2345ad4d092bSShahed Shaikh 2346ad4d092bSShahed Shaikh ret = qede_eth_dev_uninit(dev); 2347ad4d092bSShahed Shaikh if (ret) 2348ad4d092bSShahed Shaikh return ret; 2349ad4d092bSShahed Shaikh 2350ad4d092bSShahed Shaikh return qede_eth_dev_init(dev); 2351ad4d092bSShahed Shaikh } 2352ad4d092bSShahed Shaikh 23532ea6f76aSRasesh Mody static const struct eth_dev_ops qede_eth_dev_ops = { 23542ea6f76aSRasesh Mody .dev_configure = qede_dev_configure, 23552ea6f76aSRasesh Mody .dev_infos_get = qede_dev_info_get, 23562ea6f76aSRasesh Mody .rx_queue_setup = qede_rx_queue_setup, 23572ea6f76aSRasesh Mody .rx_queue_release = qede_rx_queue_release, 23583f373e1aSShahed Shaikh .rx_descriptor_status = qede_rx_descriptor_status, 23592ea6f76aSRasesh Mody .tx_queue_setup = qede_tx_queue_setup, 23602ea6f76aSRasesh Mody .tx_queue_release = qede_tx_queue_release, 23612ea6f76aSRasesh Mody .dev_start = qede_dev_start, 2362ad4d092bSShahed Shaikh .dev_reset = qede_dev_reset, 23632ea6f76aSRasesh Mody .dev_set_link_up = qede_dev_set_link_up, 23642ea6f76aSRasesh Mody .dev_set_link_down = qede_dev_set_link_down, 23652ea6f76aSRasesh Mody .link_update = qede_link_update, 23662ea6f76aSRasesh Mody .promiscuous_enable = qede_promiscuous_enable, 23672ea6f76aSRasesh Mody .promiscuous_disable = qede_promiscuous_disable, 23682ea6f76aSRasesh Mody .allmulticast_enable = qede_allmulticast_enable, 23692ea6f76aSRasesh Mody .allmulticast_disable = qede_allmulticast_disable, 2370413ecf29SHarish Patil .set_mc_addr_list = qede_set_mc_addr_list, 23712ea6f76aSRasesh Mody .dev_stop = qede_dev_stop, 23722ea6f76aSRasesh Mody .dev_close = qede_dev_close, 23732ea6f76aSRasesh Mody .stats_get = qede_get_stats, 23745cdd769aSRasesh Mody .stats_reset = qede_reset_stats, 2375d1216e22SRasesh Mody .xstats_get = qede_get_xstats, 2376d1216e22SRasesh Mody .xstats_reset = qede_reset_xstats, 2377d1216e22SRasesh Mody .xstats_get_names = qede_get_xstats_names, 23782ea6f76aSRasesh Mody .mac_addr_add = qede_mac_addr_add, 23792ea6f76aSRasesh Mody .mac_addr_remove = qede_mac_addr_remove, 23802ea6f76aSRasesh Mody .mac_addr_set = qede_mac_addr_set, 23812ea6f76aSRasesh Mody .vlan_offload_set = qede_vlan_offload_set, 23822ea6f76aSRasesh Mody .vlan_filter_set = qede_vlan_filter_set, 23832ea6f76aSRasesh Mody .flow_ctrl_set = qede_flow_ctrl_set, 23842ea6f76aSRasesh Mody .flow_ctrl_get = qede_flow_ctrl_get, 23852ea6f76aSRasesh Mody .dev_supported_ptypes_get = qede_dev_supported_ptypes_get, 23864c98f276SSony Chacko .rss_hash_update = qede_rss_hash_update, 23876d9e26c4SSony Chacko .rss_hash_conf_get = qede_rss_hash_conf_get, 2388e8876556SSony Chacko .reta_update = qede_rss_reta_update, 23893dadf73eSSony Chacko .reta_query = qede_rss_reta_query, 2390200645acSSony Chacko .mtu_set = qede_set_mtu, 239152d94b57SHarish Patil .filter_ctrl = qede_dev_filter_ctrl, 239252d94b57SHarish Patil .udp_tunnel_port_add = qede_udp_dst_port_add, 239352d94b57SHarish Patil .udp_tunnel_port_del = qede_udp_dst_port_del, 23942ea6f76aSRasesh Mody }; 23952ea6f76aSRasesh Mody 239686a2265eSRasesh Mody static const struct eth_dev_ops qede_eth_vf_dev_ops = { 239786a2265eSRasesh Mody .dev_configure = qede_dev_configure, 239886a2265eSRasesh Mody .dev_infos_get = qede_dev_info_get, 239986a2265eSRasesh Mody .rx_queue_setup = qede_rx_queue_setup, 240086a2265eSRasesh Mody .rx_queue_release = qede_rx_queue_release, 24013f373e1aSShahed Shaikh .rx_descriptor_status = qede_rx_descriptor_status, 240286a2265eSRasesh Mody .tx_queue_setup = qede_tx_queue_setup, 240386a2265eSRasesh Mody .tx_queue_release = qede_tx_queue_release, 240486a2265eSRasesh Mody .dev_start = qede_dev_start, 2405ad4d092bSShahed Shaikh .dev_reset = qede_dev_reset, 240686a2265eSRasesh Mody .dev_set_link_up = qede_dev_set_link_up, 240786a2265eSRasesh Mody .dev_set_link_down = qede_dev_set_link_down, 240886a2265eSRasesh Mody .link_update = qede_link_update, 240986a2265eSRasesh Mody .promiscuous_enable = qede_promiscuous_enable, 241086a2265eSRasesh Mody .promiscuous_disable = qede_promiscuous_disable, 241186a2265eSRasesh Mody .allmulticast_enable = qede_allmulticast_enable, 241286a2265eSRasesh Mody .allmulticast_disable = qede_allmulticast_disable, 2413413ecf29SHarish Patil .set_mc_addr_list = qede_set_mc_addr_list, 241486a2265eSRasesh Mody .dev_stop = qede_dev_stop, 241586a2265eSRasesh Mody .dev_close = qede_dev_close, 241686a2265eSRasesh Mody .stats_get = qede_get_stats, 241786a2265eSRasesh Mody .stats_reset = qede_reset_stats, 2418d1216e22SRasesh Mody .xstats_get = qede_get_xstats, 2419d1216e22SRasesh Mody .xstats_reset = qede_reset_xstats, 2420d1216e22SRasesh Mody .xstats_get_names = qede_get_xstats_names, 242186a2265eSRasesh Mody .vlan_offload_set = qede_vlan_offload_set, 242286a2265eSRasesh Mody .vlan_filter_set = qede_vlan_filter_set, 242386a2265eSRasesh Mody .dev_supported_ptypes_get = qede_dev_supported_ptypes_get, 24244c98f276SSony Chacko .rss_hash_update = qede_rss_hash_update, 24256d9e26c4SSony Chacko .rss_hash_conf_get = qede_rss_hash_conf_get, 2426e8876556SSony Chacko .reta_update = qede_rss_reta_update, 24273dadf73eSSony Chacko .reta_query = qede_rss_reta_query, 2428200645acSSony Chacko .mtu_set = qede_set_mtu, 2429e0947ed9SHarish Patil .udp_tunnel_port_add = qede_udp_dst_port_add, 2430e0947ed9SHarish Patil .udp_tunnel_port_del = qede_udp_dst_port_del, 2431c7641841SShahed Shaikh .mac_addr_add = qede_mac_addr_add, 2432c7641841SShahed Shaikh .mac_addr_remove = qede_mac_addr_remove, 2433c7641841SShahed Shaikh .mac_addr_set = qede_mac_addr_set, 243486a2265eSRasesh Mody }; 243586a2265eSRasesh Mody 24362ea6f76aSRasesh Mody static void qede_update_pf_params(struct ecore_dev *edev) 24372ea6f76aSRasesh Mody { 24382ea6f76aSRasesh Mody struct ecore_pf_params pf_params; 2439528fcfabSHarish Patil 24402ea6f76aSRasesh Mody memset(&pf_params, 0, sizeof(struct ecore_pf_params)); 2441528fcfabSHarish Patil pf_params.eth_pf_params.num_cons = QEDE_PF_NUM_CONNS; 244262207535SHarish Patil pf_params.eth_pf_params.num_arfs_filters = QEDE_RFS_MAX_FLTR; 24432ea6f76aSRasesh Mody qed_ops->common->update_pf_params(edev, &pf_params); 24442ea6f76aSRasesh Mody } 24452ea6f76aSRasesh Mody 24462ea6f76aSRasesh Mody static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf) 24472ea6f76aSRasesh Mody { 24482ea6f76aSRasesh Mody struct rte_pci_device *pci_dev; 24492ea6f76aSRasesh Mody struct rte_pci_addr pci_addr; 24502ea6f76aSRasesh Mody struct qede_dev *adapter; 24512ea6f76aSRasesh Mody struct ecore_dev *edev; 24522ea6f76aSRasesh Mody struct qed_dev_eth_info dev_info; 24532ea6f76aSRasesh Mody struct qed_slowpath_params params; 24542ea6f76aSRasesh Mody static bool do_once = true; 24552ea6f76aSRasesh Mody uint8_t bulletin_change; 245635b2d13fSOlivier Matz uint8_t vf_mac[RTE_ETHER_ADDR_LEN]; 24572ea6f76aSRasesh Mody uint8_t is_mac_forced; 24582ea6f76aSRasesh Mody bool is_mac_exist; 24592ea6f76aSRasesh Mody /* Fix up ecore debug level */ 24602ea6f76aSRasesh Mody uint32_t dp_module = ~0 & ~ECORE_MSG_HW; 24612ea6f76aSRasesh Mody uint8_t dp_level = ECORE_LEVEL_VERBOSE; 2462245aec28SShahed Shaikh uint32_t int_mode; 24632ea6f76aSRasesh Mody int rc; 24642ea6f76aSRasesh Mody 24652ea6f76aSRasesh Mody /* Extract key data structures */ 24662ea6f76aSRasesh Mody adapter = eth_dev->data->dev_private; 24678aab5d6fSRasesh Mody adapter->ethdev = eth_dev; 24682ea6f76aSRasesh Mody edev = &adapter->edev; 2469c0802544SFerruh Yigit pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 2470d4b7f673SJan Blunck pci_addr = pci_dev->addr; 24712ea6f76aSRasesh Mody 24722ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 24732ea6f76aSRasesh Mody 24742ea6f76aSRasesh Mody snprintf(edev->name, NAME_SIZE, PCI_SHORT_PRI_FMT ":dpdk-port-%u", 24752ea6f76aSRasesh Mody pci_addr.bus, pci_addr.devid, pci_addr.function, 24762ea6f76aSRasesh Mody eth_dev->data->port_id); 24772ea6f76aSRasesh Mody 24782ea6f76aSRasesh Mody if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 24794ffa2af9SRasesh Mody DP_ERR(edev, "Skipping device init from secondary process\n"); 24802ea6f76aSRasesh Mody return 0; 24812ea6f76aSRasesh Mody } 24822ea6f76aSRasesh Mody 24832ea6f76aSRasesh Mody rte_eth_copy_pci_info(eth_dev, pci_dev); 24842ea6f76aSRasesh Mody 2485fb58ad9eSRasesh Mody /* @DPDK */ 2486fb58ad9eSRasesh Mody edev->vendor_id = pci_dev->id.vendor_id; 2487fb58ad9eSRasesh Mody edev->device_id = pci_dev->id.device_id; 2488fb58ad9eSRasesh Mody 24895cdd769aSRasesh Mody qed_ops = qed_get_eth_ops(); 24905cdd769aSRasesh Mody if (!qed_ops) { 24915cdd769aSRasesh Mody DP_ERR(edev, "Failed to get qed_eth_ops_pass\n"); 24922b5243d7SRasesh Mody rc = -EINVAL; 24932b5243d7SRasesh Mody goto err; 24945cdd769aSRasesh Mody } 24955cdd769aSRasesh Mody 24962ea6f76aSRasesh Mody DP_INFO(edev, "Starting qede probe\n"); 24974c4bdadfSHarish Patil rc = qed_ops->common->probe(edev, pci_dev, dp_module, 24984c4bdadfSHarish Patil dp_level, is_vf); 24992ea6f76aSRasesh Mody if (rc != 0) { 25002ea6f76aSRasesh Mody DP_ERR(edev, "qede probe failed rc %d\n", rc); 25012b5243d7SRasesh Mody rc = -ENODEV; 25022b5243d7SRasesh Mody goto err; 25032ea6f76aSRasesh Mody } 25042ea6f76aSRasesh Mody qede_update_pf_params(edev); 2505245aec28SShahed Shaikh 2506245aec28SShahed Shaikh switch (pci_dev->intr_handle.type) { 2507245aec28SShahed Shaikh case RTE_INTR_HANDLE_UIO_INTX: 2508245aec28SShahed Shaikh case RTE_INTR_HANDLE_VFIO_LEGACY: 2509245aec28SShahed Shaikh int_mode = ECORE_INT_MODE_INTA; 2510d4b7f673SJan Blunck rte_intr_callback_register(&pci_dev->intr_handle, 2511245aec28SShahed Shaikh qede_interrupt_handler_intx, 2512245aec28SShahed Shaikh (void *)eth_dev); 2513245aec28SShahed Shaikh break; 2514245aec28SShahed Shaikh default: 2515245aec28SShahed Shaikh int_mode = ECORE_INT_MODE_MSIX; 2516245aec28SShahed Shaikh rte_intr_callback_register(&pci_dev->intr_handle, 2517245aec28SShahed Shaikh qede_interrupt_handler, 2518245aec28SShahed Shaikh (void *)eth_dev); 2519245aec28SShahed Shaikh } 2520245aec28SShahed Shaikh 2521d4b7f673SJan Blunck if (rte_intr_enable(&pci_dev->intr_handle)) { 25222ea6f76aSRasesh Mody DP_ERR(edev, "rte_intr_enable() failed\n"); 25232b5243d7SRasesh Mody rc = -ENODEV; 25242b5243d7SRasesh Mody goto err; 25252ea6f76aSRasesh Mody } 25262ea6f76aSRasesh Mody 25272ea6f76aSRasesh Mody /* Start the Slowpath-process */ 25282ea6f76aSRasesh Mody memset(¶ms, 0, sizeof(struct qed_slowpath_params)); 2529245aec28SShahed Shaikh 2530245aec28SShahed Shaikh params.int_mode = int_mode; 25317eca78ceSHarish Patil params.drv_major = QEDE_PMD_VERSION_MAJOR; 25327eca78ceSHarish Patil params.drv_minor = QEDE_PMD_VERSION_MINOR; 25337eca78ceSHarish Patil params.drv_rev = QEDE_PMD_VERSION_REVISION; 25347eca78ceSHarish Patil params.drv_eng = QEDE_PMD_VERSION_PATCH; 25357eca78ceSHarish Patil strncpy((char *)params.name, QEDE_PMD_VER_PREFIX, 25367eca78ceSHarish Patil QEDE_PMD_DRV_VER_STR_SIZE); 25372ea6f76aSRasesh Mody 253881f88049SShahed Shaikh qede_assign_rxtx_handlers(eth_dev); 25398de0c420SShahed Shaikh eth_dev->tx_pkt_prepare = qede_xmit_prep_pkts; 25408de0c420SShahed Shaikh 25412af14ca7SHarish Patil /* For CMT mode device do periodic polling for slowpath events. 25422af14ca7SHarish Patil * This is required since uio device uses only one MSI-x 25432af14ca7SHarish Patil * interrupt vector but we need one for each engine. 25442af14ca7SHarish Patil */ 2545c0845c33SRasesh Mody if (ECORE_IS_CMT(edev) && IS_PF(edev)) { 25460833120fSShahed Shaikh rc = rte_eal_alarm_set(QEDE_SP_TIMER_PERIOD, 25472af14ca7SHarish Patil qede_poll_sp_sb_cb, 25482af14ca7SHarish Patil (void *)eth_dev); 25492af14ca7SHarish Patil if (rc != 0) { 25502af14ca7SHarish Patil DP_ERR(edev, "Unable to start periodic" 25512af14ca7SHarish Patil " timer rc %d\n", rc); 25522b5243d7SRasesh Mody rc = -EINVAL; 25532b5243d7SRasesh Mody goto err; 25542af14ca7SHarish Patil } 25552af14ca7SHarish Patil } 25562af14ca7SHarish Patil 25572ea6f76aSRasesh Mody rc = qed_ops->common->slowpath_start(edev, ¶ms); 25582ea6f76aSRasesh Mody if (rc) { 25592ea6f76aSRasesh Mody DP_ERR(edev, "Cannot start slowpath rc = %d\n", rc); 25602af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 25612af14ca7SHarish Patil (void *)eth_dev); 25622b5243d7SRasesh Mody rc = -ENODEV; 25632b5243d7SRasesh Mody goto err; 25642ea6f76aSRasesh Mody } 25652ea6f76aSRasesh Mody 25662ea6f76aSRasesh Mody rc = qed_ops->fill_dev_info(edev, &dev_info); 25672ea6f76aSRasesh Mody if (rc) { 25682ea6f76aSRasesh Mody DP_ERR(edev, "Cannot get device_info rc %d\n", rc); 25692ea6f76aSRasesh Mody qed_ops->common->slowpath_stop(edev); 25702ea6f76aSRasesh Mody qed_ops->common->remove(edev); 25712af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 25722af14ca7SHarish Patil (void *)eth_dev); 25732b5243d7SRasesh Mody rc = -ENODEV; 25742b5243d7SRasesh Mody goto err; 25752ea6f76aSRasesh Mody } 25762ea6f76aSRasesh Mody 25772ea6f76aSRasesh Mody qede_alloc_etherdev(adapter, &dev_info); 25782ea6f76aSRasesh Mody 25792b5243d7SRasesh Mody if (do_once) { 25802b5243d7SRasesh Mody qede_print_adapter_info(adapter); 25812b5243d7SRasesh Mody do_once = false; 25822b5243d7SRasesh Mody } 25832b5243d7SRasesh Mody 2584de5588afSRasesh Mody adapter->ops->common->set_name(edev, edev->name); 25852ea6f76aSRasesh Mody 25862ea6f76aSRasesh Mody if (!is_vf) 25873320ca8cSRasesh Mody adapter->dev_info.num_mac_filters = 25882ea6f76aSRasesh Mody (uint32_t)RESC_NUM(ECORE_LEADING_HWFN(edev), 25892ea6f76aSRasesh Mody ECORE_MAC); 25902ea6f76aSRasesh Mody else 259186a2265eSRasesh Mody ecore_vf_get_num_mac_filters(ECORE_LEADING_HWFN(edev), 25923320ca8cSRasesh Mody (uint32_t *)&adapter->dev_info.num_mac_filters); 25932ea6f76aSRasesh Mody 25942ea6f76aSRasesh Mody /* Allocate memory for storing MAC addr */ 25952ea6f76aSRasesh Mody eth_dev->data->mac_addrs = rte_zmalloc(edev->name, 259635b2d13fSOlivier Matz (RTE_ETHER_ADDR_LEN * 25973320ca8cSRasesh Mody adapter->dev_info.num_mac_filters), 25982ea6f76aSRasesh Mody RTE_CACHE_LINE_SIZE); 25992ea6f76aSRasesh Mody 26002ea6f76aSRasesh Mody if (eth_dev->data->mac_addrs == NULL) { 26012ea6f76aSRasesh Mody DP_ERR(edev, "Failed to allocate MAC address\n"); 26022ea6f76aSRasesh Mody qed_ops->common->slowpath_stop(edev); 26032ea6f76aSRasesh Mody qed_ops->common->remove(edev); 26042af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 26052af14ca7SHarish Patil (void *)eth_dev); 26062ea6f76aSRasesh Mody return -ENOMEM; 26072ea6f76aSRasesh Mody } 26082ea6f76aSRasesh Mody 260986a2265eSRasesh Mody if (!is_vf) { 2610538da7a1SOlivier Matz rte_ether_addr_copy((struct rte_ether_addr *)edev->hwfns[0]. 26112ea6f76aSRasesh Mody hw_info.hw_mac_addr, 26122ea6f76aSRasesh Mody ð_dev->data->mac_addrs[0]); 2613538da7a1SOlivier Matz rte_ether_addr_copy(ð_dev->data->mac_addrs[0], 261486a2265eSRasesh Mody &adapter->primary_mac); 261586a2265eSRasesh Mody } else { 261686a2265eSRasesh Mody ecore_vf_read_bulletin(ECORE_LEADING_HWFN(edev), 261786a2265eSRasesh Mody &bulletin_change); 261886a2265eSRasesh Mody if (bulletin_change) { 261986a2265eSRasesh Mody is_mac_exist = 262086a2265eSRasesh Mody ecore_vf_bulletin_get_forced_mac( 262186a2265eSRasesh Mody ECORE_LEADING_HWFN(edev), 262286a2265eSRasesh Mody vf_mac, 262386a2265eSRasesh Mody &is_mac_forced); 2624c7641841SShahed Shaikh if (is_mac_exist) { 262586a2265eSRasesh Mody DP_INFO(edev, "VF macaddr received from PF\n"); 2626538da7a1SOlivier Matz rte_ether_addr_copy( 26276d13ea8eSOlivier Matz (struct rte_ether_addr *)&vf_mac, 262886a2265eSRasesh Mody ð_dev->data->mac_addrs[0]); 2629538da7a1SOlivier Matz rte_ether_addr_copy( 2630538da7a1SOlivier Matz ð_dev->data->mac_addrs[0], 263186a2265eSRasesh Mody &adapter->primary_mac); 263286a2265eSRasesh Mody } else { 26334ffa2af9SRasesh Mody DP_ERR(edev, "No VF macaddr assigned\n"); 263486a2265eSRasesh Mody } 263586a2265eSRasesh Mody } 263686a2265eSRasesh Mody } 26372ea6f76aSRasesh Mody 263886a2265eSRasesh Mody eth_dev->dev_ops = (is_vf) ? &qede_eth_vf_dev_ops : &qede_eth_dev_ops; 26392ea6f76aSRasesh Mody 2640dd28bc8cSHarish Patil /* Bring-up the link */ 2641dd28bc8cSHarish Patil qede_dev_set_link_state(eth_dev, true); 2642dd28bc8cSHarish Patil 26434c4bdadfSHarish Patil adapter->num_tx_queues = 0; 26444c4bdadfSHarish Patil adapter->num_rx_queues = 0; 2645f5765f66SShahed Shaikh SLIST_INIT(&adapter->arfs_info.arfs_list_head); 26464c4bdadfSHarish Patil SLIST_INIT(&adapter->vlan_list_head); 26474c4bdadfSHarish Patil SLIST_INIT(&adapter->uc_list_head); 2648413ecf29SHarish Patil SLIST_INIT(&adapter->mc_list_head); 264935b2d13fSOlivier Matz adapter->mtu = RTE_ETHER_MTU; 2650dd28bc8cSHarish Patil adapter->vport_started = false; 2651dd28bc8cSHarish Patil 2652c8b34b7eSHarish Patil /* VF tunnel offloads is enabled by default in PF driver */ 2653c8b34b7eSHarish Patil adapter->vxlan.num_filters = 0; 26547cf0f102SHarish Patil adapter->geneve.num_filters = 0; 2655e1e38962SHarish Patil adapter->ipgre.num_filters = 0; 26567cf0f102SHarish Patil if (is_vf) { 26577cf0f102SHarish Patil adapter->vxlan.enable = true; 2658c8b34b7eSHarish Patil adapter->vxlan.filter_type = ETH_TUNNEL_FILTER_IMAC | 2659c8b34b7eSHarish Patil ETH_TUNNEL_FILTER_IVLAN; 2660c8b34b7eSHarish Patil adapter->vxlan.udp_port = QEDE_VXLAN_DEF_PORT; 2661c8b34b7eSHarish Patil adapter->geneve.enable = true; 26627cf0f102SHarish Patil adapter->geneve.filter_type = ETH_TUNNEL_FILTER_IMAC | 2663c8b34b7eSHarish Patil ETH_TUNNEL_FILTER_IVLAN; 26647cf0f102SHarish Patil adapter->geneve.udp_port = QEDE_GENEVE_DEF_PORT; 2665e1e38962SHarish Patil adapter->ipgre.enable = true; 2666e1e38962SHarish Patil adapter->ipgre.filter_type = ETH_TUNNEL_FILTER_IMAC | 2667e1e38962SHarish Patil ETH_TUNNEL_FILTER_IVLAN; 26687cf0f102SHarish Patil } else { 26697cf0f102SHarish Patil adapter->vxlan.enable = false; 26707cf0f102SHarish Patil adapter->geneve.enable = false; 2671e1e38962SHarish Patil adapter->ipgre.enable = false; 26727cf0f102SHarish Patil } 2673dbac54c2SHarish Patil 26744ffa2af9SRasesh Mody DP_INFO(edev, "MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n", 26752ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[0], 26762ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[1], 26772ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[2], 26782ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[3], 26792ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[4], 26802ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[5]); 26812ea6f76aSRasesh Mody 26824c4bdadfSHarish Patil DP_INFO(edev, "Device initialized\n"); 26834c4bdadfSHarish Patil 26844c4bdadfSHarish Patil return 0; 26852b5243d7SRasesh Mody 26862b5243d7SRasesh Mody err: 26872b5243d7SRasesh Mody if (do_once) { 26882b5243d7SRasesh Mody qede_print_adapter_info(adapter); 26892b5243d7SRasesh Mody do_once = false; 26902b5243d7SRasesh Mody } 26912b5243d7SRasesh Mody return rc; 26922ea6f76aSRasesh Mody } 26932ea6f76aSRasesh Mody 26942ea6f76aSRasesh Mody static int qedevf_eth_dev_init(struct rte_eth_dev *eth_dev) 26952ea6f76aSRasesh Mody { 26962ea6f76aSRasesh Mody return qede_common_dev_init(eth_dev, 1); 26972ea6f76aSRasesh Mody } 26982ea6f76aSRasesh Mody 26992ea6f76aSRasesh Mody static int qede_eth_dev_init(struct rte_eth_dev *eth_dev) 27002ea6f76aSRasesh Mody { 27012ea6f76aSRasesh Mody return qede_common_dev_init(eth_dev, 0); 27022ea6f76aSRasesh Mody } 27032ea6f76aSRasesh Mody 27042ea6f76aSRasesh Mody static int qede_dev_common_uninit(struct rte_eth_dev *eth_dev) 27052ea6f76aSRasesh Mody { 2706e8fb98d6SRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 2707e8fb98d6SRasesh Mody struct ecore_dev *edev = &qdev->edev; 2708e8fb98d6SRasesh Mody 2709e8fb98d6SRasesh Mody PMD_INIT_FUNC_TRACE(edev); 2710e8fb98d6SRasesh Mody 27112ea6f76aSRasesh Mody /* only uninitialize in the primary process */ 27122ea6f76aSRasesh Mody if (rte_eal_process_type() != RTE_PROC_PRIMARY) 27132ea6f76aSRasesh Mody return 0; 27142ea6f76aSRasesh Mody 27152ea6f76aSRasesh Mody /* safe to close dev here */ 27162ea6f76aSRasesh Mody qede_dev_close(eth_dev); 27172ea6f76aSRasesh Mody 27182ea6f76aSRasesh Mody eth_dev->dev_ops = NULL; 27192ea6f76aSRasesh Mody eth_dev->rx_pkt_burst = NULL; 27202ea6f76aSRasesh Mody eth_dev->tx_pkt_burst = NULL; 27212ea6f76aSRasesh Mody 27222ea6f76aSRasesh Mody return 0; 27232ea6f76aSRasesh Mody } 27242ea6f76aSRasesh Mody 27252ea6f76aSRasesh Mody static int qede_eth_dev_uninit(struct rte_eth_dev *eth_dev) 27262ea6f76aSRasesh Mody { 27272ea6f76aSRasesh Mody return qede_dev_common_uninit(eth_dev); 27282ea6f76aSRasesh Mody } 27292ea6f76aSRasesh Mody 27302ea6f76aSRasesh Mody static int qedevf_eth_dev_uninit(struct rte_eth_dev *eth_dev) 27312ea6f76aSRasesh Mody { 27322ea6f76aSRasesh Mody return qede_dev_common_uninit(eth_dev); 27332ea6f76aSRasesh Mody } 27342ea6f76aSRasesh Mody 273528a1fd4fSFerruh Yigit static const struct rte_pci_id pci_id_qedevf_map[] = { 27362ea6f76aSRasesh Mody #define QEDEVF_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev) 27372ea6f76aSRasesh Mody { 273877f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_VF) 27392ea6f76aSRasesh Mody }, 27402ea6f76aSRasesh Mody { 274177f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_IOV) 274277f72221SRasesh Mody }, 274377f72221SRasesh Mody { 274477f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_IOV) 27452ea6f76aSRasesh Mody }, 27462ea6f76aSRasesh Mody {.vendor_id = 0,} 27472ea6f76aSRasesh Mody }; 27482ea6f76aSRasesh Mody 274928a1fd4fSFerruh Yigit static const struct rte_pci_id pci_id_qede_map[] = { 27502ea6f76aSRasesh Mody #define QEDE_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev) 27512ea6f76aSRasesh Mody { 275277f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980E) 27532ea6f76aSRasesh Mody }, 27542ea6f76aSRasesh Mody { 275577f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980S) 27562ea6f76aSRasesh Mody }, 27572ea6f76aSRasesh Mody { 275877f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_40) 27592ea6f76aSRasesh Mody }, 27602ea6f76aSRasesh Mody { 276177f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_25) 27622ea6f76aSRasesh Mody }, 27632af14ca7SHarish Patil { 276477f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_100) 276577f72221SRasesh Mody }, 276677f72221SRasesh Mody { 2767e6512107SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_50) 2768e6512107SRasesh Mody }, 2769e6512107SRasesh Mody { 277077f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_50G) 277177f72221SRasesh Mody }, 277277f72221SRasesh Mody { 277377f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_10G) 277477f72221SRasesh Mody }, 277577f72221SRasesh Mody { 277677f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_40G) 277777f72221SRasesh Mody }, 277877f72221SRasesh Mody { 277977f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_25G) 27802af14ca7SHarish Patil }, 27812ea6f76aSRasesh Mody {.vendor_id = 0,} 27822ea6f76aSRasesh Mody }; 27832ea6f76aSRasesh Mody 2784fdf91e0fSJan Blunck static int qedevf_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 2785fdf91e0fSJan Blunck struct rte_pci_device *pci_dev) 2786fdf91e0fSJan Blunck { 2787fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_probe(pci_dev, 2788fdf91e0fSJan Blunck sizeof(struct qede_dev), qedevf_eth_dev_init); 2789fdf91e0fSJan Blunck } 2790fdf91e0fSJan Blunck 2791fdf91e0fSJan Blunck static int qedevf_eth_dev_pci_remove(struct rte_pci_device *pci_dev) 2792fdf91e0fSJan Blunck { 2793fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_remove(pci_dev, qedevf_eth_dev_uninit); 2794fdf91e0fSJan Blunck } 2795fdf91e0fSJan Blunck 2796fdf91e0fSJan Blunck static struct rte_pci_driver rte_qedevf_pmd = { 27972ea6f76aSRasesh Mody .id_table = pci_id_qedevf_map, 2798b76fafb1SDavid Marchand .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 2799fdf91e0fSJan Blunck .probe = qedevf_eth_dev_pci_probe, 2800fdf91e0fSJan Blunck .remove = qedevf_eth_dev_pci_remove, 28012ea6f76aSRasesh Mody }; 28022ea6f76aSRasesh Mody 2803fdf91e0fSJan Blunck static int qede_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 2804fdf91e0fSJan Blunck struct rte_pci_device *pci_dev) 2805fdf91e0fSJan Blunck { 2806fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_probe(pci_dev, 2807fdf91e0fSJan Blunck sizeof(struct qede_dev), qede_eth_dev_init); 2808fdf91e0fSJan Blunck } 2809fdf91e0fSJan Blunck 2810fdf91e0fSJan Blunck static int qede_eth_dev_pci_remove(struct rte_pci_device *pci_dev) 2811fdf91e0fSJan Blunck { 2812fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_remove(pci_dev, qede_eth_dev_uninit); 2813fdf91e0fSJan Blunck } 2814fdf91e0fSJan Blunck 2815fdf91e0fSJan Blunck static struct rte_pci_driver rte_qede_pmd = { 28162ea6f76aSRasesh Mody .id_table = pci_id_qede_map, 2817b76fafb1SDavid Marchand .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 2818fdf91e0fSJan Blunck .probe = qede_eth_dev_pci_probe, 2819fdf91e0fSJan Blunck .remove = qede_eth_dev_pci_remove, 28202ea6f76aSRasesh Mody }; 28212ea6f76aSRasesh Mody 2822fdf91e0fSJan Blunck RTE_PMD_REGISTER_PCI(net_qede, rte_qede_pmd); 282301f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_qede, pci_id_qede_map); 282406e81dc9SDavid Marchand RTE_PMD_REGISTER_KMOD_DEP(net_qede, "* igb_uio | uio_pci_generic | vfio-pci"); 2825fdf91e0fSJan Blunck RTE_PMD_REGISTER_PCI(net_qede_vf, rte_qedevf_pmd); 282601f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_qede_vf, pci_id_qedevf_map); 282706e81dc9SDavid Marchand RTE_PMD_REGISTER_KMOD_DEP(net_qede_vf, "* igb_uio | vfio-pci"); 282869b65739SStephen Hemminger 2829f8e99896SThomas Monjalon RTE_INIT(qede_init_log) 283069b65739SStephen Hemminger { 2831b8da8fadSHarry van Haaren qede_logtype_init = rte_log_register("pmd.net.qede.init"); 283269b65739SStephen Hemminger if (qede_logtype_init >= 0) 283369b65739SStephen Hemminger rte_log_set_level(qede_logtype_init, RTE_LOG_NOTICE); 2834b8da8fadSHarry van Haaren qede_logtype_driver = rte_log_register("pmd.net.qede.driver"); 283569b65739SStephen Hemminger if (qede_logtype_driver >= 0) 283669b65739SStephen Hemminger rte_log_set_level(qede_logtype_driver, RTE_LOG_NOTICE); 283769b65739SStephen Hemminger } 2838