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> 10f64b91b0SRasesh Mody #include <rte_kvargs.h> 112ea6f76aSRasesh Mody 122ea6f76aSRasesh Mody static const struct qed_eth_ops *qed_ops; 13ad4d092bSShahed Shaikh static int qede_eth_dev_uninit(struct rte_eth_dev *eth_dev); 14ad4d092bSShahed Shaikh static int qede_eth_dev_init(struct rte_eth_dev *eth_dev); 15ad4d092bSShahed Shaikh 160833120fSShahed Shaikh #define QEDE_SP_TIMER_PERIOD 10000 /* 100ms */ 172ea6f76aSRasesh Mody 18d1216e22SRasesh Mody struct rte_qede_xstats_name_off { 19d1216e22SRasesh Mody char name[RTE_ETH_XSTATS_NAME_SIZE]; 20d1216e22SRasesh Mody uint64_t offset; 21d1216e22SRasesh Mody }; 22d1216e22SRasesh Mody 23d1216e22SRasesh Mody static const struct rte_qede_xstats_name_off qede_xstats_strings[] = { 249c1aa3e1SRasesh Mody {"rx_unicast_bytes", 259c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_ucast_bytes)}, 26d1216e22SRasesh Mody {"rx_multicast_bytes", 279c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mcast_bytes)}, 28d1216e22SRasesh Mody {"rx_broadcast_bytes", 299c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_bcast_bytes)}, 309c1aa3e1SRasesh Mody {"rx_unicast_packets", 319c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_ucast_pkts)}, 32d1216e22SRasesh Mody {"rx_multicast_packets", 339c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mcast_pkts)}, 34d1216e22SRasesh Mody {"rx_broadcast_packets", 359c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_bcast_pkts)}, 36d1216e22SRasesh Mody 379c1aa3e1SRasesh Mody {"tx_unicast_bytes", 389c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_ucast_bytes)}, 39d1216e22SRasesh Mody {"tx_multicast_bytes", 409c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mcast_bytes)}, 41d1216e22SRasesh Mody {"tx_broadcast_bytes", 429c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_bcast_bytes)}, 439c1aa3e1SRasesh Mody {"tx_unicast_packets", 449c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_ucast_pkts)}, 45d1216e22SRasesh Mody {"tx_multicast_packets", 469c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mcast_pkts)}, 47d1216e22SRasesh Mody {"tx_broadcast_packets", 489c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_bcast_pkts)}, 49d1216e22SRasesh Mody 50d1216e22SRasesh Mody {"rx_64_byte_packets", 519c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_64_byte_packets)}, 52d1216e22SRasesh Mody {"rx_65_to_127_byte_packets", 539c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 549c1aa3e1SRasesh Mody rx_65_to_127_byte_packets)}, 55d1216e22SRasesh Mody {"rx_128_to_255_byte_packets", 569c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 579c1aa3e1SRasesh Mody rx_128_to_255_byte_packets)}, 58d1216e22SRasesh Mody {"rx_256_to_511_byte_packets", 599c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 609c1aa3e1SRasesh Mody rx_256_to_511_byte_packets)}, 61d1216e22SRasesh Mody {"rx_512_to_1023_byte_packets", 629c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 639c1aa3e1SRasesh Mody rx_512_to_1023_byte_packets)}, 64d1216e22SRasesh Mody {"rx_1024_to_1518_byte_packets", 659c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 669c1aa3e1SRasesh Mody rx_1024_to_1518_byte_packets)}, 67d1216e22SRasesh Mody {"tx_64_byte_packets", 689c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_64_byte_packets)}, 69d1216e22SRasesh Mody {"tx_65_to_127_byte_packets", 709c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 719c1aa3e1SRasesh Mody tx_65_to_127_byte_packets)}, 72d1216e22SRasesh Mody {"tx_128_to_255_byte_packets", 739c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 749c1aa3e1SRasesh Mody tx_128_to_255_byte_packets)}, 75d1216e22SRasesh Mody {"tx_256_to_511_byte_packets", 769c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 779c1aa3e1SRasesh Mody tx_256_to_511_byte_packets)}, 78d1216e22SRasesh Mody {"tx_512_to_1023_byte_packets", 799c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 809c1aa3e1SRasesh Mody tx_512_to_1023_byte_packets)}, 81d1216e22SRasesh Mody {"tx_1024_to_1518_byte_packets", 829c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 839c1aa3e1SRasesh Mody tx_1024_to_1518_byte_packets)}, 84d1216e22SRasesh Mody 85d1216e22SRasesh Mody {"rx_mac_crtl_frames", 869c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_crtl_frames)}, 87d1216e22SRasesh Mody {"tx_mac_control_frames", 889c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mac_ctrl_frames)}, 899c1aa3e1SRasesh Mody {"rx_pause_frames", 909c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_pause_frames)}, 919c1aa3e1SRasesh Mody {"tx_pause_frames", 929c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_pause_frames)}, 93d1216e22SRasesh Mody {"rx_priority_flow_control_frames", 949c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_pfc_frames)}, 95d1216e22SRasesh Mody {"tx_priority_flow_control_frames", 969c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_pfc_frames)}, 97d1216e22SRasesh Mody 989c1aa3e1SRasesh Mody {"rx_crc_errors", 999c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_crc_errors)}, 1009c1aa3e1SRasesh Mody {"rx_align_errors", 1019c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_align_errors)}, 102d1216e22SRasesh Mody {"rx_carrier_errors", 1039c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_carrier_errors)}, 104d1216e22SRasesh Mody {"rx_oversize_packet_errors", 1059c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_oversize_packets)}, 1069c1aa3e1SRasesh Mody {"rx_jabber_errors", 1079c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_jabbers)}, 108d1216e22SRasesh Mody {"rx_undersize_packet_errors", 1099c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_undersize_packets)}, 1109c1aa3e1SRasesh Mody {"rx_fragments", offsetof(struct ecore_eth_stats_common, rx_fragments)}, 111d1216e22SRasesh Mody {"rx_host_buffer_not_available", 1129c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, no_buff_discards)}, 113d1216e22SRasesh Mody /* Number of packets discarded because they are bigger than MTU */ 114d1216e22SRasesh Mody {"rx_packet_too_big_discards", 1159c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 1169c1aa3e1SRasesh Mody packet_too_big_discard)}, 117d1216e22SRasesh Mody {"rx_ttl_zero_discards", 1189c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, ttl0_discard)}, 119d1216e22SRasesh Mody {"rx_multi_function_tag_filter_discards", 1209c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, mftag_filter_discards)}, 121d1216e22SRasesh Mody {"rx_mac_filter_discards", 1229c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, mac_filter_discards)}, 1232c0784ebSShahed Shaikh {"rx_gft_filter_drop", 1242c0784ebSShahed Shaikh offsetof(struct ecore_eth_stats_common, gft_filter_drop)}, 125d1216e22SRasesh Mody {"rx_hw_buffer_truncates", 1269c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, brb_truncates)}, 127d1216e22SRasesh Mody {"rx_hw_buffer_discards", 1289c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, brb_discards)}, 129d1216e22SRasesh Mody {"tx_error_drop_packets", 1309c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_err_drop_pkts)}, 131d1216e22SRasesh Mody 1329c1aa3e1SRasesh Mody {"rx_mac_bytes", offsetof(struct ecore_eth_stats_common, rx_mac_bytes)}, 133d1216e22SRasesh Mody {"rx_mac_unicast_packets", 1349c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_uc_packets)}, 135d1216e22SRasesh Mody {"rx_mac_multicast_packets", 1369c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_mc_packets)}, 137d1216e22SRasesh Mody {"rx_mac_broadcast_packets", 1389c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_bc_packets)}, 139d1216e22SRasesh Mody {"rx_mac_frames_ok", 1409c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, rx_mac_frames_ok)}, 1419c1aa3e1SRasesh Mody {"tx_mac_bytes", offsetof(struct ecore_eth_stats_common, tx_mac_bytes)}, 142d1216e22SRasesh Mody {"tx_mac_unicast_packets", 1439c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mac_uc_packets)}, 144d1216e22SRasesh Mody {"tx_mac_multicast_packets", 1459c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mac_mc_packets)}, 146d1216e22SRasesh Mody {"tx_mac_broadcast_packets", 1479c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tx_mac_bc_packets)}, 148d1216e22SRasesh Mody 149d1216e22SRasesh Mody {"lro_coalesced_packets", 1509c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tpa_coalesced_pkts)}, 151d1216e22SRasesh Mody {"lro_coalesced_events", 1529c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tpa_coalesced_events)}, 153d1216e22SRasesh Mody {"lro_aborts_num", 1549c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, tpa_aborts_num)}, 155d1216e22SRasesh Mody {"lro_not_coalesced_packets", 1569c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 1579c1aa3e1SRasesh Mody tpa_not_coalesced_pkts)}, 158d1216e22SRasesh Mody {"lro_coalesced_bytes", 1599c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_common, 1609c1aa3e1SRasesh Mody tpa_coalesced_bytes)}, 1619c1aa3e1SRasesh Mody }; 1629c1aa3e1SRasesh Mody 1639c1aa3e1SRasesh Mody static const struct rte_qede_xstats_name_off qede_bb_xstats_strings[] = { 1649c1aa3e1SRasesh Mody {"rx_1519_to_1522_byte_packets", 1659c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1669c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1679c1aa3e1SRasesh Mody rx_1519_to_1522_byte_packets)}, 1689c1aa3e1SRasesh Mody {"rx_1519_to_2047_byte_packets", 1699c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1709c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1719c1aa3e1SRasesh Mody rx_1519_to_2047_byte_packets)}, 1729c1aa3e1SRasesh Mody {"rx_2048_to_4095_byte_packets", 1739c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1749c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1759c1aa3e1SRasesh Mody rx_2048_to_4095_byte_packets)}, 1769c1aa3e1SRasesh Mody {"rx_4096_to_9216_byte_packets", 1779c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1789c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1799c1aa3e1SRasesh Mody rx_4096_to_9216_byte_packets)}, 1809c1aa3e1SRasesh Mody {"rx_9217_to_16383_byte_packets", 1819c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1829c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1839c1aa3e1SRasesh Mody rx_9217_to_16383_byte_packets)}, 1849c1aa3e1SRasesh Mody 1859c1aa3e1SRasesh Mody {"tx_1519_to_2047_byte_packets", 1869c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1879c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1889c1aa3e1SRasesh Mody tx_1519_to_2047_byte_packets)}, 1899c1aa3e1SRasesh Mody {"tx_2048_to_4095_byte_packets", 1909c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1919c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1929c1aa3e1SRasesh Mody tx_2048_to_4095_byte_packets)}, 1939c1aa3e1SRasesh Mody {"tx_4096_to_9216_byte_packets", 1949c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1959c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 1969c1aa3e1SRasesh Mody tx_4096_to_9216_byte_packets)}, 1979c1aa3e1SRasesh Mody {"tx_9217_to_16383_byte_packets", 1989c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 1999c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, 2009c1aa3e1SRasesh Mody tx_9217_to_16383_byte_packets)}, 2019c1aa3e1SRasesh Mody 2029c1aa3e1SRasesh Mody {"tx_lpi_entry_count", 2039c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 2049c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, tx_lpi_entry_count)}, 2059c1aa3e1SRasesh Mody {"tx_total_collisions", 2069c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, bb) + 2079c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_bb, tx_total_collisions)}, 2089c1aa3e1SRasesh Mody }; 2099c1aa3e1SRasesh Mody 2109c1aa3e1SRasesh Mody static const struct rte_qede_xstats_name_off qede_ah_xstats_strings[] = { 2119c1aa3e1SRasesh Mody {"rx_1519_to_max_byte_packets", 2129c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, ah) + 2139c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_ah, 2149c1aa3e1SRasesh Mody rx_1519_to_max_byte_packets)}, 2159c1aa3e1SRasesh Mody {"tx_1519_to_max_byte_packets", 2169c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats, ah) + 2179c1aa3e1SRasesh Mody offsetof(struct ecore_eth_stats_ah, 2189c1aa3e1SRasesh Mody tx_1519_to_max_byte_packets)}, 219d1216e22SRasesh Mody }; 220d1216e22SRasesh Mody 2217634c5f9SRasesh Mody static const struct rte_qede_xstats_name_off qede_rxq_xstats_strings[] = { 2227634c5f9SRasesh Mody {"rx_q_segments", 2237634c5f9SRasesh Mody offsetof(struct qede_rx_queue, rx_segs)}, 2247634c5f9SRasesh Mody {"rx_q_hw_errors", 2257634c5f9SRasesh Mody offsetof(struct qede_rx_queue, rx_hw_errors)}, 2267634c5f9SRasesh Mody {"rx_q_allocation_errors", 2277634c5f9SRasesh Mody offsetof(struct qede_rx_queue, rx_alloc_errors)} 2287634c5f9SRasesh Mody }; 2297634c5f9SRasesh Mody 230f97b56f9SRasesh Mody /* Get FW version string based on fw_size */ 231f97b56f9SRasesh Mody static int 232f97b56f9SRasesh Mody qede_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size) 233f97b56f9SRasesh Mody { 234f97b56f9SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 235f97b56f9SRasesh Mody struct ecore_dev *edev = &qdev->edev; 236f97b56f9SRasesh Mody struct qed_dev_info *info = &qdev->dev_info.common; 237f97b56f9SRasesh Mody static char ver_str[QEDE_PMD_DRV_VER_STR_SIZE]; 238f97b56f9SRasesh Mody size_t size; 239f97b56f9SRasesh Mody 240f97b56f9SRasesh Mody if (fw_ver == NULL) 241f97b56f9SRasesh Mody return 0; 242f97b56f9SRasesh Mody 243f97b56f9SRasesh Mody if (IS_PF(edev)) 244f97b56f9SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 245f97b56f9SRasesh Mody QEDE_PMD_FW_VERSION); 246f97b56f9SRasesh Mody else 247f97b56f9SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%d.%d.%d.%d", 248f97b56f9SRasesh Mody info->fw_major, info->fw_minor, 249f97b56f9SRasesh Mody info->fw_rev, info->fw_eng); 250f97b56f9SRasesh Mody size = strlen(ver_str); 251f97b56f9SRasesh Mody if (size + 1 <= fw_size) /* Add 1 byte for "\0" */ 252f97b56f9SRasesh Mody strlcpy(fw_ver, ver_str, fw_size); 253f97b56f9SRasesh Mody else 254f97b56f9SRasesh Mody return (size + 1); 255f97b56f9SRasesh Mody 256f97b56f9SRasesh Mody snprintf(ver_str + size, (QEDE_PMD_DRV_VER_STR_SIZE - size), 257f97b56f9SRasesh Mody " MFW: %d.%d.%d.%d", 258f97b56f9SRasesh Mody GET_MFW_FIELD(info->mfw_rev, QED_MFW_VERSION_3), 259f97b56f9SRasesh Mody GET_MFW_FIELD(info->mfw_rev, QED_MFW_VERSION_2), 260f97b56f9SRasesh Mody GET_MFW_FIELD(info->mfw_rev, QED_MFW_VERSION_1), 261f97b56f9SRasesh Mody GET_MFW_FIELD(info->mfw_rev, QED_MFW_VERSION_0)); 262f97b56f9SRasesh Mody size = strlen(ver_str); 263f97b56f9SRasesh Mody if (size + 1 <= fw_size) 264f97b56f9SRasesh Mody strlcpy(fw_ver, ver_str, fw_size); 265f97b56f9SRasesh Mody 266f97b56f9SRasesh Mody if (fw_size <= 32) 267f97b56f9SRasesh Mody goto out; 268f97b56f9SRasesh Mody 269f97b56f9SRasesh Mody snprintf(ver_str + size, (QEDE_PMD_DRV_VER_STR_SIZE - size), 270f97b56f9SRasesh Mody " MBI: %d.%d.%d", 271f97b56f9SRasesh Mody GET_MFW_FIELD(info->mbi_version, QED_MBI_VERSION_2), 272f97b56f9SRasesh Mody GET_MFW_FIELD(info->mbi_version, QED_MBI_VERSION_1), 273f97b56f9SRasesh Mody GET_MFW_FIELD(info->mbi_version, QED_MBI_VERSION_0)); 274f97b56f9SRasesh Mody size = strlen(ver_str); 275f97b56f9SRasesh Mody if (size + 1 <= fw_size) 276f97b56f9SRasesh Mody strlcpy(fw_ver, ver_str, fw_size); 277f97b56f9SRasesh Mody 278f97b56f9SRasesh Mody out: 279f97b56f9SRasesh Mody return 0; 280f97b56f9SRasesh Mody } 281f97b56f9SRasesh Mody 2822ea6f76aSRasesh Mody static void qede_interrupt_action(struct ecore_hwfn *p_hwfn) 2832ea6f76aSRasesh Mody { 284d459b043SManish Chopra OSAL_SPIN_LOCK(&p_hwfn->spq_lock); 2852ea6f76aSRasesh Mody ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn)); 286d459b043SManish Chopra OSAL_SPIN_UNLOCK(&p_hwfn->spq_lock); 2872ea6f76aSRasesh Mody } 2882ea6f76aSRasesh Mody 2892ea6f76aSRasesh Mody static void 290245aec28SShahed Shaikh qede_interrupt_handler_intx(void *param) 291245aec28SShahed Shaikh { 292245aec28SShahed Shaikh struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 293245aec28SShahed Shaikh struct qede_dev *qdev = eth_dev->data->dev_private; 294245aec28SShahed Shaikh struct ecore_dev *edev = &qdev->edev; 295245aec28SShahed Shaikh u64 status; 296245aec28SShahed Shaikh 297245aec28SShahed Shaikh /* Check if our device actually raised an interrupt */ 298245aec28SShahed Shaikh status = ecore_int_igu_read_sisr_reg(ECORE_LEADING_HWFN(edev)); 299245aec28SShahed Shaikh if (status & 0x1) { 300245aec28SShahed Shaikh qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 301245aec28SShahed Shaikh 3026bee9d5fSNithin Dabilpuram if (rte_intr_ack(eth_dev->intr_handle)) 3036bee9d5fSNithin Dabilpuram DP_ERR(edev, "rte_intr_ack failed\n"); 304245aec28SShahed Shaikh } 305245aec28SShahed Shaikh } 306245aec28SShahed Shaikh 307245aec28SShahed Shaikh static void 308c23a1a30SQi Zhang qede_interrupt_handler(void *param) 3092ea6f76aSRasesh Mody { 3102ea6f76aSRasesh Mody struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 3112ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 3122ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 3132ea6f76aSRasesh Mody 3142ea6f76aSRasesh Mody qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 3156bee9d5fSNithin Dabilpuram if (rte_intr_ack(eth_dev->intr_handle)) 3166bee9d5fSNithin Dabilpuram DP_ERR(edev, "rte_intr_ack failed\n"); 3172ea6f76aSRasesh Mody } 3182ea6f76aSRasesh Mody 3192ea6f76aSRasesh Mody static void 320a60704d1SRasesh Mody qede_assign_rxtx_handlers(struct rte_eth_dev *dev, bool is_dummy) 32181f88049SShahed Shaikh { 32274e5a25dSShahed Shaikh uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads; 32381f88049SShahed Shaikh struct qede_dev *qdev = dev->data->dev_private; 32481f88049SShahed Shaikh struct ecore_dev *edev = &qdev->edev; 32574e5a25dSShahed Shaikh bool use_tx_offload = false; 32681f88049SShahed Shaikh 327a60704d1SRasesh Mody if (is_dummy) { 328a60704d1SRasesh Mody dev->rx_pkt_burst = qede_rxtx_pkts_dummy; 329a60704d1SRasesh Mody dev->tx_pkt_burst = qede_rxtx_pkts_dummy; 330a60704d1SRasesh Mody return; 331a60704d1SRasesh Mody } 332a60704d1SRasesh Mody 33381f88049SShahed Shaikh if (ECORE_IS_CMT(edev)) { 33481f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts_cmt; 33581f88049SShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts_cmt; 33681f88049SShahed Shaikh return; 33781f88049SShahed Shaikh } 33881f88049SShahed Shaikh 33981f88049SShahed Shaikh if (dev->data->lro || dev->data->scattered_rx) { 34081f88049SShahed Shaikh DP_INFO(edev, "Assigning qede_recv_pkts\n"); 34181f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts; 34281f88049SShahed Shaikh } else { 34381f88049SShahed Shaikh DP_INFO(edev, "Assigning qede_recv_pkts_regular\n"); 34481f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts_regular; 34581f88049SShahed Shaikh } 34681f88049SShahed Shaikh 34774e5a25dSShahed Shaikh use_tx_offload = !!(tx_offloads & 34874e5a25dSShahed Shaikh (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | /* tunnel */ 34974e5a25dSShahed Shaikh DEV_TX_OFFLOAD_TCP_TSO | /* tso */ 35074e5a25dSShahed Shaikh DEV_TX_OFFLOAD_VLAN_INSERT)); /* vlan insert */ 35174e5a25dSShahed Shaikh 35274e5a25dSShahed Shaikh if (use_tx_offload) { 35374e5a25dSShahed Shaikh DP_INFO(edev, "Assigning qede_xmit_pkts\n"); 35481f88049SShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts; 35574e5a25dSShahed Shaikh } else { 35674e5a25dSShahed Shaikh DP_INFO(edev, "Assigning qede_xmit_pkts_regular\n"); 35774e5a25dSShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts_regular; 35874e5a25dSShahed Shaikh } 35981f88049SShahed Shaikh } 36081f88049SShahed Shaikh 36181f88049SShahed Shaikh static void 3622ea6f76aSRasesh Mody qede_alloc_etherdev(struct qede_dev *qdev, struct qed_dev_eth_info *info) 3632ea6f76aSRasesh Mody { 3642ea6f76aSRasesh Mody rte_memcpy(&qdev->dev_info, info, sizeof(*info)); 3652ea6f76aSRasesh Mody qdev->ops = qed_ops; 3662ea6f76aSRasesh Mody } 3672ea6f76aSRasesh Mody 368f97b56f9SRasesh Mody static void qede_print_adapter_info(struct rte_eth_dev *dev) 3692ea6f76aSRasesh Mody { 370f97b56f9SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 3712ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 3727eca78ceSHarish Patil static char ver_str[QEDE_PMD_DRV_VER_STR_SIZE]; 3732ea6f76aSRasesh Mody 3742b5243d7SRasesh Mody DP_INFO(edev, "**************************************************\n"); 375f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "DPDK version", rte_version()); 376f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s %c%d\n", "Chip details", 3772ea6f76aSRasesh Mody ECORE_IS_BB(edev) ? "BB" : "AH", 3783818ac22SRasesh Mody 'A' + edev->chip_rev, 3793818ac22SRasesh Mody (int)edev->chip_metal); 3802b5243d7SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 3812b5243d7SRasesh Mody QEDE_PMD_DRV_VERSION); 382f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "Driver version", ver_str); 3832b5243d7SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 3842b5243d7SRasesh Mody QEDE_PMD_BASE_VERSION); 385f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "Base version", ver_str); 386f97b56f9SRasesh Mody qede_fw_version_get(dev, ver_str, sizeof(ver_str)); 387f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "Firmware version", ver_str); 388f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "Firmware file", qede_fw_file); 3892b5243d7SRasesh Mody DP_INFO(edev, "**************************************************\n"); 3902ea6f76aSRasesh Mody } 3912ea6f76aSRasesh Mody 392ce26be6eSRasesh Mody static void qede_reset_queue_stats(struct qede_dev *qdev, bool xstats) 393ce26be6eSRasesh Mody { 3948de0c420SShahed Shaikh struct rte_eth_dev *dev = (struct rte_eth_dev *)qdev->ethdev; 395ce26be6eSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 396ce26be6eSRasesh Mody unsigned int i = 0, j = 0, qid; 397ce26be6eSRasesh Mody unsigned int rxq_stat_cntrs, txq_stat_cntrs; 398ce26be6eSRasesh Mody struct qede_tx_queue *txq; 399ce26be6eSRasesh Mody 400ce26be6eSRasesh Mody DP_VERBOSE(edev, ECORE_MSG_DEBUG, "Clearing queue stats\n"); 401ce26be6eSRasesh Mody 4028de0c420SShahed Shaikh rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(dev), 403ce26be6eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 4048de0c420SShahed Shaikh txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(dev), 405ce26be6eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 406ce26be6eSRasesh Mody 4078de0c420SShahed Shaikh for (qid = 0; qid < qdev->num_rx_queues; qid++) { 408ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 409ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rcv_pkts), 0, 410ce26be6eSRasesh Mody sizeof(uint64_t)); 411ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 412ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rx_hw_errors), 0, 413ce26be6eSRasesh Mody sizeof(uint64_t)); 414ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 415ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rx_alloc_errors), 0, 416ce26be6eSRasesh Mody sizeof(uint64_t)); 417ce26be6eSRasesh Mody 418ce26be6eSRasesh Mody if (xstats) 419ce26be6eSRasesh Mody for (j = 0; j < RTE_DIM(qede_rxq_xstats_strings); j++) 420ce26be6eSRasesh Mody OSAL_MEMSET((((char *) 421ce26be6eSRasesh Mody (qdev->fp_array[qid].rxq)) + 422ce26be6eSRasesh Mody qede_rxq_xstats_strings[j].offset), 423ce26be6eSRasesh Mody 0, 424ce26be6eSRasesh Mody sizeof(uint64_t)); 425ce26be6eSRasesh Mody 426ce26be6eSRasesh Mody i++; 427ce26be6eSRasesh Mody if (i == rxq_stat_cntrs) 428ce26be6eSRasesh Mody break; 429ce26be6eSRasesh Mody } 430ce26be6eSRasesh Mody 431ce26be6eSRasesh Mody i = 0; 432ce26be6eSRasesh Mody 4338de0c420SShahed Shaikh for (qid = 0; qid < qdev->num_tx_queues; qid++) { 434ce26be6eSRasesh Mody txq = qdev->fp_array[qid].txq; 435ce26be6eSRasesh Mody 436ce26be6eSRasesh Mody OSAL_MEMSET((uint64_t *)(uintptr_t) 437ce26be6eSRasesh Mody (((uint64_t)(uintptr_t)(txq)) + 438ce26be6eSRasesh Mody offsetof(struct qede_tx_queue, xmit_pkts)), 0, 439ce26be6eSRasesh Mody sizeof(uint64_t)); 440ce26be6eSRasesh Mody 441ce26be6eSRasesh Mody i++; 442ce26be6eSRasesh Mody if (i == txq_stat_cntrs) 443ce26be6eSRasesh Mody break; 444ce26be6eSRasesh Mody } 445ce26be6eSRasesh Mody } 446ce26be6eSRasesh Mody 4479a6d30aeSHarish Patil static int 4489a6d30aeSHarish Patil qede_stop_vport(struct ecore_dev *edev) 4499a6d30aeSHarish Patil { 4509a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 4519a6d30aeSHarish Patil uint8_t vport_id; 4529a6d30aeSHarish Patil int rc; 4539a6d30aeSHarish Patil int i; 4549a6d30aeSHarish Patil 4559a6d30aeSHarish Patil vport_id = 0; 4569a6d30aeSHarish Patil for_each_hwfn(edev, i) { 4579a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 4589a6d30aeSHarish Patil rc = ecore_sp_vport_stop(p_hwfn, p_hwfn->hw_info.opaque_fid, 4599a6d30aeSHarish Patil vport_id); 4609a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 4619a6d30aeSHarish Patil DP_ERR(edev, "Stop V-PORT failed rc = %d\n", rc); 4629a6d30aeSHarish Patil return rc; 4639a6d30aeSHarish Patil } 4649a6d30aeSHarish Patil } 4659a6d30aeSHarish Patil 466dd28bc8cSHarish Patil DP_INFO(edev, "vport stopped\n"); 467dd28bc8cSHarish Patil 468dd28bc8cSHarish Patil return 0; 469dd28bc8cSHarish Patil } 470dd28bc8cSHarish Patil 471dd28bc8cSHarish Patil static int 472dd28bc8cSHarish Patil qede_start_vport(struct qede_dev *qdev, uint16_t mtu) 473dd28bc8cSHarish Patil { 474dd28bc8cSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 475dd28bc8cSHarish Patil struct ecore_sp_vport_start_params params; 476dd28bc8cSHarish Patil struct ecore_hwfn *p_hwfn; 477dd28bc8cSHarish Patil int rc; 478dd28bc8cSHarish Patil int i; 479dd28bc8cSHarish Patil 480dd28bc8cSHarish Patil if (qdev->vport_started) 481dd28bc8cSHarish Patil qede_stop_vport(edev); 482dd28bc8cSHarish Patil 483dd28bc8cSHarish Patil memset(¶ms, 0, sizeof(params)); 484dd28bc8cSHarish Patil params.vport_id = 0; 485dd28bc8cSHarish Patil params.mtu = mtu; 486dd28bc8cSHarish Patil /* @DPDK - Disable FW placement */ 487dd28bc8cSHarish Patil params.zero_placement_offset = 1; 488dd28bc8cSHarish Patil for_each_hwfn(edev, i) { 489dd28bc8cSHarish Patil p_hwfn = &edev->hwfns[i]; 490dd28bc8cSHarish Patil params.concrete_fid = p_hwfn->hw_info.concrete_fid; 491dd28bc8cSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 492dd28bc8cSHarish Patil rc = ecore_sp_vport_start(p_hwfn, ¶ms); 493dd28bc8cSHarish Patil if (rc != ECORE_SUCCESS) { 494dd28bc8cSHarish Patil DP_ERR(edev, "Start V-PORT failed %d\n", rc); 495dd28bc8cSHarish Patil return rc; 496dd28bc8cSHarish Patil } 497dd28bc8cSHarish Patil } 498dd28bc8cSHarish Patil ecore_reset_vport_stats(edev); 499dd28bc8cSHarish Patil qdev->vport_started = true; 500dd28bc8cSHarish Patil DP_INFO(edev, "VPORT started with MTU = %u\n", mtu); 501dd28bc8cSHarish Patil 5029a6d30aeSHarish Patil return 0; 5039a6d30aeSHarish Patil } 5049a6d30aeSHarish Patil 505612ce81bSRasesh Mody #define QEDE_NPAR_TX_SWITCHING "npar_tx_switching" 506612ce81bSRasesh Mody #define QEDE_VF_TX_SWITCHING "vf_tx_switching" 507612ce81bSRasesh Mody 5089a6d30aeSHarish Patil /* Activate or deactivate vport via vport-update */ 5099a6d30aeSHarish Patil int qede_activate_vport(struct rte_eth_dev *eth_dev, bool flg) 5109a6d30aeSHarish Patil { 5119a6d30aeSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 5129a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 5139a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 5149a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 5159a6d30aeSHarish Patil uint8_t i; 5169a6d30aeSHarish Patil int rc = -1; 5179a6d30aeSHarish Patil 5189a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 5199a6d30aeSHarish Patil params.vport_id = 0; 5209a6d30aeSHarish Patil params.update_vport_active_rx_flg = 1; 5219a6d30aeSHarish Patil params.update_vport_active_tx_flg = 1; 5229a6d30aeSHarish Patil params.vport_active_rx_flg = flg; 5239a6d30aeSHarish Patil params.vport_active_tx_flg = flg; 524d0ef40a1SDharmik Thakkar if ((qdev->enable_tx_switching == false) && (flg == true)) { 525f07aa795SHarish Patil params.update_tx_switching_flg = 1; 526f07aa795SHarish Patil params.tx_switching_flg = !flg; 527f64b91b0SRasesh Mody } 5289a6d30aeSHarish Patil for_each_hwfn(edev, i) { 5299a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 5309a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 5319a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 5329a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 5339a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 5349a6d30aeSHarish Patil DP_ERR(edev, "Failed to update vport\n"); 5359a6d30aeSHarish Patil break; 5369a6d30aeSHarish Patil } 5379a6d30aeSHarish Patil } 5381282943aSHarish Patil DP_INFO(edev, "vport is %s\n", flg ? "activated" : "deactivated"); 5391282943aSHarish Patil 5409a6d30aeSHarish Patil return rc; 5419a6d30aeSHarish Patil } 5429a6d30aeSHarish Patil 5439a6d30aeSHarish Patil static void 5449a6d30aeSHarish Patil qede_update_sge_tpa_params(struct ecore_sge_tpa_params *sge_tpa_params, 5459a6d30aeSHarish Patil uint16_t mtu, bool enable) 5469a6d30aeSHarish Patil { 5479a6d30aeSHarish Patil /* Enable LRO in split mode */ 5489a6d30aeSHarish Patil sge_tpa_params->tpa_ipv4_en_flg = enable; 5499a6d30aeSHarish Patil sge_tpa_params->tpa_ipv6_en_flg = enable; 550749d2329SHarish Patil sge_tpa_params->tpa_ipv4_tunn_en_flg = enable; 551749d2329SHarish Patil sge_tpa_params->tpa_ipv6_tunn_en_flg = enable; 5529a6d30aeSHarish Patil /* set if tpa enable changes */ 5539a6d30aeSHarish Patil sge_tpa_params->update_tpa_en_flg = 1; 5549a6d30aeSHarish Patil /* set if tpa parameters should be handled */ 5559a6d30aeSHarish Patil sge_tpa_params->update_tpa_param_flg = enable; 5569a6d30aeSHarish Patil 5579a6d30aeSHarish Patil sge_tpa_params->max_buffers_per_cqe = 20; 5589a6d30aeSHarish Patil /* Enable TPA in split mode. In this mode each TPA segment 5599a6d30aeSHarish Patil * starts on the new BD, so there is one BD per segment. 5609a6d30aeSHarish Patil */ 5619a6d30aeSHarish Patil sge_tpa_params->tpa_pkt_split_flg = 1; 5629a6d30aeSHarish Patil sge_tpa_params->tpa_hdr_data_split_flg = 0; 5639a6d30aeSHarish Patil sge_tpa_params->tpa_gro_consistent_flg = 0; 5649a6d30aeSHarish Patil sge_tpa_params->tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM; 5659a6d30aeSHarish Patil sge_tpa_params->tpa_max_size = 0x7FFF; 5669a6d30aeSHarish Patil sge_tpa_params->tpa_min_size_to_start = mtu / 2; 5679a6d30aeSHarish Patil sge_tpa_params->tpa_min_size_to_cont = mtu / 2; 5689a6d30aeSHarish Patil } 5699a6d30aeSHarish Patil 5709a6d30aeSHarish Patil /* Enable/disable LRO via vport-update */ 5719a6d30aeSHarish Patil int qede_enable_tpa(struct rte_eth_dev *eth_dev, bool flg) 5729a6d30aeSHarish Patil { 5739a6d30aeSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 5749a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 5759a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 5769a6d30aeSHarish Patil struct ecore_sge_tpa_params tpa_params; 5779a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 5789a6d30aeSHarish Patil int rc; 5799a6d30aeSHarish Patil int i; 5809a6d30aeSHarish Patil 5819a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 5829a6d30aeSHarish Patil memset(&tpa_params, 0, sizeof(struct ecore_sge_tpa_params)); 5839a6d30aeSHarish Patil qede_update_sge_tpa_params(&tpa_params, qdev->mtu, flg); 5849a6d30aeSHarish Patil params.vport_id = 0; 5859a6d30aeSHarish Patil params.sge_tpa_params = &tpa_params; 5869a6d30aeSHarish Patil for_each_hwfn(edev, i) { 5879a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 5889a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 5899a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 5909a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 5919a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 5929a6d30aeSHarish Patil DP_ERR(edev, "Failed to update LRO\n"); 5939a6d30aeSHarish Patil return -1; 5949a6d30aeSHarish Patil } 5959a6d30aeSHarish Patil } 596daee4e07SHarish Patil qdev->enable_lro = flg; 597946dfd18SHarish Patil eth_dev->data->lro = flg; 598946dfd18SHarish Patil 5999a6d30aeSHarish Patil DP_INFO(edev, "LRO is %s\n", flg ? "enabled" : "disabled"); 6009a6d30aeSHarish Patil 6019a6d30aeSHarish Patil return 0; 6029a6d30aeSHarish Patil } 6039a6d30aeSHarish Patil 6044c4bdadfSHarish Patil static int 6054c4bdadfSHarish Patil qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev, 6064c4bdadfSHarish Patil enum qed_filter_rx_mode_type type) 6074c4bdadfSHarish Patil { 6084c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 6094c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 6104c4bdadfSHarish Patil struct ecore_filter_accept_flags flags; 6114c4bdadfSHarish Patil 6124c4bdadfSHarish Patil memset(&flags, 0, sizeof(flags)); 6134c4bdadfSHarish Patil 6144c4bdadfSHarish Patil flags.update_rx_mode_config = 1; 6154c4bdadfSHarish Patil flags.update_tx_mode_config = 1; 6164c4bdadfSHarish Patil flags.rx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 6174c4bdadfSHarish Patil ECORE_ACCEPT_MCAST_MATCHED | 6184c4bdadfSHarish Patil ECORE_ACCEPT_BCAST; 6194c4bdadfSHarish Patil 6204c4bdadfSHarish Patil flags.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 6214c4bdadfSHarish Patil ECORE_ACCEPT_MCAST_MATCHED | 6224c4bdadfSHarish Patil ECORE_ACCEPT_BCAST; 6234c4bdadfSHarish Patil 6244c4bdadfSHarish Patil if (type == QED_FILTER_RX_MODE_TYPE_PROMISC) { 625b10231aeSDevendra Singh Rawat flags.rx_accept_filter |= (ECORE_ACCEPT_UCAST_UNMATCHED | 626b10231aeSDevendra Singh Rawat ECORE_ACCEPT_MCAST_UNMATCHED); 6274c4bdadfSHarish Patil if (IS_VF(edev)) { 628b10231aeSDevendra Singh Rawat flags.tx_accept_filter |= 629b10231aeSDevendra Singh Rawat (ECORE_ACCEPT_UCAST_UNMATCHED | 630b10231aeSDevendra Singh Rawat ECORE_ACCEPT_MCAST_UNMATCHED); 631b10231aeSDevendra Singh Rawat DP_INFO(edev, "Enabling Tx unmatched flags for VF\n"); 6324c4bdadfSHarish Patil } 6334c4bdadfSHarish Patil } else if (type == QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC) { 6344c4bdadfSHarish Patil flags.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 6354c4bdadfSHarish Patil } 6364c4bdadfSHarish Patil 6374c4bdadfSHarish Patil return ecore_filter_accept_cmd(edev, 0, flags, false, false, 6384c4bdadfSHarish Patil ECORE_SPQ_MODE_CB, NULL); 6394c4bdadfSHarish Patil } 640e0947ed9SHarish Patil 641eb54ba75SShahed Shaikh int 64277fac1b5SHarish Patil qede_ucast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast, 64377fac1b5SHarish Patil bool add) 64477fac1b5SHarish Patil { 64577fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 64677fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 64777fac1b5SHarish Patil struct qede_ucast_entry *tmp = NULL; 64877fac1b5SHarish Patil struct qede_ucast_entry *u; 6496d13ea8eSOlivier Matz struct rte_ether_addr *mac_addr; 65077fac1b5SHarish Patil 6516d13ea8eSOlivier Matz mac_addr = (struct rte_ether_addr *)ucast->mac; 65277fac1b5SHarish Patil if (add) { 65377fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->uc_list_head, list) { 65477fac1b5SHarish Patil if ((memcmp(mac_addr, &tmp->mac, 65535b2d13fSOlivier Matz RTE_ETHER_ADDR_LEN) == 0) && 656d2a2468eSRasesh Mody ucast->vni == tmp->vni && 65777fac1b5SHarish Patil ucast->vlan == tmp->vlan) { 658f8d2581eSShahed Shaikh DP_INFO(edev, "Unicast MAC is already added" 65977fac1b5SHarish Patil " with vlan = %u, vni = %u\n", 66077fac1b5SHarish Patil ucast->vlan, ucast->vni); 661f8d2581eSShahed Shaikh return 0; 66277fac1b5SHarish Patil } 66377fac1b5SHarish Patil } 66477fac1b5SHarish Patil u = rte_malloc(NULL, sizeof(struct qede_ucast_entry), 66577fac1b5SHarish Patil RTE_CACHE_LINE_SIZE); 66677fac1b5SHarish Patil if (!u) { 66777fac1b5SHarish Patil DP_ERR(edev, "Did not allocate memory for ucast\n"); 66877fac1b5SHarish Patil return -ENOMEM; 66977fac1b5SHarish Patil } 670538da7a1SOlivier Matz rte_ether_addr_copy(mac_addr, &u->mac); 67177fac1b5SHarish Patil u->vlan = ucast->vlan; 67252d94b57SHarish Patil u->vni = ucast->vni; 67377fac1b5SHarish Patil SLIST_INSERT_HEAD(&qdev->uc_list_head, u, list); 67477fac1b5SHarish Patil qdev->num_uc_addr++; 67577fac1b5SHarish Patil } else { 67677fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->uc_list_head, list) { 67777fac1b5SHarish Patil if ((memcmp(mac_addr, &tmp->mac, 67835b2d13fSOlivier Matz RTE_ETHER_ADDR_LEN) == 0) && 67952d94b57SHarish Patil ucast->vlan == tmp->vlan && 68052d94b57SHarish Patil ucast->vni == tmp->vni) 68177fac1b5SHarish Patil break; 68277fac1b5SHarish Patil } 68377fac1b5SHarish Patil if (tmp == NULL) { 68477fac1b5SHarish Patil DP_INFO(edev, "Unicast MAC is not found\n"); 68577fac1b5SHarish Patil return -EINVAL; 68677fac1b5SHarish Patil } 68777fac1b5SHarish Patil SLIST_REMOVE(&qdev->uc_list_head, tmp, qede_ucast_entry, list); 68877fac1b5SHarish Patil qdev->num_uc_addr--; 68977fac1b5SHarish Patil } 69077fac1b5SHarish Patil 69177fac1b5SHarish Patil return 0; 69277fac1b5SHarish Patil } 69377fac1b5SHarish Patil 69477fac1b5SHarish Patil static int 6956d13ea8eSOlivier Matz qede_add_mcast_filters(struct rte_eth_dev *eth_dev, 6966d13ea8eSOlivier Matz struct rte_ether_addr *mc_addrs, 697413ecf29SHarish Patil uint32_t mc_addrs_num) 69877fac1b5SHarish Patil { 69977fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 70077fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 701413ecf29SHarish Patil struct ecore_filter_mcast mcast; 702413ecf29SHarish Patil struct qede_mcast_entry *m = NULL; 703413ecf29SHarish Patil uint8_t i; 704413ecf29SHarish Patil int rc; 70577fac1b5SHarish Patil 706413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) { 70777fac1b5SHarish Patil m = rte_malloc(NULL, sizeof(struct qede_mcast_entry), 70877fac1b5SHarish Patil RTE_CACHE_LINE_SIZE); 70977fac1b5SHarish Patil if (!m) { 710413ecf29SHarish Patil DP_ERR(edev, "Did not allocate memory for mcast\n"); 71177fac1b5SHarish Patil return -ENOMEM; 71277fac1b5SHarish Patil } 713538da7a1SOlivier Matz rte_ether_addr_copy(&mc_addrs[i], &m->mac); 71477fac1b5SHarish Patil SLIST_INSERT_HEAD(&qdev->mc_list_head, m, list); 715413ecf29SHarish Patil } 716413ecf29SHarish Patil memset(&mcast, 0, sizeof(mcast)); 717413ecf29SHarish Patil mcast.num_mc_addrs = mc_addrs_num; 718413ecf29SHarish Patil mcast.opcode = ECORE_FILTER_ADD; 719413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) 720538da7a1SOlivier Matz rte_ether_addr_copy(&mc_addrs[i], (struct rte_ether_addr *) 721413ecf29SHarish Patil &mcast.mac[i]); 722413ecf29SHarish Patil rc = ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL); 723413ecf29SHarish Patil if (rc != ECORE_SUCCESS) { 724413ecf29SHarish Patil DP_ERR(edev, "Failed to add multicast filter (rc = %d\n)", rc); 725413ecf29SHarish Patil return -1; 726413ecf29SHarish Patil } 727413ecf29SHarish Patil 728413ecf29SHarish Patil return 0; 729413ecf29SHarish Patil } 730413ecf29SHarish Patil 731413ecf29SHarish Patil static int qede_del_mcast_filters(struct rte_eth_dev *eth_dev) 732413ecf29SHarish Patil { 733413ecf29SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 734413ecf29SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 735413ecf29SHarish Patil struct qede_mcast_entry *tmp = NULL; 736413ecf29SHarish Patil struct ecore_filter_mcast mcast; 737413ecf29SHarish Patil int j; 738413ecf29SHarish Patil int rc; 739413ecf29SHarish Patil 740413ecf29SHarish Patil memset(&mcast, 0, sizeof(mcast)); 741413ecf29SHarish Patil mcast.num_mc_addrs = qdev->num_mc_addr; 742413ecf29SHarish Patil mcast.opcode = ECORE_FILTER_REMOVE; 743413ecf29SHarish Patil j = 0; 74477fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->mc_list_head, list) { 745538da7a1SOlivier Matz rte_ether_addr_copy(&tmp->mac, 7466d13ea8eSOlivier Matz (struct rte_ether_addr *)&mcast.mac[j]); 747413ecf29SHarish Patil j++; 74877fac1b5SHarish Patil } 749413ecf29SHarish Patil rc = ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL); 750413ecf29SHarish Patil if (rc != ECORE_SUCCESS) { 751413ecf29SHarish Patil DP_ERR(edev, "Failed to delete multicast filter\n"); 752413ecf29SHarish Patil return -1; 75377fac1b5SHarish Patil } 754413ecf29SHarish Patil /* Init the list */ 755413ecf29SHarish Patil while (!SLIST_EMPTY(&qdev->mc_list_head)) { 756413ecf29SHarish Patil tmp = SLIST_FIRST(&qdev->mc_list_head); 757413ecf29SHarish Patil SLIST_REMOVE_HEAD(&qdev->mc_list_head, list); 75877fac1b5SHarish Patil } 759413ecf29SHarish Patil SLIST_INIT(&qdev->mc_list_head); 76077fac1b5SHarish Patil 76177fac1b5SHarish Patil return 0; 76277fac1b5SHarish Patil } 76377fac1b5SHarish Patil 764eb54ba75SShahed Shaikh enum _ecore_status_t 76577fac1b5SHarish Patil qede_mac_int_ops(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast, 76677fac1b5SHarish Patil bool add) 76777fac1b5SHarish Patil { 76877fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 76977fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 770413ecf29SHarish Patil enum _ecore_status_t rc = ECORE_INVAL; 77177fac1b5SHarish Patil 772413ecf29SHarish Patil if (add && (qdev->num_uc_addr >= qdev->dev_info.num_mac_filters)) { 773413ecf29SHarish Patil DP_ERR(edev, "Ucast filter table limit exceeded," 77477fac1b5SHarish Patil " Please enable promisc mode\n"); 775413ecf29SHarish Patil return ECORE_INVAL; 77677fac1b5SHarish Patil } 777413ecf29SHarish Patil 77877fac1b5SHarish Patil rc = qede_ucast_filter(eth_dev, ucast, add); 77977fac1b5SHarish Patil if (rc == 0) 78077fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, ucast, 78177fac1b5SHarish Patil ECORE_SPQ_MODE_CB, NULL); 7827e3060a3SShahed Shaikh /* Indicate error only for add filter operation. 7837e3060a3SShahed Shaikh * Delete filter operations are not severe. 7847e3060a3SShahed Shaikh */ 7857e3060a3SShahed Shaikh if ((rc != ECORE_SUCCESS) && add) 78677fac1b5SHarish Patil DP_ERR(edev, "MAC filter failed, rc = %d, op = %d\n", 78777fac1b5SHarish Patil rc, add); 78877fac1b5SHarish Patil 78977fac1b5SHarish Patil return rc; 7902ea6f76aSRasesh Mody } 7912ea6f76aSRasesh Mody 7926d01e580SWei Dai static int 7936d13ea8eSOlivier Matz qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr, 794af785e47SRasesh Mody __rte_unused uint32_t index, __rte_unused uint32_t pool) 7952ea6f76aSRasesh Mody { 79677fac1b5SHarish Patil struct ecore_filter_ucast ucast; 7976d01e580SWei Dai int re; 7982ea6f76aSRasesh Mody 799538da7a1SOlivier Matz if (!rte_is_valid_assigned_ether_addr(mac_addr)) 800c7641841SShahed Shaikh return -EINVAL; 801c7641841SShahed Shaikh 80277fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 803c7641841SShahed Shaikh ucast.opcode = ECORE_FILTER_ADD; 80477fac1b5SHarish Patil ucast.type = ECORE_FILTER_MAC; 805538da7a1SOlivier Matz rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)&ucast.mac); 8066d01e580SWei Dai re = (int)qede_mac_int_ops(eth_dev, &ucast, 1); 8076d01e580SWei Dai return re; 8082ea6f76aSRasesh Mody } 8092ea6f76aSRasesh Mody 8102ea6f76aSRasesh Mody static void 8112ea6f76aSRasesh Mody qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index) 8122ea6f76aSRasesh Mody { 8132ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 8142ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 81577fac1b5SHarish Patil struct ecore_filter_ucast ucast; 8162ea6f76aSRasesh Mody 8172ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 8182ea6f76aSRasesh Mody 8193320ca8cSRasesh Mody if (index >= qdev->dev_info.num_mac_filters) { 8202ea6f76aSRasesh Mody DP_ERR(edev, "Index %u is above MAC filter limit %u\n", 8213320ca8cSRasesh Mody index, qdev->dev_info.num_mac_filters); 8222ea6f76aSRasesh Mody return; 8232ea6f76aSRasesh Mody } 8242ea6f76aSRasesh Mody 825538da7a1SOlivier Matz if (!rte_is_valid_assigned_ether_addr(ð_dev->data->mac_addrs[index])) 826c7641841SShahed Shaikh return; 827c7641841SShahed Shaikh 82877fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 82977fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_REMOVE; 83077fac1b5SHarish Patil ucast.type = ECORE_FILTER_MAC; 83177fac1b5SHarish Patil 8322ea6f76aSRasesh Mody /* Use the index maintained by rte */ 833538da7a1SOlivier Matz rte_ether_addr_copy(ð_dev->data->mac_addrs[index], 8346d13ea8eSOlivier Matz (struct rte_ether_addr *)&ucast.mac); 83577fac1b5SHarish Patil 83683ade1ebSRasesh Mody qede_mac_int_ops(eth_dev, &ucast, false); 8372ea6f76aSRasesh Mody } 8382ea6f76aSRasesh Mody 839caccf8b3SOlivier Matz static int 8406d13ea8eSOlivier Matz qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr) 8412ea6f76aSRasesh Mody { 8422ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 8432ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8442ea6f76aSRasesh Mody 84586a2265eSRasesh Mody if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev), 84686a2265eSRasesh Mody mac_addr->addr_bytes)) { 84786a2265eSRasesh Mody DP_ERR(edev, "Setting MAC address is not allowed\n"); 848caccf8b3SOlivier Matz return -EPERM; 84986a2265eSRasesh Mody } 85086a2265eSRasesh Mody 851c7641841SShahed Shaikh qede_mac_addr_remove(eth_dev, 0); 852c7641841SShahed Shaikh 853c7641841SShahed Shaikh return qede_mac_addr_add(eth_dev, mac_addr, 0, 0); 8542ea6f76aSRasesh Mody } 8552ea6f76aSRasesh Mody 856eb54ba75SShahed Shaikh void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg) 8572ea6f76aSRasesh Mody { 8589a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8599a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 8609a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 8619a6d30aeSHarish Patil uint8_t i; 8622ea6f76aSRasesh Mody int rc; 8632ea6f76aSRasesh Mody 8649a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 8659a6d30aeSHarish Patil params.vport_id = 0; 8669a6d30aeSHarish Patil params.update_accept_any_vlan_flg = 1; 8679a6d30aeSHarish Patil params.accept_any_vlan = flg; 8689a6d30aeSHarish Patil for_each_hwfn(edev, i) { 8699a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 8709a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 8719a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 8729a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 8739a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 8749a6d30aeSHarish Patil DP_ERR(edev, "Failed to configure accept-any-vlan\n"); 8752ea6f76aSRasesh Mody return; 8762ea6f76aSRasesh Mody } 8772ea6f76aSRasesh Mody } 8782ea6f76aSRasesh Mody 8799a6d30aeSHarish Patil DP_INFO(edev, "%s accept-any-vlan\n", flg ? "enabled" : "disabled"); 8809a6d30aeSHarish Patil } 8819a6d30aeSHarish Patil 8829a6d30aeSHarish Patil static int qede_vlan_stripping(struct rte_eth_dev *eth_dev, bool flg) 8832ea6f76aSRasesh Mody { 8842ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 8852ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8869a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 8879a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 8889a6d30aeSHarish Patil uint8_t i; 8892ea6f76aSRasesh Mody int rc; 8902ea6f76aSRasesh Mody 8919a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 8929a6d30aeSHarish Patil params.vport_id = 0; 8939a6d30aeSHarish Patil params.update_inner_vlan_removal_flg = 1; 8949a6d30aeSHarish Patil params.inner_vlan_removal_flg = flg; 8959a6d30aeSHarish Patil for_each_hwfn(edev, i) { 8969a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 8979a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 8989a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 8999a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 9009a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 9019a6d30aeSHarish Patil DP_ERR(edev, "Failed to update vport\n"); 9029a6d30aeSHarish Patil return -1; 9032ea6f76aSRasesh Mody } 9049a6d30aeSHarish Patil } 9052ea6f76aSRasesh Mody 90630b170b4SShahed Shaikh qdev->vlan_strip_flg = flg; 90730b170b4SShahed Shaikh 9089a6d30aeSHarish Patil DP_INFO(edev, "VLAN stripping %s\n", flg ? "enabled" : "disabled"); 9092ea6f76aSRasesh Mody return 0; 9102ea6f76aSRasesh Mody } 9112ea6f76aSRasesh Mody 9122ea6f76aSRasesh Mody static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev, 9132ea6f76aSRasesh Mody uint16_t vlan_id, int on) 9142ea6f76aSRasesh Mody { 9152ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 9162ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 9172ea6f76aSRasesh Mody struct qed_dev_eth_info *dev_info = &qdev->dev_info; 918d6cb1753SHarish Patil struct qede_vlan_entry *tmp = NULL; 919d6cb1753SHarish Patil struct qede_vlan_entry *vlan; 92077fac1b5SHarish Patil struct ecore_filter_ucast ucast; 9212ea6f76aSRasesh Mody int rc; 9222ea6f76aSRasesh Mody 923bec02288SSony Chacko if (on) { 924d6cb1753SHarish Patil if (qdev->configured_vlans == dev_info->num_vlan_filters) { 92561a8429fSRasesh Mody DP_ERR(edev, "Reached max VLAN filter limit" 9262ea6f76aSRasesh Mody " enabling accept_any_vlan\n"); 9272ea6f76aSRasesh Mody qede_config_accept_any_vlan(qdev, true); 9282ea6f76aSRasesh Mody return 0; 9292ea6f76aSRasesh Mody } 9302ea6f76aSRasesh Mody 931d6cb1753SHarish Patil SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) { 932d6cb1753SHarish Patil if (tmp->vid == vlan_id) { 933f8d2581eSShahed Shaikh DP_INFO(edev, "VLAN %u already configured\n", 9342ea6f76aSRasesh Mody vlan_id); 935f8d2581eSShahed Shaikh return 0; 936d6cb1753SHarish Patil } 9372ea6f76aSRasesh Mody } 9382ea6f76aSRasesh Mody 939d6cb1753SHarish Patil vlan = rte_malloc(NULL, sizeof(struct qede_vlan_entry), 940d6cb1753SHarish Patil RTE_CACHE_LINE_SIZE); 941d6cb1753SHarish Patil 942d6cb1753SHarish Patil if (!vlan) { 943d6cb1753SHarish Patil DP_ERR(edev, "Did not allocate memory for VLAN\n"); 944d6cb1753SHarish Patil return -ENOMEM; 945d6cb1753SHarish Patil } 946d6cb1753SHarish Patil 94777fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 94877fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_ADD; 94977fac1b5SHarish Patil ucast.type = ECORE_FILTER_VLAN; 95077fac1b5SHarish Patil ucast.vlan = vlan_id; 95177fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, 95277fac1b5SHarish Patil NULL); 95377fac1b5SHarish Patil if (rc != 0) { 954d6cb1753SHarish Patil DP_ERR(edev, "Failed to add VLAN %u rc %d\n", vlan_id, 955d6cb1753SHarish Patil rc); 956d6cb1753SHarish Patil rte_free(vlan); 957d6cb1753SHarish Patil } else { 958d6cb1753SHarish Patil vlan->vid = vlan_id; 959d6cb1753SHarish Patil SLIST_INSERT_HEAD(&qdev->vlan_list_head, vlan, list); 960d6cb1753SHarish Patil qdev->configured_vlans++; 961d6cb1753SHarish Patil DP_INFO(edev, "VLAN %u added, configured_vlans %u\n", 962d6cb1753SHarish Patil vlan_id, qdev->configured_vlans); 963d6cb1753SHarish Patil } 964d6cb1753SHarish Patil } else { 965d6cb1753SHarish Patil SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) { 966d6cb1753SHarish Patil if (tmp->vid == vlan_id) 967d6cb1753SHarish Patil break; 968d6cb1753SHarish Patil } 969d6cb1753SHarish Patil 970d6cb1753SHarish Patil if (!tmp) { 971d6cb1753SHarish Patil if (qdev->configured_vlans == 0) { 972d6cb1753SHarish Patil DP_INFO(edev, 973d6cb1753SHarish Patil "No VLAN filters configured yet\n"); 974d6cb1753SHarish Patil return 0; 975d6cb1753SHarish Patil } 976d6cb1753SHarish Patil 977d6cb1753SHarish Patil DP_ERR(edev, "VLAN %u not configured\n", vlan_id); 978d6cb1753SHarish Patil return -EINVAL; 979d6cb1753SHarish Patil } 980d6cb1753SHarish Patil 981d6cb1753SHarish Patil SLIST_REMOVE(&qdev->vlan_list_head, tmp, qede_vlan_entry, list); 982d6cb1753SHarish Patil 98377fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 98477fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_REMOVE; 98577fac1b5SHarish Patil ucast.type = ECORE_FILTER_VLAN; 98677fac1b5SHarish Patil ucast.vlan = vlan_id; 98777fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, 98877fac1b5SHarish Patil NULL); 98977fac1b5SHarish Patil if (rc != 0) { 990d6cb1753SHarish Patil DP_ERR(edev, "Failed to delete VLAN %u rc %d\n", 991d6cb1753SHarish Patil vlan_id, rc); 992d6cb1753SHarish Patil } else { 993d6cb1753SHarish Patil qdev->configured_vlans--; 994d6cb1753SHarish Patil DP_INFO(edev, "VLAN %u removed configured_vlans %u\n", 995d6cb1753SHarish Patil vlan_id, qdev->configured_vlans); 996d6cb1753SHarish Patil } 997d6cb1753SHarish Patil } 9982ea6f76aSRasesh Mody 9992ea6f76aSRasesh Mody return rc; 10002ea6f76aSRasesh Mody } 10012ea6f76aSRasesh Mody 1002289ba0c0SDavid Harton static int qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) 1003af785e47SRasesh Mody { 1004af785e47SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1005af785e47SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1006946dfd18SHarish Patil uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; 1007af785e47SRasesh Mody 1008af785e47SRasesh Mody if (mask & ETH_VLAN_STRIP_MASK) { 1009946dfd18SHarish Patil if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 1010af785e47SRasesh Mody (void)qede_vlan_stripping(eth_dev, 1); 1011af785e47SRasesh Mody else 1012af785e47SRasesh Mody (void)qede_vlan_stripping(eth_dev, 0); 1013af785e47SRasesh Mody } 1014af785e47SRasesh Mody 1015af785e47SRasesh Mody if (mask & ETH_VLAN_FILTER_MASK) { 1016af785e47SRasesh Mody /* VLAN filtering kicks in when a VLAN is added */ 1017946dfd18SHarish Patil if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { 1018af785e47SRasesh Mody qede_vlan_filter_set(eth_dev, 0, 1); 1019af785e47SRasesh Mody } else { 1020af785e47SRasesh Mody if (qdev->configured_vlans > 1) { /* Excluding VLAN0 */ 1021af785e47SRasesh Mody DP_ERR(edev, 1022af785e47SRasesh Mody " Please remove existing VLAN filters" 1023af785e47SRasesh Mody " before disabling VLAN filtering\n"); 1024af785e47SRasesh Mody /* Signal app that VLAN filtering is still 1025af785e47SRasesh Mody * enabled 1026af785e47SRasesh Mody */ 1027946dfd18SHarish Patil eth_dev->data->dev_conf.rxmode.offloads |= 1028946dfd18SHarish Patil DEV_RX_OFFLOAD_VLAN_FILTER; 1029af785e47SRasesh Mody } else { 1030af785e47SRasesh Mody qede_vlan_filter_set(eth_dev, 0, 0); 1031af785e47SRasesh Mody } 1032af785e47SRasesh Mody } 1033af785e47SRasesh Mody } 1034af785e47SRasesh Mody 1035dd28bc8cSHarish Patil qdev->vlan_offload_mask = mask; 1036dd28bc8cSHarish Patil 1037946dfd18SHarish Patil DP_INFO(edev, "VLAN offload mask %d\n", mask); 1038289ba0c0SDavid Harton 1039289ba0c0SDavid Harton return 0; 1040af785e47SRasesh Mody } 1041af785e47SRasesh Mody 10427ab35bf6SHarish Patil static void qede_prandom_bytes(uint32_t *buff) 10437ab35bf6SHarish Patil { 10447ab35bf6SHarish Patil uint8_t i; 10457ab35bf6SHarish Patil 10467ab35bf6SHarish Patil srand((unsigned int)time(NULL)); 10477ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_KEY_SIZE; i++) 10487ab35bf6SHarish Patil buff[i] = rand(); 10497ab35bf6SHarish Patil } 10507ab35bf6SHarish Patil 10518130abb3SHarish Patil int qede_config_rss(struct rte_eth_dev *eth_dev) 10527ab35bf6SHarish Patil { 10537ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 10547ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 10557ab35bf6SHarish Patil uint32_t def_rss_key[ECORE_RSS_KEY_SIZE]; 10567ab35bf6SHarish Patil struct rte_eth_rss_reta_entry64 reta_conf[2]; 10577ab35bf6SHarish Patil struct rte_eth_rss_conf rss_conf; 10587ab35bf6SHarish Patil uint32_t i, id, pos, q; 10597ab35bf6SHarish Patil 10607ab35bf6SHarish Patil rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf; 10617ab35bf6SHarish Patil if (!rss_conf.rss_key) { 10627ab35bf6SHarish Patil DP_INFO(edev, "Applying driver default key\n"); 10637ab35bf6SHarish Patil rss_conf.rss_key_len = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); 10647ab35bf6SHarish Patil qede_prandom_bytes(&def_rss_key[0]); 10657ab35bf6SHarish Patil rss_conf.rss_key = (uint8_t *)&def_rss_key[0]; 10667ab35bf6SHarish Patil } 10677ab35bf6SHarish Patil 10687ab35bf6SHarish Patil /* Configure RSS hash */ 10697ab35bf6SHarish Patil if (qede_rss_hash_update(eth_dev, &rss_conf)) 10707ab35bf6SHarish Patil return -EINVAL; 10717ab35bf6SHarish Patil 10727ab35bf6SHarish Patil /* Configure default RETA */ 10737ab35bf6SHarish Patil memset(reta_conf, 0, sizeof(reta_conf)); 10747ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) 10757ab35bf6SHarish Patil reta_conf[i / RTE_RETA_GROUP_SIZE].mask = UINT64_MAX; 10767ab35bf6SHarish Patil 10777ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) { 10787ab35bf6SHarish Patil id = i / RTE_RETA_GROUP_SIZE; 10797ab35bf6SHarish Patil pos = i % RTE_RETA_GROUP_SIZE; 10808de0c420SShahed Shaikh q = i % QEDE_RSS_COUNT(eth_dev); 10817ab35bf6SHarish Patil reta_conf[id].reta[pos] = q; 10827ab35bf6SHarish Patil } 10837ab35bf6SHarish Patil if (qede_rss_reta_update(eth_dev, &reta_conf[0], 10847ab35bf6SHarish Patil ECORE_RSS_IND_TABLE_SIZE)) 10857ab35bf6SHarish Patil return -EINVAL; 10867ab35bf6SHarish Patil 10877ab35bf6SHarish Patil return 0; 10887ab35bf6SHarish Patil } 10897ab35bf6SHarish Patil 10904c4bdadfSHarish Patil static void qede_fastpath_start(struct ecore_dev *edev) 10914c4bdadfSHarish Patil { 10924c4bdadfSHarish Patil struct ecore_hwfn *p_hwfn; 10934c4bdadfSHarish Patil int i; 10944c4bdadfSHarish Patil 10954c4bdadfSHarish Patil for_each_hwfn(edev, i) { 10964c4bdadfSHarish Patil p_hwfn = &edev->hwfns[i]; 10974c4bdadfSHarish Patil ecore_hw_start_fastpath(p_hwfn); 10984c4bdadfSHarish Patil } 10994c4bdadfSHarish Patil } 11004c4bdadfSHarish Patil 11014c4bdadfSHarish Patil static int qede_dev_start(struct rte_eth_dev *eth_dev) 11024c4bdadfSHarish Patil { 11034c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 11044c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1105946dfd18SHarish Patil struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode; 11064c4bdadfSHarish Patil 11074c4bdadfSHarish Patil PMD_INIT_FUNC_TRACE(edev); 11084c4bdadfSHarish Patil 1109d121a6b5SRasesh Mody /* Update MTU only if it has changed */ 111029bb154fSShahed Shaikh if (qdev->new_mtu && qdev->new_mtu != qdev->mtu) { 111129bb154fSShahed Shaikh if (qede_update_mtu(eth_dev, qdev->new_mtu)) 1112d121a6b5SRasesh Mody goto err; 111329bb154fSShahed Shaikh qdev->mtu = qdev->new_mtu; 111429bb154fSShahed Shaikh qdev->new_mtu = 0; 1115d121a6b5SRasesh Mody } 1116d121a6b5SRasesh Mody 1117daee4e07SHarish Patil /* Configure TPA parameters */ 1118946dfd18SHarish Patil if (rxmode->offloads & DEV_RX_OFFLOAD_TCP_LRO) { 11194c4bdadfSHarish Patil if (qede_enable_tpa(eth_dev, true)) 1120daee4e07SHarish Patil return -EINVAL; 1121daee4e07SHarish Patil /* Enable scatter mode for LRO */ 1122946dfd18SHarish Patil if (!eth_dev->data->scattered_rx) 1123946dfd18SHarish Patil rxmode->offloads |= DEV_RX_OFFLOAD_SCATTER; 11244c4bdadfSHarish Patil } 11254c4bdadfSHarish Patil 11264c4bdadfSHarish Patil /* Start queues */ 11274c4bdadfSHarish Patil if (qede_start_queues(eth_dev)) 11284c4bdadfSHarish Patil goto err; 11294c4bdadfSHarish Patil 1130dd28bc8cSHarish Patil if (IS_PF(edev)) 1131dd28bc8cSHarish Patil qede_reset_queue_stats(qdev, true); 1132dd28bc8cSHarish Patil 11334c4bdadfSHarish Patil /* Newer SR-IOV PF driver expects RX/TX queues to be started before 11344c4bdadfSHarish Patil * enabling RSS. Hence RSS configuration is deferred up to this point. 11354c4bdadfSHarish Patil * Also, we would like to retain similar behavior in PF case, so we 11364c4bdadfSHarish Patil * don't do PF/VF specific check here. 11374c4bdadfSHarish Patil */ 1138946dfd18SHarish Patil if (eth_dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) 11394c4bdadfSHarish Patil if (qede_config_rss(eth_dev)) 11404c4bdadfSHarish Patil goto err; 11414c4bdadfSHarish Patil 11424c4bdadfSHarish Patil /* Enable vport*/ 11434c4bdadfSHarish Patil if (qede_activate_vport(eth_dev, true)) 11444c4bdadfSHarish Patil goto err; 11454c4bdadfSHarish Patil 1146d7897058SRasesh Mody /* Bring-up the link */ 1147d7897058SRasesh Mody qede_dev_set_link_state(eth_dev, true); 1148d7897058SRasesh Mody 11498aab5d6fSRasesh Mody /* Update link status */ 11508aab5d6fSRasesh Mody qede_link_update(eth_dev, 0); 11518aab5d6fSRasesh Mody 11524c4bdadfSHarish Patil /* Start/resume traffic */ 11534c4bdadfSHarish Patil qede_fastpath_start(edev); 11544c4bdadfSHarish Patil 1155a60704d1SRasesh Mody /* Assign I/O handlers */ 1156a60704d1SRasesh Mody qede_assign_rxtx_handlers(eth_dev, false); 1157a60704d1SRasesh Mody 11584c4bdadfSHarish Patil DP_INFO(edev, "Device started\n"); 11594c4bdadfSHarish Patil 11604c4bdadfSHarish Patil return 0; 11614c4bdadfSHarish Patil err: 11624c4bdadfSHarish Patil DP_ERR(edev, "Device start fails\n"); 11634c4bdadfSHarish Patil return -1; /* common error code is < 0 */ 11644c4bdadfSHarish Patil } 11654c4bdadfSHarish Patil 116662024eb8SIvan Ilchenko static int qede_dev_stop(struct rte_eth_dev *eth_dev) 11674c4bdadfSHarish Patil { 11684c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 11694c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 11704c4bdadfSHarish Patil 11714c4bdadfSHarish Patil PMD_INIT_FUNC_TRACE(edev); 1172b8f5d2aeSThomas Monjalon eth_dev->data->dev_started = 0; 11734c4bdadfSHarish Patil 1174d7897058SRasesh Mody /* Bring the link down */ 1175d7897058SRasesh Mody qede_dev_set_link_state(eth_dev, false); 1176d7897058SRasesh Mody 1177d7897058SRasesh Mody /* Update link status */ 1178d7897058SRasesh Mody qede_link_update(eth_dev, 0); 1179d7897058SRasesh Mody 1180a60704d1SRasesh Mody /* Replace I/O functions with dummy ones. It cannot 1181a60704d1SRasesh Mody * be set to NULL because rte_eth_rx_burst() doesn't check for NULL. 1182a60704d1SRasesh Mody */ 1183a60704d1SRasesh Mody qede_assign_rxtx_handlers(eth_dev, true); 1184a60704d1SRasesh Mody 11854c4bdadfSHarish Patil /* Disable vport */ 11864c4bdadfSHarish Patil if (qede_activate_vport(eth_dev, false)) 118762024eb8SIvan Ilchenko return 0; 11884c4bdadfSHarish Patil 11894c4bdadfSHarish Patil if (qdev->enable_lro) 11904c4bdadfSHarish Patil qede_enable_tpa(eth_dev, false); 11914c4bdadfSHarish Patil 11924c4bdadfSHarish Patil /* Stop queues */ 11934c4bdadfSHarish Patil qede_stop_queues(eth_dev); 11944c4bdadfSHarish Patil 11954c4bdadfSHarish Patil /* Disable traffic */ 11964c4bdadfSHarish Patil ecore_hw_stop_fastpath(edev); /* TBD - loop */ 11974c4bdadfSHarish Patil 11984c4bdadfSHarish Patil DP_INFO(edev, "Device is stopped\n"); 119962024eb8SIvan Ilchenko 120062024eb8SIvan Ilchenko return 0; 12014c4bdadfSHarish Patil } 12024c4bdadfSHarish Patil 1203b74fd6b8SFerruh Yigit static const char * const valid_args[] = { 1204612ce81bSRasesh Mody QEDE_NPAR_TX_SWITCHING, 1205612ce81bSRasesh Mody QEDE_VF_TX_SWITCHING, 1206f64b91b0SRasesh Mody NULL, 1207f64b91b0SRasesh Mody }; 1208f64b91b0SRasesh Mody 1209f64b91b0SRasesh Mody static int qede_args_check(const char *key, const char *val, void *opaque) 1210f64b91b0SRasesh Mody { 1211f64b91b0SRasesh Mody unsigned long tmp; 1212f64b91b0SRasesh Mody int ret = 0; 1213f64b91b0SRasesh Mody struct rte_eth_dev *eth_dev = opaque; 1214f64b91b0SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1215f64b91b0SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1216f64b91b0SRasesh Mody 1217f64b91b0SRasesh Mody errno = 0; 1218f64b91b0SRasesh Mody tmp = strtoul(val, NULL, 0); 1219f64b91b0SRasesh Mody if (errno) { 1220f64b91b0SRasesh Mody DP_INFO(edev, "%s: \"%s\" is not a valid integer", key, val); 1221f64b91b0SRasesh Mody return errno; 1222f64b91b0SRasesh Mody } 1223f64b91b0SRasesh Mody 1224612ce81bSRasesh Mody if ((strcmp(QEDE_NPAR_TX_SWITCHING, key) == 0) || 1225a16aef52SRasesh Mody ((strcmp(QEDE_VF_TX_SWITCHING, key) == 0) && IS_VF(edev))) { 1226f64b91b0SRasesh Mody qdev->enable_tx_switching = !!tmp; 1227a16aef52SRasesh Mody DP_INFO(edev, "Disabling %s tx-switching\n", 1228a16aef52SRasesh Mody strcmp(QEDE_NPAR_TX_SWITCHING, key) ? 1229a16aef52SRasesh Mody "VF" : "NPAR"); 1230a16aef52SRasesh Mody } 1231f64b91b0SRasesh Mody 1232f64b91b0SRasesh Mody return ret; 1233f64b91b0SRasesh Mody } 1234f64b91b0SRasesh Mody 1235f64b91b0SRasesh Mody static int qede_args(struct rte_eth_dev *eth_dev) 1236f64b91b0SRasesh Mody { 1237f64b91b0SRasesh Mody struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device); 1238f64b91b0SRasesh Mody struct rte_kvargs *kvlist; 1239f64b91b0SRasesh Mody struct rte_devargs *devargs; 1240f64b91b0SRasesh Mody int ret; 1241f64b91b0SRasesh Mody int i; 1242f64b91b0SRasesh Mody 1243f64b91b0SRasesh Mody devargs = pci_dev->device.devargs; 1244f64b91b0SRasesh Mody if (!devargs) 1245f64b91b0SRasesh Mody return 0; /* return success */ 1246f64b91b0SRasesh Mody 1247f64b91b0SRasesh Mody kvlist = rte_kvargs_parse(devargs->args, valid_args); 1248f64b91b0SRasesh Mody if (kvlist == NULL) 1249f64b91b0SRasesh Mody return -EINVAL; 1250f64b91b0SRasesh Mody 1251f64b91b0SRasesh Mody /* Process parameters. */ 1252f64b91b0SRasesh Mody for (i = 0; (valid_args[i] != NULL); ++i) { 1253f64b91b0SRasesh Mody if (rte_kvargs_count(kvlist, valid_args[i])) { 1254f64b91b0SRasesh Mody ret = rte_kvargs_process(kvlist, valid_args[i], 1255f64b91b0SRasesh Mody qede_args_check, eth_dev); 1256f64b91b0SRasesh Mody if (ret != ECORE_SUCCESS) { 1257f64b91b0SRasesh Mody rte_kvargs_free(kvlist); 1258f64b91b0SRasesh Mody return ret; 1259f64b91b0SRasesh Mody } 1260f64b91b0SRasesh Mody } 1261f64b91b0SRasesh Mody } 1262f64b91b0SRasesh Mody rte_kvargs_free(kvlist); 1263f64b91b0SRasesh Mody 1264f64b91b0SRasesh Mody return 0; 1265f64b91b0SRasesh Mody } 1266f64b91b0SRasesh Mody 12672ea6f76aSRasesh Mody static int qede_dev_configure(struct rte_eth_dev *eth_dev) 12682ea6f76aSRasesh Mody { 12694c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 12704c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 12712ea6f76aSRasesh Mody struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode; 127205ccc9d8SRasesh Mody uint8_t num_rxqs; 127305ccc9d8SRasesh Mody uint8_t num_txqs; 1274289ba0c0SDavid Harton int ret; 12752ea6f76aSRasesh Mody 12762ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 12772ea6f76aSRasesh Mody 127873fb89ddSAndrew Rybchenko if (rxmode->mq_mode & ETH_MQ_RX_RSS_FLAG) 12798b945a7fSPavan Nikhilesh rxmode->offloads |= DEV_RX_OFFLOAD_RSS_HASH; 12808b945a7fSPavan Nikhilesh 1281e60644c4SHarish Patil /* We need to have min 1 RX queue.There is no min check in 1282e60644c4SHarish Patil * rte_eth_dev_configure(), so we are checking it here. 1283e60644c4SHarish Patil */ 1284e60644c4SHarish Patil if (eth_dev->data->nb_rx_queues == 0) { 1285e60644c4SHarish Patil DP_ERR(edev, "Minimum one RX queue is required\n"); 1286e60644c4SHarish Patil return -EINVAL; 1287e60644c4SHarish Patil } 1288e60644c4SHarish Patil 1289f64b91b0SRasesh Mody /* Enable Tx switching by default */ 1290f64b91b0SRasesh Mody qdev->enable_tx_switching = 1; 1291f64b91b0SRasesh Mody 1292f64b91b0SRasesh Mody /* Parse devargs and fix up rxmode */ 1293f64b91b0SRasesh Mody if (qede_args(eth_dev)) 1294a16aef52SRasesh Mody DP_NOTICE(edev, false, 1295a16aef52SRasesh Mody "Invalid devargs supplied, requested change will not take effect\n"); 1296f64b91b0SRasesh Mody 1297946dfd18SHarish Patil if (!(rxmode->mq_mode == ETH_MQ_RX_NONE || 1298946dfd18SHarish Patil rxmode->mq_mode == ETH_MQ_RX_RSS)) { 12994c4bdadfSHarish Patil DP_ERR(edev, "Unsupported multi-queue mode\n"); 13004c4bdadfSHarish Patil return -ENOTSUP; 130129540be7SHarish Patil } 13024c4bdadfSHarish Patil /* Flow director mode check */ 13034c4bdadfSHarish Patil if (qede_check_fdir_support(eth_dev)) 13044c4bdadfSHarish Patil return -ENOTSUP; 130529540be7SHarish Patil 130605ccc9d8SRasesh Mody /* Allocate/reallocate fastpath resources only for new queue config */ 130705ccc9d8SRasesh Mody num_txqs = eth_dev->data->nb_tx_queues * edev->num_hwfns; 130805ccc9d8SRasesh Mody num_rxqs = eth_dev->data->nb_rx_queues * edev->num_hwfns; 130905ccc9d8SRasesh Mody if (qdev->num_tx_queues != num_txqs || 131005ccc9d8SRasesh Mody qdev->num_rx_queues != num_rxqs) { 13114c4bdadfSHarish Patil qede_dealloc_fp_resc(eth_dev); 131205ccc9d8SRasesh Mody qdev->num_tx_queues = num_txqs; 131305ccc9d8SRasesh Mody qdev->num_rx_queues = num_rxqs; 13144c4bdadfSHarish Patil if (qede_alloc_fp_resc(qdev)) 13154c4bdadfSHarish Patil return -ENOMEM; 131605ccc9d8SRasesh Mody } 13172ea6f76aSRasesh Mody 13189e334305SRasesh Mody /* If jumbo enabled adjust MTU */ 1319946dfd18SHarish Patil if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) 13209e334305SRasesh Mody eth_dev->data->mtu = 13219e334305SRasesh Mody eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - 132235b2d13fSOlivier Matz RTE_ETHER_HDR_LEN - QEDE_ETH_OVERHEAD; 13239e334305SRasesh Mody 1324946dfd18SHarish Patil if (rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) 1325946dfd18SHarish Patil eth_dev->data->scattered_rx = 1; 1326946dfd18SHarish Patil 13279e334305SRasesh Mody if (qede_start_vport(qdev, eth_dev->data->mtu)) 13289a6d30aeSHarish Patil return -1; 1329946dfd18SHarish Patil 13309e334305SRasesh Mody qdev->mtu = eth_dev->data->mtu; 1331dbac54c2SHarish Patil 1332d87246a4SHarish Patil /* Enable VLAN offloads by default */ 1333289ba0c0SDavid Harton ret = qede_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK | 1334c6dd1eb8SRasesh Mody ETH_VLAN_FILTER_MASK); 1335289ba0c0SDavid Harton if (ret) 1336289ba0c0SDavid Harton return ret; 1337d87246a4SHarish Patil 13384c4bdadfSHarish Patil DP_INFO(edev, "Device configured with RSS=%d TSS=%d\n", 13398de0c420SShahed Shaikh QEDE_RSS_COUNT(eth_dev), QEDE_TSS_COUNT(eth_dev)); 13408de0c420SShahed Shaikh 13418de0c420SShahed Shaikh if (ECORE_IS_CMT(edev)) 13428de0c420SShahed Shaikh DP_INFO(edev, "Actual HW queues for CMT mode - RX = %d TX = %d\n", 13438de0c420SShahed Shaikh qdev->num_rx_queues, qdev->num_tx_queues); 13448de0c420SShahed Shaikh 13459c5d0a66SHarish Patil 13462ea6f76aSRasesh Mody return 0; 13472ea6f76aSRasesh Mody } 13482ea6f76aSRasesh Mody 13492ea6f76aSRasesh Mody /* Info about HW descriptor ring limitations */ 13502ea6f76aSRasesh Mody static const struct rte_eth_desc_lim qede_rx_desc_lim = { 1351c008e17bSHarish Patil .nb_max = 0x8000, /* 32K */ 13522ea6f76aSRasesh Mody .nb_min = 128, 13532ea6f76aSRasesh Mody .nb_align = 128 /* lowest common multiple */ 13542ea6f76aSRasesh Mody }; 13552ea6f76aSRasesh Mody 13562ea6f76aSRasesh Mody static const struct rte_eth_desc_lim qede_tx_desc_lim = { 1357c008e17bSHarish Patil .nb_max = 0x8000, /* 32K */ 13582ea6f76aSRasesh Mody .nb_min = 256, 135929540be7SHarish Patil .nb_align = 256, 136029540be7SHarish Patil .nb_seg_max = ETH_TX_MAX_BDS_PER_LSO_PACKET, 136129540be7SHarish Patil .nb_mtu_seg_max = ETH_TX_MAX_BDS_PER_NON_LSO_PACKET 13622ea6f76aSRasesh Mody }; 13632ea6f76aSRasesh Mody 1364bdad90d1SIvan Ilchenko static int 13652ea6f76aSRasesh Mody qede_dev_info_get(struct rte_eth_dev *eth_dev, 13662ea6f76aSRasesh Mody struct rte_eth_dev_info *dev_info) 13672ea6f76aSRasesh Mody { 13682ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 13692ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 137064c239b7SHarish Patil struct qed_link_output link; 13711ea56b80SHarish Patil uint32_t speed_cap = 0; 13722ea6f76aSRasesh Mody 13732ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 13742ea6f76aSRasesh Mody 1375f6033f24SHarish Patil dev_info->min_rx_bufsize = (uint32_t)QEDE_MIN_RX_BUFF_SIZE; 13762ea6f76aSRasesh Mody dev_info->max_rx_pktlen = (uint32_t)ETH_TX_MAX_NON_LSO_PKT_LEN; 13772ea6f76aSRasesh Mody dev_info->rx_desc_lim = qede_rx_desc_lim; 13782ea6f76aSRasesh Mody dev_info->tx_desc_lim = qede_tx_desc_lim; 1379528fcfabSHarish Patil 1380528fcfabSHarish Patil if (IS_PF(edev)) 1381528fcfabSHarish Patil dev_info->max_rx_queues = (uint16_t)RTE_MIN( 1382528fcfabSHarish Patil QEDE_MAX_RSS_CNT(qdev), QEDE_PF_NUM_CONNS / 2); 1383528fcfabSHarish Patil else 1384528fcfabSHarish Patil dev_info->max_rx_queues = (uint16_t)RTE_MIN( 1385528fcfabSHarish Patil QEDE_MAX_RSS_CNT(qdev), ECORE_MAX_VF_CHAINS_PER_PF); 13868de0c420SShahed Shaikh /* Since CMT mode internally doubles the number of queues */ 13878de0c420SShahed Shaikh if (ECORE_IS_CMT(edev)) 13888de0c420SShahed Shaikh dev_info->max_rx_queues = dev_info->max_rx_queues / 2; 13898de0c420SShahed Shaikh 13902ea6f76aSRasesh Mody dev_info->max_tx_queues = dev_info->max_rx_queues; 1391528fcfabSHarish Patil 13923320ca8cSRasesh Mody dev_info->max_mac_addrs = qdev->dev_info.num_mac_filters; 139386a2265eSRasesh Mody dev_info->max_vfs = 0; 13945cdd769aSRasesh Mody dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE; 13957ab35bf6SHarish Patil dev_info->hash_key_size = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); 13962ea6f76aSRasesh Mody dev_info->flow_type_rss_offloads = (uint64_t)QEDE_RSS_OFFLOAD_ALL; 1397946dfd18SHarish Patil dev_info->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM | 13982ea6f76aSRasesh Mody DEV_RX_OFFLOAD_UDP_CKSUM | 13993d4bb441SHarish Patil DEV_RX_OFFLOAD_TCP_CKSUM | 140029540be7SHarish Patil DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | 1401946dfd18SHarish Patil DEV_RX_OFFLOAD_TCP_LRO | 140270815c9eSFerruh Yigit DEV_RX_OFFLOAD_KEEP_CRC | 1403946dfd18SHarish Patil DEV_RX_OFFLOAD_SCATTER | 1404946dfd18SHarish Patil DEV_RX_OFFLOAD_JUMBO_FRAME | 1405946dfd18SHarish Patil DEV_RX_OFFLOAD_VLAN_FILTER | 14068b945a7fSPavan Nikhilesh DEV_RX_OFFLOAD_VLAN_STRIP | 14078b945a7fSPavan Nikhilesh DEV_RX_OFFLOAD_RSS_HASH); 1408946dfd18SHarish Patil dev_info->rx_queue_offload_capa = 0; 140929540be7SHarish Patil 1410946dfd18SHarish Patil /* TX offloads are on a per-packet basis, so it is applicable 1411946dfd18SHarish Patil * to both at port and queue levels. 1412946dfd18SHarish Patil */ 14132ea6f76aSRasesh Mody dev_info->tx_offload_capa = (DEV_TX_OFFLOAD_VLAN_INSERT | 14142ea6f76aSRasesh Mody DEV_TX_OFFLOAD_IPV4_CKSUM | 14152ea6f76aSRasesh Mody DEV_TX_OFFLOAD_UDP_CKSUM | 14163d4bb441SHarish Patil DEV_TX_OFFLOAD_TCP_CKSUM | 141729540be7SHarish Patil DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | 1418946dfd18SHarish Patil DEV_TX_OFFLOAD_MULTI_SEGS | 141929540be7SHarish Patil DEV_TX_OFFLOAD_TCP_TSO | 1420d378cefaSShahed Shaikh DEV_TX_OFFLOAD_VXLAN_TNL_TSO | 1421d378cefaSShahed Shaikh DEV_TX_OFFLOAD_GENEVE_TNL_TSO); 1422946dfd18SHarish Patil dev_info->tx_queue_offload_capa = dev_info->tx_offload_capa; 1423946dfd18SHarish Patil 1424946dfd18SHarish Patil dev_info->default_txconf = (struct rte_eth_txconf) { 142503803462SRasesh Mody .offloads = DEV_TX_OFFLOAD_MULTI_SEGS, 1426946dfd18SHarish Patil }; 1427946dfd18SHarish Patil 1428946dfd18SHarish Patil dev_info->default_rxconf = (struct rte_eth_rxconf) { 1429946dfd18SHarish Patil /* Packets are always dropped if no descriptors are available */ 1430946dfd18SHarish Patil .rx_drop_en = 1, 1431048a68edSShahed Shaikh .offloads = 0, 1432946dfd18SHarish Patil }; 14332ea6f76aSRasesh Mody 143464c239b7SHarish Patil memset(&link, 0, sizeof(struct qed_link_output)); 143564c239b7SHarish Patil qdev->ops->common->get_link(edev, &link); 14361ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) 14371ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_1G; 14381ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) 14391ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_10G; 14401ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) 14411ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_25G; 14421ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) 14431ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_40G; 14441ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) 14451ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_50G; 14461ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) 14471ea56b80SHarish Patil speed_cap |= ETH_LINK_SPEED_100G; 14481ea56b80SHarish Patil dev_info->speed_capa = speed_cap; 1449bdad90d1SIvan Ilchenko 1450bdad90d1SIvan Ilchenko return 0; 14512ea6f76aSRasesh Mody } 14522ea6f76aSRasesh Mody 14532ea6f76aSRasesh Mody /* return 0 means link status changed, -1 means not changed */ 14548aab5d6fSRasesh Mody int 14552ea6f76aSRasesh Mody qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete) 14562ea6f76aSRasesh Mody { 14572ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 14582ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 1459c6034a20SShahed Shaikh struct qed_link_output q_link; 1460c6034a20SShahed Shaikh struct rte_eth_link link; 14612ea6f76aSRasesh Mody uint16_t link_duplex; 14622ea6f76aSRasesh Mody 1463c6034a20SShahed Shaikh memset(&q_link, 0, sizeof(q_link)); 1464c6034a20SShahed Shaikh memset(&link, 0, sizeof(link)); 1465c6034a20SShahed Shaikh 1466c6034a20SShahed Shaikh qdev->ops->common->get_link(edev, &q_link); 14672ea6f76aSRasesh Mody 14682ea6f76aSRasesh Mody /* Link Speed */ 1469c6034a20SShahed Shaikh link.link_speed = q_link.speed; 14702ea6f76aSRasesh Mody 14712ea6f76aSRasesh Mody /* Link Mode */ 1472c6034a20SShahed Shaikh switch (q_link.duplex) { 14732ea6f76aSRasesh Mody case QEDE_DUPLEX_HALF: 14742ea6f76aSRasesh Mody link_duplex = ETH_LINK_HALF_DUPLEX; 14752ea6f76aSRasesh Mody break; 14762ea6f76aSRasesh Mody case QEDE_DUPLEX_FULL: 14772ea6f76aSRasesh Mody link_duplex = ETH_LINK_FULL_DUPLEX; 14782ea6f76aSRasesh Mody break; 14792ea6f76aSRasesh Mody case QEDE_DUPLEX_UNKNOWN: 14802ea6f76aSRasesh Mody default: 14812ea6f76aSRasesh Mody link_duplex = -1; 14822ea6f76aSRasesh Mody } 1483c6034a20SShahed Shaikh link.link_duplex = link_duplex; 14842ea6f76aSRasesh Mody 14852ea6f76aSRasesh Mody /* Link Status */ 1486c6034a20SShahed Shaikh link.link_status = q_link.link_up ? ETH_LINK_UP : ETH_LINK_DOWN; 14872ea6f76aSRasesh Mody 14882ea6f76aSRasesh Mody /* AN */ 1489c6034a20SShahed Shaikh link.link_autoneg = (q_link.supported_caps & QEDE_SUPPORTED_AUTONEG) ? 14902ea6f76aSRasesh Mody ETH_LINK_AUTONEG : ETH_LINK_FIXED; 14912ea6f76aSRasesh Mody 14922ea6f76aSRasesh Mody DP_INFO(edev, "Link - Speed %u Mode %u AN %u Status %u\n", 1493c6034a20SShahed Shaikh link.link_speed, link.link_duplex, 1494c6034a20SShahed Shaikh link.link_autoneg, link.link_status); 14952ea6f76aSRasesh Mody 1496c6034a20SShahed Shaikh return rte_eth_linkstatus_set(eth_dev, &link); 14972ea6f76aSRasesh Mody } 14982ea6f76aSRasesh Mody 14999039c812SAndrew Rybchenko static int qede_promiscuous_enable(struct rte_eth_dev *eth_dev) 15002ea6f76aSRasesh Mody { 15019039c812SAndrew Rybchenko enum _ecore_status_t ecore_status; 1502b10231aeSDevendra Singh Rawat struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1503b10231aeSDevendra Singh Rawat struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1504b10231aeSDevendra Singh Rawat enum qed_filter_rx_mode_type type = QED_FILTER_RX_MODE_TYPE_PROMISC; 15052ea6f76aSRasesh Mody 15062ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 15072ea6f76aSRasesh Mody 15089039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, type); 15099039c812SAndrew Rybchenko 15109039c812SAndrew Rybchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 15112ea6f76aSRasesh Mody } 15122ea6f76aSRasesh Mody 15139039c812SAndrew Rybchenko static int qede_promiscuous_disable(struct rte_eth_dev *eth_dev) 15142ea6f76aSRasesh Mody { 15152ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 15162ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 15179039c812SAndrew Rybchenko enum _ecore_status_t ecore_status; 15182ea6f76aSRasesh Mody 15192ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 15202ea6f76aSRasesh Mody 15212ea6f76aSRasesh Mody if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1) 15229039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 15232ea6f76aSRasesh Mody QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC); 15242ea6f76aSRasesh Mody else 15259039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 152677fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_REGULAR); 15279039c812SAndrew Rybchenko 15289039c812SAndrew Rybchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 15292ea6f76aSRasesh Mody } 15302ea6f76aSRasesh Mody 15312af14ca7SHarish Patil static void qede_poll_sp_sb_cb(void *param) 15322af14ca7SHarish Patil { 15332af14ca7SHarish Patil struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 15342af14ca7SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 15352af14ca7SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 15362af14ca7SHarish Patil int rc; 15372af14ca7SHarish Patil 15382af14ca7SHarish Patil qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 15392af14ca7SHarish Patil qede_interrupt_action(&edev->hwfns[1]); 15402af14ca7SHarish Patil 15410833120fSShahed Shaikh rc = rte_eal_alarm_set(QEDE_SP_TIMER_PERIOD, 15422af14ca7SHarish Patil qede_poll_sp_sb_cb, 15432af14ca7SHarish Patil (void *)eth_dev); 15442af14ca7SHarish Patil if (rc != 0) { 15452af14ca7SHarish Patil DP_ERR(edev, "Unable to start periodic" 15462af14ca7SHarish Patil " timer rc %d\n", rc); 15472af14ca7SHarish Patil } 15482af14ca7SHarish Patil } 15492af14ca7SHarish Patil 1550b142387bSThomas Monjalon static int qede_dev_close(struct rte_eth_dev *eth_dev) 15512ea6f76aSRasesh Mody { 1552c0802544SFerruh Yigit struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 1553dbac54c2SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1554dbac54c2SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 155562024eb8SIvan Ilchenko int ret = 0; 15562ea6f76aSRasesh Mody 15572ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 15582ea6f76aSRasesh Mody 15591df1bb52SRasesh Mody /* only close in case of the primary process */ 15601df1bb52SRasesh Mody if (rte_eal_process_type() != RTE_PROC_PRIMARY) 15611df1bb52SRasesh Mody return 0; 15621df1bb52SRasesh Mody 15632ea6f76aSRasesh Mody /* dev_stop() shall cleanup fp resources in hw but without releasing 15642ea6f76aSRasesh Mody * dma memories and sw structures so that dev_start() can be called 15652ea6f76aSRasesh Mody * by the app without reconfiguration. However, in dev_close() we 15662ea6f76aSRasesh Mody * can release all the resources and device can be brought up newly 15672ea6f76aSRasesh Mody */ 15684c4bdadfSHarish Patil if (eth_dev->data->dev_started) 156962024eb8SIvan Ilchenko ret = qede_dev_stop(eth_dev); 15702ea6f76aSRasesh Mody 1571bf44e27aSManish Chopra if (qdev->vport_started) 15729a6d30aeSHarish Patil qede_stop_vport(edev); 1573dd28bc8cSHarish Patil qdev->vport_started = false; 15744c4bdadfSHarish Patil qede_fdir_dealloc_resc(eth_dev); 1575dbac54c2SHarish Patil qede_dealloc_fp_resc(eth_dev); 15762ea6f76aSRasesh Mody 15774c4bdadfSHarish Patil eth_dev->data->nb_rx_queues = 0; 15784c4bdadfSHarish Patil eth_dev->data->nb_tx_queues = 0; 15794c4bdadfSHarish Patil 15802ea6f76aSRasesh Mody qdev->ops->common->slowpath_stop(edev); 15812ea6f76aSRasesh Mody qdev->ops->common->remove(edev); 1582d4b7f673SJan Blunck rte_intr_disable(&pci_dev->intr_handle); 15834eee1bbfSShahed Shaikh 15844eee1bbfSShahed Shaikh switch (pci_dev->intr_handle.type) { 15854eee1bbfSShahed Shaikh case RTE_INTR_HANDLE_UIO_INTX: 15864eee1bbfSShahed Shaikh case RTE_INTR_HANDLE_VFIO_LEGACY: 1587d4b7f673SJan Blunck rte_intr_callback_unregister(&pci_dev->intr_handle, 15884eee1bbfSShahed Shaikh qede_interrupt_handler_intx, 15894eee1bbfSShahed Shaikh (void *)eth_dev); 15904eee1bbfSShahed Shaikh break; 15914eee1bbfSShahed Shaikh default: 15924eee1bbfSShahed Shaikh rte_intr_callback_unregister(&pci_dev->intr_handle, 15934eee1bbfSShahed Shaikh qede_interrupt_handler, 15944eee1bbfSShahed Shaikh (void *)eth_dev); 15954eee1bbfSShahed Shaikh } 15964eee1bbfSShahed Shaikh 1597c0845c33SRasesh Mody if (ECORE_IS_CMT(edev)) 15982af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, (void *)eth_dev); 1599b142387bSThomas Monjalon 160062024eb8SIvan Ilchenko return ret; 16012ea6f76aSRasesh Mody } 16022ea6f76aSRasesh Mody 1603d5b0924bSMatan Azrad static int 16042ea6f76aSRasesh Mody qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats) 16052ea6f76aSRasesh Mody { 16062ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 16072ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 16082ea6f76aSRasesh Mody struct ecore_eth_stats stats; 16090aa3e7b9SShahed Shaikh unsigned int i = 0, j = 0, qid, idx, hw_fn; 161006e83c4eSRasesh Mody unsigned int rxq_stat_cntrs, txq_stat_cntrs; 16117634c5f9SRasesh Mody struct qede_tx_queue *txq; 16122ea6f76aSRasesh Mody 16134c4bdadfSHarish Patil ecore_get_vport_stats(edev, &stats); 16142ea6f76aSRasesh Mody 16152ea6f76aSRasesh Mody /* RX Stats */ 16169c1aa3e1SRasesh Mody eth_stats->ipackets = stats.common.rx_ucast_pkts + 16179c1aa3e1SRasesh Mody stats.common.rx_mcast_pkts + stats.common.rx_bcast_pkts; 16182ea6f76aSRasesh Mody 16199c1aa3e1SRasesh Mody eth_stats->ibytes = stats.common.rx_ucast_bytes + 16209c1aa3e1SRasesh Mody stats.common.rx_mcast_bytes + stats.common.rx_bcast_bytes; 16212ea6f76aSRasesh Mody 16229c1aa3e1SRasesh Mody eth_stats->ierrors = stats.common.rx_crc_errors + 16239c1aa3e1SRasesh Mody stats.common.rx_align_errors + 16249c1aa3e1SRasesh Mody stats.common.rx_carrier_errors + 16259c1aa3e1SRasesh Mody stats.common.rx_oversize_packets + 16269c1aa3e1SRasesh Mody stats.common.rx_jabbers + stats.common.rx_undersize_packets; 16272ea6f76aSRasesh Mody 16289c1aa3e1SRasesh Mody eth_stats->rx_nombuf = stats.common.no_buff_discards; 16292ea6f76aSRasesh Mody 16309c1aa3e1SRasesh Mody eth_stats->imissed = stats.common.mftag_filter_discards + 16319c1aa3e1SRasesh Mody stats.common.mac_filter_discards + 16329c1aa3e1SRasesh Mody stats.common.no_buff_discards + 16339c1aa3e1SRasesh Mody stats.common.brb_truncates + stats.common.brb_discards; 16342ea6f76aSRasesh Mody 16352ea6f76aSRasesh Mody /* TX stats */ 16369c1aa3e1SRasesh Mody eth_stats->opackets = stats.common.tx_ucast_pkts + 16379c1aa3e1SRasesh Mody stats.common.tx_mcast_pkts + stats.common.tx_bcast_pkts; 16382ea6f76aSRasesh Mody 16399c1aa3e1SRasesh Mody eth_stats->obytes = stats.common.tx_ucast_bytes + 16409c1aa3e1SRasesh Mody stats.common.tx_mcast_bytes + stats.common.tx_bcast_bytes; 16412ea6f76aSRasesh Mody 16429c1aa3e1SRasesh Mody eth_stats->oerrors = stats.common.tx_err_drop_pkts; 16437634c5f9SRasesh Mody 16447634c5f9SRasesh Mody /* Queue stats */ 16458de0c420SShahed Shaikh rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(eth_dev), 164606e83c4eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 16478de0c420SShahed Shaikh txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(eth_dev), 164806e83c4eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 16498de0c420SShahed Shaikh if (rxq_stat_cntrs != (unsigned int)QEDE_RSS_COUNT(eth_dev) || 16508de0c420SShahed Shaikh txq_stat_cntrs != (unsigned int)QEDE_TSS_COUNT(eth_dev)) 165106e83c4eSRasesh Mody DP_VERBOSE(edev, ECORE_MSG_DEBUG, 165206e83c4eSRasesh Mody "Not all the queue stats will be displayed. Set" 165306e83c4eSRasesh Mody " RTE_ETHDEV_QUEUE_STAT_CNTRS config param" 165406e83c4eSRasesh Mody " appropriately and retry.\n"); 165506e83c4eSRasesh Mody 16568de0c420SShahed Shaikh for (qid = 0; qid < eth_dev->data->nb_rx_queues; qid++) { 16570aa3e7b9SShahed Shaikh eth_stats->q_ipackets[i] = 0; 16580aa3e7b9SShahed Shaikh eth_stats->q_errors[i] = 0; 16590aa3e7b9SShahed Shaikh 16600aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 16610aa3e7b9SShahed Shaikh idx = qid * edev->num_hwfns + hw_fn; 16620aa3e7b9SShahed Shaikh 16630aa3e7b9SShahed Shaikh eth_stats->q_ipackets[i] += 16640aa3e7b9SShahed Shaikh *(uint64_t *) 16650aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16667634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16677634c5f9SRasesh Mody rcv_pkts)); 16680aa3e7b9SShahed Shaikh eth_stats->q_errors[i] += 16690aa3e7b9SShahed Shaikh *(uint64_t *) 16700aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16717634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16727634c5f9SRasesh Mody rx_hw_errors)) + 16730aa3e7b9SShahed Shaikh *(uint64_t *) 16740aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16757634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16767634c5f9SRasesh Mody rx_alloc_errors)); 16770aa3e7b9SShahed Shaikh } 16780aa3e7b9SShahed Shaikh 16797634c5f9SRasesh Mody i++; 168006e83c4eSRasesh Mody if (i == rxq_stat_cntrs) 168106e83c4eSRasesh Mody break; 168206e83c4eSRasesh Mody } 16837634c5f9SRasesh Mody 16848de0c420SShahed Shaikh for (qid = 0; qid < eth_dev->data->nb_tx_queues; qid++) { 16850aa3e7b9SShahed Shaikh eth_stats->q_opackets[j] = 0; 16860aa3e7b9SShahed Shaikh 16870aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 16880aa3e7b9SShahed Shaikh idx = qid * edev->num_hwfns + hw_fn; 16890aa3e7b9SShahed Shaikh 16900aa3e7b9SShahed Shaikh txq = qdev->fp_array[idx].txq; 16910aa3e7b9SShahed Shaikh eth_stats->q_opackets[j] += 16927634c5f9SRasesh Mody *((uint64_t *)(uintptr_t) 16937634c5f9SRasesh Mody (((uint64_t)(uintptr_t)(txq)) + 16947634c5f9SRasesh Mody offsetof(struct qede_tx_queue, 16957634c5f9SRasesh Mody xmit_pkts))); 16960aa3e7b9SShahed Shaikh } 16970aa3e7b9SShahed Shaikh 16987634c5f9SRasesh Mody j++; 169906e83c4eSRasesh Mody if (j == txq_stat_cntrs) 170006e83c4eSRasesh Mody break; 17017634c5f9SRasesh Mody } 1702d5b0924bSMatan Azrad 1703d5b0924bSMatan Azrad return 0; 17047634c5f9SRasesh Mody } 17057634c5f9SRasesh Mody 17067634c5f9SRasesh Mody static unsigned 17077634c5f9SRasesh Mody qede_get_xstats_count(struct qede_dev *qdev) { 17088de0c420SShahed Shaikh struct rte_eth_dev *dev = (struct rte_eth_dev *)qdev->ethdev; 17098de0c420SShahed Shaikh 17109c1aa3e1SRasesh Mody if (ECORE_IS_BB(&qdev->edev)) 17117634c5f9SRasesh Mody return RTE_DIM(qede_xstats_strings) + 17129c1aa3e1SRasesh Mody RTE_DIM(qede_bb_xstats_strings) + 17139c1aa3e1SRasesh Mody (RTE_DIM(qede_rxq_xstats_strings) * 17148de0c420SShahed Shaikh QEDE_RSS_COUNT(dev) * qdev->edev.num_hwfns); 17159c1aa3e1SRasesh Mody else 17169c1aa3e1SRasesh Mody return RTE_DIM(qede_xstats_strings) + 17179c1aa3e1SRasesh Mody RTE_DIM(qede_ah_xstats_strings) + 171806e83c4eSRasesh Mody (RTE_DIM(qede_rxq_xstats_strings) * 17198de0c420SShahed Shaikh QEDE_RSS_COUNT(dev)); 1720d1216e22SRasesh Mody } 17212ea6f76aSRasesh Mody 1722d1216e22SRasesh Mody static int 1723dd2c630aSFerruh Yigit qede_get_xstats_names(struct rte_eth_dev *dev, 1724af785e47SRasesh Mody struct rte_eth_xstat_name *xstats_names, 1725af785e47SRasesh Mody __rte_unused unsigned int limit) 1726d1216e22SRasesh Mody { 17277634c5f9SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 17289c1aa3e1SRasesh Mody struct ecore_dev *edev = &qdev->edev; 17297634c5f9SRasesh Mody const unsigned int stat_cnt = qede_get_xstats_count(qdev); 17300aa3e7b9SShahed Shaikh unsigned int i, qid, hw_fn, stat_idx = 0; 1731d1216e22SRasesh Mody 17320aa3e7b9SShahed Shaikh if (xstats_names == NULL) 17330aa3e7b9SShahed Shaikh return stat_cnt; 17340aa3e7b9SShahed Shaikh 17357634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) { 17366723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 17376723c0fcSBruce Richardson qede_xstats_strings[i].name, 17386723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 17397634c5f9SRasesh Mody stat_idx++; 17407634c5f9SRasesh Mody } 17417634c5f9SRasesh Mody 17429c1aa3e1SRasesh Mody if (ECORE_IS_BB(edev)) { 17439c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_bb_xstats_strings); i++) { 17446723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 17456723c0fcSBruce Richardson qede_bb_xstats_strings[i].name, 17466723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 17479c1aa3e1SRasesh Mody stat_idx++; 17489c1aa3e1SRasesh Mody } 17499c1aa3e1SRasesh Mody } else { 17509c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_ah_xstats_strings); i++) { 17516723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 17526723c0fcSBruce Richardson qede_ah_xstats_strings[i].name, 17536723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 17549c1aa3e1SRasesh Mody stat_idx++; 17559c1aa3e1SRasesh Mody } 17569c1aa3e1SRasesh Mody } 17579c1aa3e1SRasesh Mody 17580aa3e7b9SShahed Shaikh for (qid = 0; qid < QEDE_RSS_COUNT(dev); qid++) { 17590aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 17607634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) { 17617634c5f9SRasesh Mody snprintf(xstats_names[stat_idx].name, 17620aa3e7b9SShahed Shaikh RTE_ETH_XSTATS_NAME_SIZE, 17630aa3e7b9SShahed Shaikh "%.4s%d.%d%s", 17640aa3e7b9SShahed Shaikh qede_rxq_xstats_strings[i].name, 17650aa3e7b9SShahed Shaikh hw_fn, qid, 17667634c5f9SRasesh Mody qede_rxq_xstats_strings[i].name + 4); 17677634c5f9SRasesh Mody stat_idx++; 17687634c5f9SRasesh Mody } 17697634c5f9SRasesh Mody } 17707634c5f9SRasesh Mody } 1771d1216e22SRasesh Mody 1772d1216e22SRasesh Mody return stat_cnt; 1773d1216e22SRasesh Mody } 1774d1216e22SRasesh Mody 1775d1216e22SRasesh Mody static int 1776d1216e22SRasesh Mody qede_get_xstats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, 1777d1216e22SRasesh Mody unsigned int n) 1778d1216e22SRasesh Mody { 1779d1216e22SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 1780d1216e22SRasesh Mody struct ecore_dev *edev = &qdev->edev; 1781d1216e22SRasesh Mody struct ecore_eth_stats stats; 17827634c5f9SRasesh Mody const unsigned int num = qede_get_xstats_count(qdev); 17830aa3e7b9SShahed Shaikh unsigned int i, qid, hw_fn, fpidx, stat_idx = 0; 1784d1216e22SRasesh Mody 1785d1216e22SRasesh Mody if (n < num) 1786d1216e22SRasesh Mody return num; 1787d1216e22SRasesh Mody 17884c4bdadfSHarish Patil ecore_get_vport_stats(edev, &stats); 1789d1216e22SRasesh Mody 17907634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) { 17917634c5f9SRasesh Mody xstats[stat_idx].value = *(uint64_t *)(((char *)&stats) + 17927634c5f9SRasesh Mody qede_xstats_strings[i].offset); 1793513c78aeSOlivier Matz xstats[stat_idx].id = stat_idx; 17947634c5f9SRasesh Mody stat_idx++; 17957634c5f9SRasesh Mody } 1796d1216e22SRasesh Mody 17979c1aa3e1SRasesh Mody if (ECORE_IS_BB(edev)) { 17989c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_bb_xstats_strings); i++) { 17999c1aa3e1SRasesh Mody xstats[stat_idx].value = 18009c1aa3e1SRasesh Mody *(uint64_t *)(((char *)&stats) + 18019c1aa3e1SRasesh Mody qede_bb_xstats_strings[i].offset); 18029c1aa3e1SRasesh Mody xstats[stat_idx].id = stat_idx; 18039c1aa3e1SRasesh Mody stat_idx++; 18049c1aa3e1SRasesh Mody } 18059c1aa3e1SRasesh Mody } else { 18069c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_ah_xstats_strings); i++) { 18079c1aa3e1SRasesh Mody xstats[stat_idx].value = 18089c1aa3e1SRasesh Mody *(uint64_t *)(((char *)&stats) + 18099c1aa3e1SRasesh Mody qede_ah_xstats_strings[i].offset); 18109c1aa3e1SRasesh Mody xstats[stat_idx].id = stat_idx; 18119c1aa3e1SRasesh Mody stat_idx++; 18129c1aa3e1SRasesh Mody } 18139c1aa3e1SRasesh Mody } 18149c1aa3e1SRasesh Mody 18150aa3e7b9SShahed Shaikh for (qid = 0; qid < dev->data->nb_rx_queues; qid++) { 18160aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 18177634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) { 18180aa3e7b9SShahed Shaikh fpidx = qid * edev->num_hwfns + hw_fn; 18198de0c420SShahed Shaikh xstats[stat_idx].value = *(uint64_t *) 18200aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[fpidx].rxq)) + 18217634c5f9SRasesh Mody qede_rxq_xstats_strings[i].offset); 1822513c78aeSOlivier Matz xstats[stat_idx].id = stat_idx; 18237634c5f9SRasesh Mody stat_idx++; 18247634c5f9SRasesh Mody } 18250aa3e7b9SShahed Shaikh 18260aa3e7b9SShahed Shaikh } 18277634c5f9SRasesh Mody } 18287634c5f9SRasesh Mody 18297634c5f9SRasesh Mody return stat_idx; 1830d1216e22SRasesh Mody } 1831d1216e22SRasesh Mody 18329970a9adSIgor Romanov static int 1833d1216e22SRasesh Mody qede_reset_xstats(struct rte_eth_dev *dev) 1834d1216e22SRasesh Mody { 1835d1216e22SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 1836d1216e22SRasesh Mody struct ecore_dev *edev = &qdev->edev; 1837d1216e22SRasesh Mody 1838d1216e22SRasesh Mody ecore_reset_vport_stats(edev); 1839ce26be6eSRasesh Mody qede_reset_queue_stats(qdev, true); 18409970a9adSIgor Romanov 18419970a9adSIgor Romanov return 0; 18422ea6f76aSRasesh Mody } 18432ea6f76aSRasesh Mody 18442ea6f76aSRasesh Mody int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up) 18452ea6f76aSRasesh Mody { 18462ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 18472ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 18482ea6f76aSRasesh Mody struct qed_link_params link_params; 18492ea6f76aSRasesh Mody int rc; 18502ea6f76aSRasesh Mody 18512ea6f76aSRasesh Mody DP_INFO(edev, "setting link state %d\n", link_up); 18522ea6f76aSRasesh Mody memset(&link_params, 0, sizeof(link_params)); 18532ea6f76aSRasesh Mody link_params.link_up = link_up; 18542ea6f76aSRasesh Mody rc = qdev->ops->common->set_link(edev, &link_params); 18552ea6f76aSRasesh Mody if (rc != ECORE_SUCCESS) 18562ea6f76aSRasesh Mody DP_ERR(edev, "Unable to set link state %d\n", link_up); 18572ea6f76aSRasesh Mody 18582ea6f76aSRasesh Mody return rc; 18592ea6f76aSRasesh Mody } 18602ea6f76aSRasesh Mody 18612ea6f76aSRasesh Mody static int qede_dev_set_link_up(struct rte_eth_dev *eth_dev) 18622ea6f76aSRasesh Mody { 18632ea6f76aSRasesh Mody return qede_dev_set_link_state(eth_dev, true); 18642ea6f76aSRasesh Mody } 18652ea6f76aSRasesh Mody 18662ea6f76aSRasesh Mody static int qede_dev_set_link_down(struct rte_eth_dev *eth_dev) 18672ea6f76aSRasesh Mody { 18682ea6f76aSRasesh Mody return qede_dev_set_link_state(eth_dev, false); 18692ea6f76aSRasesh Mody } 18702ea6f76aSRasesh Mody 18719970a9adSIgor Romanov static int qede_reset_stats(struct rte_eth_dev *eth_dev) 18725cdd769aSRasesh Mody { 18735cdd769aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 18745cdd769aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 18755cdd769aSRasesh Mody 18765cdd769aSRasesh Mody ecore_reset_vport_stats(edev); 1877ce26be6eSRasesh Mody qede_reset_queue_stats(qdev, false); 18789970a9adSIgor Romanov 18799970a9adSIgor Romanov return 0; 18805cdd769aSRasesh Mody } 18815cdd769aSRasesh Mody 1882ca041cd4SIvan Ilchenko static int qede_allmulticast_enable(struct rte_eth_dev *eth_dev) 18832ea6f76aSRasesh Mody { 18842ea6f76aSRasesh Mody enum qed_filter_rx_mode_type type = 18852ea6f76aSRasesh Mody QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC; 1886ca041cd4SIvan Ilchenko enum _ecore_status_t ecore_status; 18872ea6f76aSRasesh Mody 1888a91fb48aSBalazs Nemeth if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1) 1889a91fb48aSBalazs Nemeth type = QED_FILTER_RX_MODE_TYPE_PROMISC; 1890ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, type); 1891ca041cd4SIvan Ilchenko 1892ca041cd4SIvan Ilchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 18932ea6f76aSRasesh Mody } 18942ea6f76aSRasesh Mody 1895ca041cd4SIvan Ilchenko static int qede_allmulticast_disable(struct rte_eth_dev *eth_dev) 18962ea6f76aSRasesh Mody { 1897ca041cd4SIvan Ilchenko enum _ecore_status_t ecore_status; 1898ca041cd4SIvan Ilchenko 18992ea6f76aSRasesh Mody if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1) 1900ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 190177fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_PROMISC); 19022ea6f76aSRasesh Mody else 1903ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 190477fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_REGULAR); 1905ca041cd4SIvan Ilchenko 1906ca041cd4SIvan Ilchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 19072ea6f76aSRasesh Mody } 19082ea6f76aSRasesh Mody 1909413ecf29SHarish Patil static int 19106d13ea8eSOlivier Matz qede_set_mc_addr_list(struct rte_eth_dev *eth_dev, 19116d13ea8eSOlivier Matz struct rte_ether_addr *mc_addrs, 1912413ecf29SHarish Patil uint32_t mc_addrs_num) 1913413ecf29SHarish Patil { 1914413ecf29SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1915413ecf29SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1916413ecf29SHarish Patil uint8_t i; 1917413ecf29SHarish Patil 1918413ecf29SHarish Patil if (mc_addrs_num > ECORE_MAX_MC_ADDRS) { 1919413ecf29SHarish Patil DP_ERR(edev, "Reached max multicast filters limit," 1920413ecf29SHarish Patil "Please enable multicast promisc mode\n"); 1921413ecf29SHarish Patil return -ENOSPC; 1922413ecf29SHarish Patil } 1923413ecf29SHarish Patil 1924413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) { 1925538da7a1SOlivier Matz if (!rte_is_multicast_ether_addr(&mc_addrs[i])) { 1926413ecf29SHarish Patil DP_ERR(edev, "Not a valid multicast MAC\n"); 1927413ecf29SHarish Patil return -EINVAL; 1928413ecf29SHarish Patil } 1929413ecf29SHarish Patil } 1930413ecf29SHarish Patil 1931413ecf29SHarish Patil /* Flush all existing entries */ 1932413ecf29SHarish Patil if (qede_del_mcast_filters(eth_dev)) 1933413ecf29SHarish Patil return -1; 1934413ecf29SHarish Patil 1935413ecf29SHarish Patil /* Set new mcast list */ 1936413ecf29SHarish Patil return qede_add_mcast_filters(eth_dev, mc_addrs, mc_addrs_num); 1937413ecf29SHarish Patil } 1938413ecf29SHarish Patil 1939d121a6b5SRasesh Mody /* Update MTU via vport-update without doing port restart. 1940d121a6b5SRasesh Mody * The vport must be deactivated before calling this API. 1941d121a6b5SRasesh Mody */ 1942d121a6b5SRasesh Mody int qede_update_mtu(struct rte_eth_dev *eth_dev, uint16_t mtu) 1943d121a6b5SRasesh Mody { 1944d121a6b5SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1945d121a6b5SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1946d121a6b5SRasesh Mody struct ecore_hwfn *p_hwfn; 1947d121a6b5SRasesh Mody int rc; 1948d121a6b5SRasesh Mody int i; 1949d121a6b5SRasesh Mody 1950d121a6b5SRasesh Mody if (IS_PF(edev)) { 1951d121a6b5SRasesh Mody struct ecore_sp_vport_update_params params; 1952d121a6b5SRasesh Mody 1953d121a6b5SRasesh Mody memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 1954d121a6b5SRasesh Mody params.vport_id = 0; 1955d121a6b5SRasesh Mody params.mtu = mtu; 1956d121a6b5SRasesh Mody params.vport_id = 0; 1957d121a6b5SRasesh Mody for_each_hwfn(edev, i) { 1958d121a6b5SRasesh Mody p_hwfn = &edev->hwfns[i]; 1959d121a6b5SRasesh Mody params.opaque_fid = p_hwfn->hw_info.opaque_fid; 1960d121a6b5SRasesh Mody rc = ecore_sp_vport_update(p_hwfn, ¶ms, 1961d121a6b5SRasesh Mody ECORE_SPQ_MODE_EBLOCK, NULL); 1962d121a6b5SRasesh Mody if (rc != ECORE_SUCCESS) 1963d121a6b5SRasesh Mody goto err; 1964d121a6b5SRasesh Mody } 1965d121a6b5SRasesh Mody } else { 1966d121a6b5SRasesh Mody for_each_hwfn(edev, i) { 1967d121a6b5SRasesh Mody p_hwfn = &edev->hwfns[i]; 1968d121a6b5SRasesh Mody rc = ecore_vf_pf_update_mtu(p_hwfn, mtu); 1969d121a6b5SRasesh Mody if (rc == ECORE_INVAL) { 1970d121a6b5SRasesh Mody DP_INFO(edev, "VF MTU Update TLV not supported\n"); 1971d121a6b5SRasesh Mody /* Recreate vport */ 1972d121a6b5SRasesh Mody rc = qede_start_vport(qdev, mtu); 1973d121a6b5SRasesh Mody if (rc != ECORE_SUCCESS) 1974d121a6b5SRasesh Mody goto err; 1975d121a6b5SRasesh Mody 1976d121a6b5SRasesh Mody /* Restore config lost due to vport stop */ 1977d121a6b5SRasesh Mody if (eth_dev->data->promiscuous) 1978d121a6b5SRasesh Mody qede_promiscuous_enable(eth_dev); 1979d121a6b5SRasesh Mody else 1980d121a6b5SRasesh Mody qede_promiscuous_disable(eth_dev); 1981d121a6b5SRasesh Mody 1982d121a6b5SRasesh Mody if (eth_dev->data->all_multicast) 1983d121a6b5SRasesh Mody qede_allmulticast_enable(eth_dev); 1984d121a6b5SRasesh Mody else 1985d121a6b5SRasesh Mody qede_allmulticast_disable(eth_dev); 1986d121a6b5SRasesh Mody 1987d121a6b5SRasesh Mody qede_vlan_offload_set(eth_dev, 1988d121a6b5SRasesh Mody qdev->vlan_offload_mask); 1989d121a6b5SRasesh Mody } else if (rc != ECORE_SUCCESS) { 1990d121a6b5SRasesh Mody goto err; 1991d121a6b5SRasesh Mody } 1992d121a6b5SRasesh Mody } 1993d121a6b5SRasesh Mody } 1994d121a6b5SRasesh Mody DP_INFO(edev, "%s MTU updated to %u\n", IS_PF(edev) ? "PF" : "VF", mtu); 1995d121a6b5SRasesh Mody 1996d121a6b5SRasesh Mody return 0; 1997d121a6b5SRasesh Mody 1998d121a6b5SRasesh Mody err: 1999d121a6b5SRasesh Mody DP_ERR(edev, "Failed to update MTU\n"); 2000d121a6b5SRasesh Mody return -1; 2001d121a6b5SRasesh Mody } 2002d121a6b5SRasesh Mody 20032ea6f76aSRasesh Mody static int qede_flow_ctrl_set(struct rte_eth_dev *eth_dev, 20042ea6f76aSRasesh Mody struct rte_eth_fc_conf *fc_conf) 20052ea6f76aSRasesh Mody { 20062ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 20072ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 20082ea6f76aSRasesh Mody struct qed_link_output current_link; 20092ea6f76aSRasesh Mody struct qed_link_params params; 20102ea6f76aSRasesh Mody 20112ea6f76aSRasesh Mody memset(¤t_link, 0, sizeof(current_link)); 20122ea6f76aSRasesh Mody qdev->ops->common->get_link(edev, ¤t_link); 20132ea6f76aSRasesh Mody 20142ea6f76aSRasesh Mody memset(¶ms, 0, sizeof(params)); 20152ea6f76aSRasesh Mody params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG; 20162ea6f76aSRasesh Mody if (fc_conf->autoneg) { 20172ea6f76aSRasesh Mody if (!(current_link.supported_caps & QEDE_SUPPORTED_AUTONEG)) { 20182ea6f76aSRasesh Mody DP_ERR(edev, "Autoneg not supported\n"); 20192ea6f76aSRasesh Mody return -EINVAL; 20202ea6f76aSRasesh Mody } 20212ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE; 20222ea6f76aSRasesh Mody } 20232ea6f76aSRasesh Mody 20242ea6f76aSRasesh Mody /* Pause is assumed to be supported (SUPPORTED_Pause) */ 20252ea6f76aSRasesh Mody if (fc_conf->mode == RTE_FC_FULL) 20262ea6f76aSRasesh Mody params.pause_config |= (QED_LINK_PAUSE_TX_ENABLE | 20272ea6f76aSRasesh Mody QED_LINK_PAUSE_RX_ENABLE); 20282ea6f76aSRasesh Mody if (fc_conf->mode == RTE_FC_TX_PAUSE) 20292ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_TX_ENABLE; 20302ea6f76aSRasesh Mody if (fc_conf->mode == RTE_FC_RX_PAUSE) 20312ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_RX_ENABLE; 20322ea6f76aSRasesh Mody 20332ea6f76aSRasesh Mody params.link_up = true; 20342ea6f76aSRasesh Mody (void)qdev->ops->common->set_link(edev, ¶ms); 20352ea6f76aSRasesh Mody 20362ea6f76aSRasesh Mody return 0; 20372ea6f76aSRasesh Mody } 20382ea6f76aSRasesh Mody 20392ea6f76aSRasesh Mody static int qede_flow_ctrl_get(struct rte_eth_dev *eth_dev, 20402ea6f76aSRasesh Mody struct rte_eth_fc_conf *fc_conf) 20412ea6f76aSRasesh Mody { 20422ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 20432ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 20442ea6f76aSRasesh Mody struct qed_link_output current_link; 20452ea6f76aSRasesh Mody 20462ea6f76aSRasesh Mody memset(¤t_link, 0, sizeof(current_link)); 20472ea6f76aSRasesh Mody qdev->ops->common->get_link(edev, ¤t_link); 20482ea6f76aSRasesh Mody 20492ea6f76aSRasesh Mody if (current_link.pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE) 20502ea6f76aSRasesh Mody fc_conf->autoneg = true; 20512ea6f76aSRasesh Mody 20522ea6f76aSRasesh Mody if (current_link.pause_config & (QED_LINK_PAUSE_RX_ENABLE | 20532ea6f76aSRasesh Mody QED_LINK_PAUSE_TX_ENABLE)) 20542ea6f76aSRasesh Mody fc_conf->mode = RTE_FC_FULL; 20552ea6f76aSRasesh Mody else if (current_link.pause_config & QED_LINK_PAUSE_RX_ENABLE) 20562ea6f76aSRasesh Mody fc_conf->mode = RTE_FC_RX_PAUSE; 20572ea6f76aSRasesh Mody else if (current_link.pause_config & QED_LINK_PAUSE_TX_ENABLE) 20582ea6f76aSRasesh Mody fc_conf->mode = RTE_FC_TX_PAUSE; 20592ea6f76aSRasesh Mody else 20602ea6f76aSRasesh Mody fc_conf->mode = RTE_FC_NONE; 20612ea6f76aSRasesh Mody 20622ea6f76aSRasesh Mody return 0; 20632ea6f76aSRasesh Mody } 20642ea6f76aSRasesh Mody 20652ea6f76aSRasesh Mody static const uint32_t * 20662ea6f76aSRasesh Mody qede_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev) 20672ea6f76aSRasesh Mody { 20682ea6f76aSRasesh Mody static const uint32_t ptypes[] = { 2069fb88acb5SHarish Patil RTE_PTYPE_L2_ETHER, 2070fb88acb5SHarish Patil RTE_PTYPE_L2_ETHER_VLAN, 20712ea6f76aSRasesh Mody RTE_PTYPE_L3_IPV4, 20722ea6f76aSRasesh Mody RTE_PTYPE_L3_IPV6, 2073fb88acb5SHarish Patil RTE_PTYPE_L4_TCP, 2074fb88acb5SHarish Patil RTE_PTYPE_L4_UDP, 2075fb88acb5SHarish Patil RTE_PTYPE_TUNNEL_VXLAN, 2076fb88acb5SHarish Patil RTE_PTYPE_L4_FRAG, 2077d378cefaSShahed Shaikh RTE_PTYPE_TUNNEL_GENEVE, 2078e1e38962SHarish Patil RTE_PTYPE_TUNNEL_GRE, 2079fb88acb5SHarish Patil /* Inner */ 2080fb88acb5SHarish Patil RTE_PTYPE_INNER_L2_ETHER, 2081fb88acb5SHarish Patil RTE_PTYPE_INNER_L2_ETHER_VLAN, 2082fb88acb5SHarish Patil RTE_PTYPE_INNER_L3_IPV4, 2083fb88acb5SHarish Patil RTE_PTYPE_INNER_L3_IPV6, 2084fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_TCP, 2085fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_UDP, 2086fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_FRAG, 20872ea6f76aSRasesh Mody RTE_PTYPE_UNKNOWN 20882ea6f76aSRasesh Mody }; 20892ea6f76aSRasesh Mody 20908de0c420SShahed Shaikh if (eth_dev->rx_pkt_burst == qede_recv_pkts || 209181f88049SShahed Shaikh eth_dev->rx_pkt_burst == qede_recv_pkts_regular || 20928de0c420SShahed Shaikh eth_dev->rx_pkt_burst == qede_recv_pkts_cmt) 20932ea6f76aSRasesh Mody return ptypes; 20942ea6f76aSRasesh Mody 20952ea6f76aSRasesh Mody return NULL; 20962ea6f76aSRasesh Mody } 20972ea6f76aSRasesh Mody 20987ab35bf6SHarish Patil static void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf) 20999c5d0a66SHarish Patil { 21009c5d0a66SHarish Patil *rss_caps = 0; 21019c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_IPV4) ? ECORE_RSS_IPV4 : 0; 21029c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_IPV6) ? ECORE_RSS_IPV6 : 0; 21039c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_IPV6_EX) ? ECORE_RSS_IPV6 : 0; 21049c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP) ? ECORE_RSS_IPV4_TCP : 0; 21059c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP) ? ECORE_RSS_IPV6_TCP : 0; 21069c5d0a66SHarish Patil *rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX) ? ECORE_RSS_IPV6_TCP : 0; 210782bd0987SHarish Patil *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_UDP) ? ECORE_RSS_IPV4_UDP : 0; 210882bd0987SHarish Patil *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_UDP) ? ECORE_RSS_IPV6_UDP : 0; 21099c5d0a66SHarish Patil } 21109c5d0a66SHarish Patil 2111af785e47SRasesh Mody int qede_rss_hash_update(struct rte_eth_dev *eth_dev, 21124c98f276SSony Chacko struct rte_eth_rss_conf *rss_conf) 21134c98f276SSony Chacko { 21147ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 21157ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 21167ab35bf6SHarish Patil struct ecore_sp_vport_update_params vport_update_params; 21177ab35bf6SHarish Patil struct ecore_rss_params rss_params; 21187ab35bf6SHarish Patil struct ecore_hwfn *p_hwfn; 21194c98f276SSony Chacko uint32_t *key = (uint32_t *)rss_conf->rss_key; 21204c98f276SSony Chacko uint64_t hf = rss_conf->rss_hf; 21217ab35bf6SHarish Patil uint8_t len = rss_conf->rss_key_len; 2122235cbe4cSShahed Shaikh uint8_t idx, i, j, fpidx; 21237ab35bf6SHarish Patil int rc; 21244c98f276SSony Chacko 21254c98f276SSony Chacko memset(&vport_update_params, 0, sizeof(vport_update_params)); 21267ab35bf6SHarish Patil memset(&rss_params, 0, sizeof(rss_params)); 21277ab35bf6SHarish Patil 21287ab35bf6SHarish Patil DP_INFO(edev, "RSS hf = 0x%lx len = %u key = %p\n", 21297ab35bf6SHarish Patil (unsigned long)hf, len, key); 21304c98f276SSony Chacko 21319c5d0a66SHarish Patil if (hf != 0) { 21327ab35bf6SHarish Patil /* Enabling RSS */ 21337ab35bf6SHarish Patil DP_INFO(edev, "Enabling rss\n"); 21349c5d0a66SHarish Patil 21357ab35bf6SHarish Patil /* RSS caps */ 21367ab35bf6SHarish Patil qede_init_rss_caps(&rss_params.rss_caps, hf); 21377ab35bf6SHarish Patil rss_params.update_rss_capabilities = 1; 21387ab35bf6SHarish Patil 21397ab35bf6SHarish Patil /* RSS hash key */ 21407ab35bf6SHarish Patil if (key) { 21417ab35bf6SHarish Patil if (len > (ECORE_RSS_KEY_SIZE * sizeof(uint32_t))) { 2142*6ceb7ab8SIgor Russkikh len = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); 2143*6ceb7ab8SIgor Russkikh DP_NOTICE(edev, false, 2144*6ceb7ab8SIgor Russkikh "RSS key length too big, trimmed to %d\n", 2145*6ceb7ab8SIgor Russkikh len); 21467ab35bf6SHarish Patil } 21477ab35bf6SHarish Patil DP_INFO(edev, "Applying user supplied hash key\n"); 21487ab35bf6SHarish Patil rss_params.update_rss_key = 1; 21497ab35bf6SHarish Patil memcpy(&rss_params.rss_key, key, len); 21507ab35bf6SHarish Patil } 21517ab35bf6SHarish Patil rss_params.rss_enable = 1; 21524c98f276SSony Chacko } 21534c98f276SSony Chacko 21547ab35bf6SHarish Patil rss_params.update_rss_config = 1; 21557ab35bf6SHarish Patil /* tbl_size has to be set with capabilities */ 21567ab35bf6SHarish Patil rss_params.rss_table_size_log = 7; 21577ab35bf6SHarish Patil vport_update_params.vport_id = 0; 21587ab35bf6SHarish Patil 21597ab35bf6SHarish Patil for_each_hwfn(edev, i) { 2160235cbe4cSShahed Shaikh /* pass the L2 handles instead of qids */ 2161235cbe4cSShahed Shaikh for (j = 0 ; j < ECORE_RSS_IND_TABLE_SIZE ; j++) { 2162235cbe4cSShahed Shaikh idx = j % QEDE_RSS_COUNT(eth_dev); 2163235cbe4cSShahed Shaikh fpidx = idx * edev->num_hwfns + i; 2164235cbe4cSShahed Shaikh rss_params.rss_ind_table[j] = 2165235cbe4cSShahed Shaikh qdev->fp_array[fpidx].rxq->handle; 2166235cbe4cSShahed Shaikh } 2167235cbe4cSShahed Shaikh 2168235cbe4cSShahed Shaikh vport_update_params.rss_params = &rss_params; 2169235cbe4cSShahed Shaikh 21707ab35bf6SHarish Patil p_hwfn = &edev->hwfns[i]; 21717ab35bf6SHarish Patil vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid; 21727ab35bf6SHarish Patil rc = ecore_sp_vport_update(p_hwfn, &vport_update_params, 21737ab35bf6SHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 21747ab35bf6SHarish Patil if (rc) { 21757ab35bf6SHarish Patil DP_ERR(edev, "vport-update for RSS failed\n"); 21767ab35bf6SHarish Patil return rc; 21777ab35bf6SHarish Patil } 21787ab35bf6SHarish Patil } 21797ab35bf6SHarish Patil qdev->rss_enable = rss_params.rss_enable; 21807ab35bf6SHarish Patil 21817ab35bf6SHarish Patil /* Update local structure for hash query */ 21827ab35bf6SHarish Patil qdev->rss_conf.rss_hf = hf; 21837ab35bf6SHarish Patil qdev->rss_conf.rss_key_len = len; 21847ab35bf6SHarish Patil if (qdev->rss_enable) { 21857ab35bf6SHarish Patil if (qdev->rss_conf.rss_key == NULL) { 21867ab35bf6SHarish Patil qdev->rss_conf.rss_key = (uint8_t *)malloc(len); 21877ab35bf6SHarish Patil if (qdev->rss_conf.rss_key == NULL) { 21887ab35bf6SHarish Patil DP_ERR(edev, "No memory to store RSS key\n"); 21897ab35bf6SHarish Patil return -ENOMEM; 21907ab35bf6SHarish Patil } 21917ab35bf6SHarish Patil } 21927ab35bf6SHarish Patil if (key && len) { 21937ab35bf6SHarish Patil DP_INFO(edev, "Storing RSS key\n"); 21947ab35bf6SHarish Patil memcpy(qdev->rss_conf.rss_key, key, len); 21957ab35bf6SHarish Patil } 21967ab35bf6SHarish Patil } else if (!qdev->rss_enable && len == 0) { 21977ab35bf6SHarish Patil if (qdev->rss_conf.rss_key) { 21987ab35bf6SHarish Patil free(qdev->rss_conf.rss_key); 21997ab35bf6SHarish Patil qdev->rss_conf.rss_key = NULL; 22007ab35bf6SHarish Patil DP_INFO(edev, "Free RSS key\n"); 22017ab35bf6SHarish Patil } 22027ab35bf6SHarish Patil } 22037ab35bf6SHarish Patil 22047ab35bf6SHarish Patil return 0; 22057ab35bf6SHarish Patil } 22067ab35bf6SHarish Patil 22077ab35bf6SHarish Patil static int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev, 22086d9e26c4SSony Chacko struct rte_eth_rss_conf *rss_conf) 22096d9e26c4SSony Chacko { 22107ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 22116d9e26c4SSony Chacko 22127ab35bf6SHarish Patil rss_conf->rss_hf = qdev->rss_conf.rss_hf; 22137ab35bf6SHarish Patil rss_conf->rss_key_len = qdev->rss_conf.rss_key_len; 22146d9e26c4SSony Chacko 22157ab35bf6SHarish Patil if (rss_conf->rss_key && qdev->rss_conf.rss_key) 22167ab35bf6SHarish Patil memcpy(rss_conf->rss_key, qdev->rss_conf.rss_key, 22177ab35bf6SHarish Patil rss_conf->rss_key_len); 22186d9e26c4SSony Chacko return 0; 22196d9e26c4SSony Chacko } 22206d9e26c4SSony Chacko 2221af785e47SRasesh Mody int qede_rss_reta_update(struct rte_eth_dev *eth_dev, 2222e8876556SSony Chacko struct rte_eth_rss_reta_entry64 *reta_conf, 2223e8876556SSony Chacko uint16_t reta_size) 2224e8876556SSony Chacko { 22257ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 22267ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 22277ab35bf6SHarish Patil struct ecore_sp_vport_update_params vport_update_params; 22288b3ee85eSRasesh Mody struct ecore_rss_params *params; 2229235cbe4cSShahed Shaikh uint16_t i, j, idx, fid, shift; 22307ab35bf6SHarish Patil struct ecore_hwfn *p_hwfn; 22317ab35bf6SHarish Patil uint8_t entry; 22328b3ee85eSRasesh Mody int rc = 0; 2233e8876556SSony Chacko 2234e8876556SSony Chacko if (reta_size > ETH_RSS_RETA_SIZE_128) { 2235e8876556SSony Chacko DP_ERR(edev, "reta_size %d is not supported by hardware\n", 2236e8876556SSony Chacko reta_size); 2237e8876556SSony Chacko return -EINVAL; 2238e8876556SSony Chacko } 2239e8876556SSony Chacko 2240e8876556SSony Chacko memset(&vport_update_params, 0, sizeof(vport_update_params)); 2241235cbe4cSShahed Shaikh params = rte_zmalloc("qede_rss", sizeof(*params), RTE_CACHE_LINE_SIZE); 2242ef86e67aSRongQiang Xie if (params == NULL) { 2243ef86e67aSRongQiang Xie DP_ERR(edev, "failed to allocate memory\n"); 2244ef86e67aSRongQiang Xie return -ENOMEM; 2245ef86e67aSRongQiang Xie } 2246e8876556SSony Chacko 22478b3ee85eSRasesh Mody params->update_rss_ind_table = 1; 22488b3ee85eSRasesh Mody params->rss_table_size_log = 7; 22498b3ee85eSRasesh Mody params->update_rss_config = 1; 22508b3ee85eSRasesh Mody 2251e8876556SSony Chacko vport_update_params.vport_id = 0; 22527ab35bf6SHarish Patil /* Use the current value of rss_enable */ 22538b3ee85eSRasesh Mody params->rss_enable = qdev->rss_enable; 22548b3ee85eSRasesh Mody vport_update_params.rss_params = params; 2255e8876556SSony Chacko 22567ab35bf6SHarish Patil for_each_hwfn(edev, i) { 2257235cbe4cSShahed Shaikh for (j = 0; j < reta_size; j++) { 2258235cbe4cSShahed Shaikh idx = j / RTE_RETA_GROUP_SIZE; 2259235cbe4cSShahed Shaikh shift = j % RTE_RETA_GROUP_SIZE; 2260235cbe4cSShahed Shaikh if (reta_conf[idx].mask & (1ULL << shift)) { 2261235cbe4cSShahed Shaikh entry = reta_conf[idx].reta[shift]; 2262235cbe4cSShahed Shaikh fid = entry * edev->num_hwfns + i; 2263235cbe4cSShahed Shaikh /* Pass rxq handles to ecore */ 2264235cbe4cSShahed Shaikh params->rss_ind_table[j] = 2265235cbe4cSShahed Shaikh qdev->fp_array[fid].rxq->handle; 2266235cbe4cSShahed Shaikh /* Update the local copy for RETA query cmd */ 2267235cbe4cSShahed Shaikh qdev->rss_ind_table[j] = entry; 2268235cbe4cSShahed Shaikh } 2269235cbe4cSShahed Shaikh } 2270235cbe4cSShahed Shaikh 22717ab35bf6SHarish Patil p_hwfn = &edev->hwfns[i]; 22727ab35bf6SHarish Patil vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid; 22737ab35bf6SHarish Patil rc = ecore_sp_vport_update(p_hwfn, &vport_update_params, 22747ab35bf6SHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 22757ab35bf6SHarish Patil if (rc) { 22767ab35bf6SHarish Patil DP_ERR(edev, "vport-update for RSS failed\n"); 22778b3ee85eSRasesh Mody goto out; 22787ab35bf6SHarish Patil } 2279e8876556SSony Chacko } 2280e8876556SSony Chacko 22818b3ee85eSRasesh Mody out: 22828b3ee85eSRasesh Mody rte_free(params); 22838b3ee85eSRasesh Mody return rc; 22847ab35bf6SHarish Patil } 22857ab35bf6SHarish Patil 22867ab35bf6SHarish Patil static int qede_rss_reta_query(struct rte_eth_dev *eth_dev, 22873dadf73eSSony Chacko struct rte_eth_rss_reta_entry64 *reta_conf, 22883dadf73eSSony Chacko uint16_t reta_size) 22893dadf73eSSony Chacko { 22903dadf73eSSony Chacko struct qede_dev *qdev = eth_dev->data->dev_private; 22917ab35bf6SHarish Patil struct ecore_dev *edev = &qdev->edev; 22923dadf73eSSony Chacko uint16_t i, idx, shift; 22937ab35bf6SHarish Patil uint8_t entry; 22943dadf73eSSony Chacko 22953dadf73eSSony Chacko if (reta_size > ETH_RSS_RETA_SIZE_128) { 22963dadf73eSSony Chacko DP_ERR(edev, "reta_size %d is not supported\n", 22973dadf73eSSony Chacko reta_size); 22987ab35bf6SHarish Patil return -EINVAL; 22993dadf73eSSony Chacko } 23003dadf73eSSony Chacko 23013dadf73eSSony Chacko for (i = 0; i < reta_size; i++) { 23023dadf73eSSony Chacko idx = i / RTE_RETA_GROUP_SIZE; 23033dadf73eSSony Chacko shift = i % RTE_RETA_GROUP_SIZE; 23043dadf73eSSony Chacko if (reta_conf[idx].mask & (1ULL << shift)) { 23057ab35bf6SHarish Patil entry = qdev->rss_ind_table[i]; 23063dadf73eSSony Chacko reta_conf[idx].reta[shift] = entry; 23073dadf73eSSony Chacko } 23083dadf73eSSony Chacko } 23093dadf73eSSony Chacko 23103dadf73eSSony Chacko return 0; 23113dadf73eSSony Chacko } 23123dadf73eSSony Chacko 23134c4bdadfSHarish Patil 23144c4bdadfSHarish Patil 2315af785e47SRasesh Mody static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 2316200645acSSony Chacko { 23171ef4c3a5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(dev); 23181ef4c3a5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 2319200645acSSony Chacko struct rte_eth_dev_info dev_info = {0}; 23201ef4c3a5SHarish Patil struct qede_fastpath *fp; 23219e334305SRasesh Mody uint32_t max_rx_pkt_len; 23221ef4c3a5SHarish Patil uint32_t frame_size; 23231ef4c3a5SHarish Patil uint16_t bufsz; 23249e334305SRasesh Mody bool restart = false; 2325318d7da3SShahed Shaikh int i, rc; 2326200645acSSony Chacko 23271ef4c3a5SHarish Patil PMD_INIT_FUNC_TRACE(edev); 2328bdad90d1SIvan Ilchenko rc = qede_dev_info_get(dev, &dev_info); 2329bdad90d1SIvan Ilchenko if (rc != 0) { 2330bdad90d1SIvan Ilchenko DP_ERR(edev, "Error during getting ethernet device info\n"); 2331bdad90d1SIvan Ilchenko return rc; 2332bdad90d1SIvan Ilchenko } 2333318d7da3SShahed Shaikh max_rx_pkt_len = mtu + QEDE_MAX_ETHER_HDR_LEN; 2334318d7da3SShahed Shaikh frame_size = max_rx_pkt_len; 233535b2d13fSOlivier Matz if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen) { 23369e334305SRasesh Mody DP_ERR(edev, "MTU %u out of range, %u is maximum allowable\n", 233735b2d13fSOlivier Matz mtu, dev_info.max_rx_pktlen - RTE_ETHER_HDR_LEN - 2338318d7da3SShahed Shaikh QEDE_ETH_OVERHEAD); 2339200645acSSony Chacko return -EINVAL; 23401ef4c3a5SHarish Patil } 2341200645acSSony Chacko if (!dev->data->scattered_rx && 23421ef4c3a5SHarish Patil frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) { 23431ef4c3a5SHarish Patil DP_INFO(edev, "MTU greater than minimum RX buffer size of %u\n", 23441ef4c3a5SHarish Patil dev->data->min_rx_buf_size); 2345200645acSSony Chacko return -EINVAL; 23461ef4c3a5SHarish Patil } 23479e334305SRasesh Mody if (dev->data->dev_started) { 23489e334305SRasesh Mody dev->data->dev_started = 0; 234962024eb8SIvan Ilchenko rc = qede_dev_stop(dev); 235062024eb8SIvan Ilchenko if (rc != 0) 235162024eb8SIvan Ilchenko return rc; 23529e334305SRasesh Mody restart = true; 23539e334305SRasesh Mody } 23541ef4c3a5SHarish Patil rte_delay_ms(1000); 235529bb154fSShahed Shaikh qdev->new_mtu = mtu; 2356dd28bc8cSHarish Patil 23571ef4c3a5SHarish Patil /* Fix up RX buf size for all queues of the port */ 23588de0c420SShahed Shaikh for (i = 0; i < qdev->num_rx_queues; i++) { 23591ef4c3a5SHarish Patil fp = &qdev->fp_array[i]; 23609e334305SRasesh Mody if (fp->rxq != NULL) { 23611ef4c3a5SHarish Patil bufsz = (uint16_t)rte_pktmbuf_data_room_size( 23621ef4c3a5SHarish Patil fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM; 2363318d7da3SShahed Shaikh /* cache align the mbuf size to simplfy rx_buf_size 2364318d7da3SShahed Shaikh * calculation 2365318d7da3SShahed Shaikh */ 2366318d7da3SShahed Shaikh bufsz = QEDE_FLOOR_TO_CACHE_LINE_SIZE(bufsz); 2367318d7da3SShahed Shaikh rc = qede_calc_rx_buf_size(dev, bufsz, frame_size); 2368318d7da3SShahed Shaikh if (rc < 0) 2369318d7da3SShahed Shaikh return rc; 2370318d7da3SShahed Shaikh 2371318d7da3SShahed Shaikh fp->rxq->rx_buf_size = rc; 23721ef4c3a5SHarish Patil } 23739e334305SRasesh Mody } 2374f9a69f8bSSteve Yang if (frame_size > QEDE_ETH_MAX_LEN) 2375ab3ce1e0SFerruh Yigit dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; 2376200645acSSony Chacko else 2377ab3ce1e0SFerruh Yigit dev->data->dev_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; 2378dd28bc8cSHarish Patil 23799e334305SRasesh Mody if (!dev->data->dev_started && restart) { 23809e334305SRasesh Mody qede_dev_start(dev); 23819e334305SRasesh Mody dev->data->dev_started = 1; 23829e334305SRasesh Mody } 2383dd28bc8cSHarish Patil 2384200645acSSony Chacko /* update max frame size */ 23859e334305SRasesh Mody dev->data->dev_conf.rxmode.max_rx_pkt_len = max_rx_pkt_len; 238681f88049SShahed Shaikh 2387200645acSSony Chacko return 0; 2388200645acSSony Chacko } 2389200645acSSony Chacko 2390ad4d092bSShahed Shaikh static int 2391ad4d092bSShahed Shaikh qede_dev_reset(struct rte_eth_dev *dev) 2392ad4d092bSShahed Shaikh { 2393ad4d092bSShahed Shaikh int ret; 2394ad4d092bSShahed Shaikh 2395ad4d092bSShahed Shaikh ret = qede_eth_dev_uninit(dev); 2396ad4d092bSShahed Shaikh if (ret) 2397ad4d092bSShahed Shaikh return ret; 2398ad4d092bSShahed Shaikh 2399ad4d092bSShahed Shaikh return qede_eth_dev_init(dev); 2400ad4d092bSShahed Shaikh } 2401ad4d092bSShahed Shaikh 24022ea6f76aSRasesh Mody static const struct eth_dev_ops qede_eth_dev_ops = { 24032ea6f76aSRasesh Mody .dev_configure = qede_dev_configure, 24042ea6f76aSRasesh Mody .dev_infos_get = qede_dev_info_get, 24052ea6f76aSRasesh Mody .rx_queue_setup = qede_rx_queue_setup, 24062ea6f76aSRasesh Mody .rx_queue_release = qede_rx_queue_release, 24072ea6f76aSRasesh Mody .tx_queue_setup = qede_tx_queue_setup, 24082ea6f76aSRasesh Mody .tx_queue_release = qede_tx_queue_release, 24092ea6f76aSRasesh Mody .dev_start = qede_dev_start, 2410ad4d092bSShahed Shaikh .dev_reset = qede_dev_reset, 24112ea6f76aSRasesh Mody .dev_set_link_up = qede_dev_set_link_up, 24122ea6f76aSRasesh Mody .dev_set_link_down = qede_dev_set_link_down, 24132ea6f76aSRasesh Mody .link_update = qede_link_update, 24142ea6f76aSRasesh Mody .promiscuous_enable = qede_promiscuous_enable, 24152ea6f76aSRasesh Mody .promiscuous_disable = qede_promiscuous_disable, 24162ea6f76aSRasesh Mody .allmulticast_enable = qede_allmulticast_enable, 24172ea6f76aSRasesh Mody .allmulticast_disable = qede_allmulticast_disable, 2418413ecf29SHarish Patil .set_mc_addr_list = qede_set_mc_addr_list, 24192ea6f76aSRasesh Mody .dev_stop = qede_dev_stop, 24202ea6f76aSRasesh Mody .dev_close = qede_dev_close, 24212ea6f76aSRasesh Mody .stats_get = qede_get_stats, 24225cdd769aSRasesh Mody .stats_reset = qede_reset_stats, 2423d1216e22SRasesh Mody .xstats_get = qede_get_xstats, 2424d1216e22SRasesh Mody .xstats_reset = qede_reset_xstats, 2425d1216e22SRasesh Mody .xstats_get_names = qede_get_xstats_names, 24262ea6f76aSRasesh Mody .mac_addr_add = qede_mac_addr_add, 24272ea6f76aSRasesh Mody .mac_addr_remove = qede_mac_addr_remove, 24282ea6f76aSRasesh Mody .mac_addr_set = qede_mac_addr_set, 24292ea6f76aSRasesh Mody .vlan_offload_set = qede_vlan_offload_set, 24302ea6f76aSRasesh Mody .vlan_filter_set = qede_vlan_filter_set, 24312ea6f76aSRasesh Mody .flow_ctrl_set = qede_flow_ctrl_set, 24322ea6f76aSRasesh Mody .flow_ctrl_get = qede_flow_ctrl_get, 24332ea6f76aSRasesh Mody .dev_supported_ptypes_get = qede_dev_supported_ptypes_get, 24344c98f276SSony Chacko .rss_hash_update = qede_rss_hash_update, 24356d9e26c4SSony Chacko .rss_hash_conf_get = qede_rss_hash_conf_get, 2436e8876556SSony Chacko .reta_update = qede_rss_reta_update, 24373dadf73eSSony Chacko .reta_query = qede_rss_reta_query, 2438200645acSSony Chacko .mtu_set = qede_set_mtu, 243952d94b57SHarish Patil .filter_ctrl = qede_dev_filter_ctrl, 244052d94b57SHarish Patil .udp_tunnel_port_add = qede_udp_dst_port_add, 244152d94b57SHarish Patil .udp_tunnel_port_del = qede_udp_dst_port_del, 2442f97b56f9SRasesh Mody .fw_version_get = qede_fw_version_get, 2443a50d7cbbSRasesh Mody .get_reg = qede_get_regs, 24442ea6f76aSRasesh Mody }; 24452ea6f76aSRasesh Mody 244686a2265eSRasesh Mody static const struct eth_dev_ops qede_eth_vf_dev_ops = { 244786a2265eSRasesh Mody .dev_configure = qede_dev_configure, 244886a2265eSRasesh Mody .dev_infos_get = qede_dev_info_get, 244986a2265eSRasesh Mody .rx_queue_setup = qede_rx_queue_setup, 245086a2265eSRasesh Mody .rx_queue_release = qede_rx_queue_release, 245186a2265eSRasesh Mody .tx_queue_setup = qede_tx_queue_setup, 245286a2265eSRasesh Mody .tx_queue_release = qede_tx_queue_release, 245386a2265eSRasesh Mody .dev_start = qede_dev_start, 2454ad4d092bSShahed Shaikh .dev_reset = qede_dev_reset, 245586a2265eSRasesh Mody .dev_set_link_up = qede_dev_set_link_up, 245686a2265eSRasesh Mody .dev_set_link_down = qede_dev_set_link_down, 245786a2265eSRasesh Mody .link_update = qede_link_update, 245886a2265eSRasesh Mody .promiscuous_enable = qede_promiscuous_enable, 245986a2265eSRasesh Mody .promiscuous_disable = qede_promiscuous_disable, 246086a2265eSRasesh Mody .allmulticast_enable = qede_allmulticast_enable, 246186a2265eSRasesh Mody .allmulticast_disable = qede_allmulticast_disable, 2462413ecf29SHarish Patil .set_mc_addr_list = qede_set_mc_addr_list, 246386a2265eSRasesh Mody .dev_stop = qede_dev_stop, 246486a2265eSRasesh Mody .dev_close = qede_dev_close, 246586a2265eSRasesh Mody .stats_get = qede_get_stats, 246686a2265eSRasesh Mody .stats_reset = qede_reset_stats, 2467d1216e22SRasesh Mody .xstats_get = qede_get_xstats, 2468d1216e22SRasesh Mody .xstats_reset = qede_reset_xstats, 2469d1216e22SRasesh Mody .xstats_get_names = qede_get_xstats_names, 247086a2265eSRasesh Mody .vlan_offload_set = qede_vlan_offload_set, 247186a2265eSRasesh Mody .vlan_filter_set = qede_vlan_filter_set, 247286a2265eSRasesh Mody .dev_supported_ptypes_get = qede_dev_supported_ptypes_get, 24734c98f276SSony Chacko .rss_hash_update = qede_rss_hash_update, 24746d9e26c4SSony Chacko .rss_hash_conf_get = qede_rss_hash_conf_get, 2475e8876556SSony Chacko .reta_update = qede_rss_reta_update, 24763dadf73eSSony Chacko .reta_query = qede_rss_reta_query, 2477200645acSSony Chacko .mtu_set = qede_set_mtu, 2478e0947ed9SHarish Patil .udp_tunnel_port_add = qede_udp_dst_port_add, 2479e0947ed9SHarish Patil .udp_tunnel_port_del = qede_udp_dst_port_del, 2480c7641841SShahed Shaikh .mac_addr_add = qede_mac_addr_add, 2481c7641841SShahed Shaikh .mac_addr_remove = qede_mac_addr_remove, 2482c7641841SShahed Shaikh .mac_addr_set = qede_mac_addr_set, 2483f97b56f9SRasesh Mody .fw_version_get = qede_fw_version_get, 248486a2265eSRasesh Mody }; 248586a2265eSRasesh Mody 24862ea6f76aSRasesh Mody static void qede_update_pf_params(struct ecore_dev *edev) 24872ea6f76aSRasesh Mody { 24882ea6f76aSRasesh Mody struct ecore_pf_params pf_params; 2489528fcfabSHarish Patil 24902ea6f76aSRasesh Mody memset(&pf_params, 0, sizeof(struct ecore_pf_params)); 2491528fcfabSHarish Patil pf_params.eth_pf_params.num_cons = QEDE_PF_NUM_CONNS; 249262207535SHarish Patil pf_params.eth_pf_params.num_arfs_filters = QEDE_RFS_MAX_FLTR; 24932ea6f76aSRasesh Mody qed_ops->common->update_pf_params(edev, &pf_params); 24942ea6f76aSRasesh Mody } 24952ea6f76aSRasesh Mody 2496c176fd86SManish Chopra static void qede_generate_random_mac_addr(struct rte_ether_addr *mac_addr) 2497c176fd86SManish Chopra { 2498c176fd86SManish Chopra uint64_t random; 2499c176fd86SManish Chopra 2500c176fd86SManish Chopra /* Set Organizationally Unique Identifier (OUI) prefix. */ 2501c176fd86SManish Chopra mac_addr->addr_bytes[0] = 0x00; 2502c176fd86SManish Chopra mac_addr->addr_bytes[1] = 0x09; 2503c176fd86SManish Chopra mac_addr->addr_bytes[2] = 0xC0; 2504c176fd86SManish Chopra 2505c176fd86SManish Chopra /* Force indication of locally assigned MAC address. */ 2506c176fd86SManish Chopra mac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR; 2507c176fd86SManish Chopra 2508c176fd86SManish Chopra /* Generate the last 3 bytes of the MAC address with a random number. */ 2509c176fd86SManish Chopra random = rte_rand(); 2510c176fd86SManish Chopra 2511c176fd86SManish Chopra memcpy(&mac_addr->addr_bytes[3], &random, 3); 2512c176fd86SManish Chopra } 2513c176fd86SManish Chopra 25142ea6f76aSRasesh Mody static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf) 25152ea6f76aSRasesh Mody { 25162ea6f76aSRasesh Mody struct rte_pci_device *pci_dev; 25172ea6f76aSRasesh Mody struct rte_pci_addr pci_addr; 25182ea6f76aSRasesh Mody struct qede_dev *adapter; 25192ea6f76aSRasesh Mody struct ecore_dev *edev; 25202ea6f76aSRasesh Mody struct qed_dev_eth_info dev_info; 25212ea6f76aSRasesh Mody struct qed_slowpath_params params; 25222ea6f76aSRasesh Mody static bool do_once = true; 25232ea6f76aSRasesh Mody uint8_t bulletin_change; 252435b2d13fSOlivier Matz uint8_t vf_mac[RTE_ETHER_ADDR_LEN]; 25252ea6f76aSRasesh Mody uint8_t is_mac_forced; 2526c176fd86SManish Chopra bool is_mac_exist = false; 25272ea6f76aSRasesh Mody /* Fix up ecore debug level */ 25282ea6f76aSRasesh Mody uint32_t dp_module = ~0 & ~ECORE_MSG_HW; 25292ea6f76aSRasesh Mody uint8_t dp_level = ECORE_LEVEL_VERBOSE; 2530245aec28SShahed Shaikh uint32_t int_mode; 25312ea6f76aSRasesh Mody int rc; 25322ea6f76aSRasesh Mody 25332ea6f76aSRasesh Mody /* Extract key data structures */ 25342ea6f76aSRasesh Mody adapter = eth_dev->data->dev_private; 25358aab5d6fSRasesh Mody adapter->ethdev = eth_dev; 25362ea6f76aSRasesh Mody edev = &adapter->edev; 2537c0802544SFerruh Yigit pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 2538d4b7f673SJan Blunck pci_addr = pci_dev->addr; 25392ea6f76aSRasesh Mody 25402ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 25412ea6f76aSRasesh Mody 25422ea6f76aSRasesh Mody snprintf(edev->name, NAME_SIZE, PCI_SHORT_PRI_FMT ":dpdk-port-%u", 25432ea6f76aSRasesh Mody pci_addr.bus, pci_addr.devid, pci_addr.function, 25442ea6f76aSRasesh Mody eth_dev->data->port_id); 25452ea6f76aSRasesh Mody 25462ea6f76aSRasesh Mody if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 25474ffa2af9SRasesh Mody DP_ERR(edev, "Skipping device init from secondary process\n"); 25482ea6f76aSRasesh Mody return 0; 25492ea6f76aSRasesh Mody } 25502ea6f76aSRasesh Mody 25512ea6f76aSRasesh Mody rte_eth_copy_pci_info(eth_dev, pci_dev); 2552f30e69b4SFerruh Yigit eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 25532ea6f76aSRasesh Mody 2554fb58ad9eSRasesh Mody /* @DPDK */ 2555fb58ad9eSRasesh Mody edev->vendor_id = pci_dev->id.vendor_id; 2556fb58ad9eSRasesh Mody edev->device_id = pci_dev->id.device_id; 2557fb58ad9eSRasesh Mody 25585cdd769aSRasesh Mody qed_ops = qed_get_eth_ops(); 25595cdd769aSRasesh Mody if (!qed_ops) { 25605cdd769aSRasesh Mody DP_ERR(edev, "Failed to get qed_eth_ops_pass\n"); 25612b5243d7SRasesh Mody rc = -EINVAL; 25622b5243d7SRasesh Mody goto err; 25635cdd769aSRasesh Mody } 25645cdd769aSRasesh Mody 25652ea6f76aSRasesh Mody DP_INFO(edev, "Starting qede probe\n"); 25664c4bdadfSHarish Patil rc = qed_ops->common->probe(edev, pci_dev, dp_module, 25674c4bdadfSHarish Patil dp_level, is_vf); 25682ea6f76aSRasesh Mody if (rc != 0) { 25692ea6f76aSRasesh Mody DP_ERR(edev, "qede probe failed rc %d\n", rc); 25702b5243d7SRasesh Mody rc = -ENODEV; 25712b5243d7SRasesh Mody goto err; 25722ea6f76aSRasesh Mody } 25732ea6f76aSRasesh Mody qede_update_pf_params(edev); 2574245aec28SShahed Shaikh 2575245aec28SShahed Shaikh switch (pci_dev->intr_handle.type) { 2576245aec28SShahed Shaikh case RTE_INTR_HANDLE_UIO_INTX: 2577245aec28SShahed Shaikh case RTE_INTR_HANDLE_VFIO_LEGACY: 2578245aec28SShahed Shaikh int_mode = ECORE_INT_MODE_INTA; 2579d4b7f673SJan Blunck rte_intr_callback_register(&pci_dev->intr_handle, 2580245aec28SShahed Shaikh qede_interrupt_handler_intx, 2581245aec28SShahed Shaikh (void *)eth_dev); 2582245aec28SShahed Shaikh break; 2583245aec28SShahed Shaikh default: 2584245aec28SShahed Shaikh int_mode = ECORE_INT_MODE_MSIX; 2585245aec28SShahed Shaikh rte_intr_callback_register(&pci_dev->intr_handle, 2586245aec28SShahed Shaikh qede_interrupt_handler, 2587245aec28SShahed Shaikh (void *)eth_dev); 2588245aec28SShahed Shaikh } 2589245aec28SShahed Shaikh 2590d4b7f673SJan Blunck if (rte_intr_enable(&pci_dev->intr_handle)) { 25912ea6f76aSRasesh Mody DP_ERR(edev, "rte_intr_enable() failed\n"); 25922b5243d7SRasesh Mody rc = -ENODEV; 25932b5243d7SRasesh Mody goto err; 25942ea6f76aSRasesh Mody } 25952ea6f76aSRasesh Mody 25962ea6f76aSRasesh Mody /* Start the Slowpath-process */ 25972ea6f76aSRasesh Mody memset(¶ms, 0, sizeof(struct qed_slowpath_params)); 2598245aec28SShahed Shaikh 2599245aec28SShahed Shaikh params.int_mode = int_mode; 26007eca78ceSHarish Patil params.drv_major = QEDE_PMD_VERSION_MAJOR; 26017eca78ceSHarish Patil params.drv_minor = QEDE_PMD_VERSION_MINOR; 26027eca78ceSHarish Patil params.drv_rev = QEDE_PMD_VERSION_REVISION; 26037eca78ceSHarish Patil params.drv_eng = QEDE_PMD_VERSION_PATCH; 26047eca78ceSHarish Patil strncpy((char *)params.name, QEDE_PMD_VER_PREFIX, 26057eca78ceSHarish Patil QEDE_PMD_DRV_VER_STR_SIZE); 26062ea6f76aSRasesh Mody 2607a60704d1SRasesh Mody qede_assign_rxtx_handlers(eth_dev, true); 26088de0c420SShahed Shaikh eth_dev->tx_pkt_prepare = qede_xmit_prep_pkts; 26098de0c420SShahed Shaikh 26102af14ca7SHarish Patil /* For CMT mode device do periodic polling for slowpath events. 26112af14ca7SHarish Patil * This is required since uio device uses only one MSI-x 26122af14ca7SHarish Patil * interrupt vector but we need one for each engine. 26132af14ca7SHarish Patil */ 2614c0845c33SRasesh Mody if (ECORE_IS_CMT(edev) && IS_PF(edev)) { 26150833120fSShahed Shaikh rc = rte_eal_alarm_set(QEDE_SP_TIMER_PERIOD, 26162af14ca7SHarish Patil qede_poll_sp_sb_cb, 26172af14ca7SHarish Patil (void *)eth_dev); 26182af14ca7SHarish Patil if (rc != 0) { 26192af14ca7SHarish Patil DP_ERR(edev, "Unable to start periodic" 26202af14ca7SHarish Patil " timer rc %d\n", rc); 26212b5243d7SRasesh Mody rc = -EINVAL; 26222b5243d7SRasesh Mody goto err; 26232af14ca7SHarish Patil } 26242af14ca7SHarish Patil } 26252af14ca7SHarish Patil 26262ea6f76aSRasesh Mody rc = qed_ops->common->slowpath_start(edev, ¶ms); 26272ea6f76aSRasesh Mody if (rc) { 26282ea6f76aSRasesh Mody DP_ERR(edev, "Cannot start slowpath rc = %d\n", rc); 26292af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 26302af14ca7SHarish Patil (void *)eth_dev); 26312b5243d7SRasesh Mody rc = -ENODEV; 26322b5243d7SRasesh Mody goto err; 26332ea6f76aSRasesh Mody } 26342ea6f76aSRasesh Mody 26352ea6f76aSRasesh Mody rc = qed_ops->fill_dev_info(edev, &dev_info); 26362ea6f76aSRasesh Mody if (rc) { 26372ea6f76aSRasesh Mody DP_ERR(edev, "Cannot get device_info rc %d\n", rc); 26382ea6f76aSRasesh Mody qed_ops->common->slowpath_stop(edev); 26392ea6f76aSRasesh Mody qed_ops->common->remove(edev); 26402af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 26412af14ca7SHarish Patil (void *)eth_dev); 26422b5243d7SRasesh Mody rc = -ENODEV; 26432b5243d7SRasesh Mody goto err; 26442ea6f76aSRasesh Mody } 26452ea6f76aSRasesh Mody 26462ea6f76aSRasesh Mody qede_alloc_etherdev(adapter, &dev_info); 26472ea6f76aSRasesh Mody 26482b5243d7SRasesh Mody if (do_once) { 2649f97b56f9SRasesh Mody qede_print_adapter_info(eth_dev); 26502b5243d7SRasesh Mody do_once = false; 26512b5243d7SRasesh Mody } 26522b5243d7SRasesh Mody 2653de5588afSRasesh Mody adapter->ops->common->set_name(edev, edev->name); 26542ea6f76aSRasesh Mody 26552ea6f76aSRasesh Mody if (!is_vf) 26563320ca8cSRasesh Mody adapter->dev_info.num_mac_filters = 26572ea6f76aSRasesh Mody (uint32_t)RESC_NUM(ECORE_LEADING_HWFN(edev), 26582ea6f76aSRasesh Mody ECORE_MAC); 26592ea6f76aSRasesh Mody else 266086a2265eSRasesh Mody ecore_vf_get_num_mac_filters(ECORE_LEADING_HWFN(edev), 26613320ca8cSRasesh Mody (uint32_t *)&adapter->dev_info.num_mac_filters); 26622ea6f76aSRasesh Mody 26632ea6f76aSRasesh Mody /* Allocate memory for storing MAC addr */ 26642ea6f76aSRasesh Mody eth_dev->data->mac_addrs = rte_zmalloc(edev->name, 266535b2d13fSOlivier Matz (RTE_ETHER_ADDR_LEN * 26663320ca8cSRasesh Mody adapter->dev_info.num_mac_filters), 26672ea6f76aSRasesh Mody RTE_CACHE_LINE_SIZE); 26682ea6f76aSRasesh Mody 26692ea6f76aSRasesh Mody if (eth_dev->data->mac_addrs == NULL) { 26702ea6f76aSRasesh Mody DP_ERR(edev, "Failed to allocate MAC address\n"); 26712ea6f76aSRasesh Mody qed_ops->common->slowpath_stop(edev); 26722ea6f76aSRasesh Mody qed_ops->common->remove(edev); 26732af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 26742af14ca7SHarish Patil (void *)eth_dev); 26752ea6f76aSRasesh Mody return -ENOMEM; 26762ea6f76aSRasesh Mody } 26772ea6f76aSRasesh Mody 267886a2265eSRasesh Mody if (!is_vf) { 2679538da7a1SOlivier Matz rte_ether_addr_copy((struct rte_ether_addr *)edev->hwfns[0]. 26802ea6f76aSRasesh Mody hw_info.hw_mac_addr, 26812ea6f76aSRasesh Mody ð_dev->data->mac_addrs[0]); 2682538da7a1SOlivier Matz rte_ether_addr_copy(ð_dev->data->mac_addrs[0], 268386a2265eSRasesh Mody &adapter->primary_mac); 268486a2265eSRasesh Mody } else { 268586a2265eSRasesh Mody ecore_vf_read_bulletin(ECORE_LEADING_HWFN(edev), 268686a2265eSRasesh Mody &bulletin_change); 268786a2265eSRasesh Mody if (bulletin_change) { 268886a2265eSRasesh Mody is_mac_exist = 268986a2265eSRasesh Mody ecore_vf_bulletin_get_forced_mac( 269086a2265eSRasesh Mody ECORE_LEADING_HWFN(edev), 269186a2265eSRasesh Mody vf_mac, 269286a2265eSRasesh Mody &is_mac_forced); 2693c7641841SShahed Shaikh if (is_mac_exist) { 269486a2265eSRasesh Mody DP_INFO(edev, "VF macaddr received from PF\n"); 2695538da7a1SOlivier Matz rte_ether_addr_copy( 26966d13ea8eSOlivier Matz (struct rte_ether_addr *)&vf_mac, 269786a2265eSRasesh Mody ð_dev->data->mac_addrs[0]); 2698538da7a1SOlivier Matz rte_ether_addr_copy( 2699538da7a1SOlivier Matz ð_dev->data->mac_addrs[0], 270086a2265eSRasesh Mody &adapter->primary_mac); 270186a2265eSRasesh Mody } else { 27024ffa2af9SRasesh Mody DP_ERR(edev, "No VF macaddr assigned\n"); 270386a2265eSRasesh Mody } 270486a2265eSRasesh Mody } 2705c176fd86SManish Chopra 2706c176fd86SManish Chopra /* If MAC doesn't exist from PF, generate random one */ 2707c176fd86SManish Chopra if (!is_mac_exist) { 2708c176fd86SManish Chopra struct rte_ether_addr *mac_addr; 2709c176fd86SManish Chopra 2710c176fd86SManish Chopra mac_addr = (struct rte_ether_addr *)&vf_mac; 2711c176fd86SManish Chopra qede_generate_random_mac_addr(mac_addr); 2712c176fd86SManish Chopra 2713c176fd86SManish Chopra rte_ether_addr_copy(mac_addr, 2714c176fd86SManish Chopra ð_dev->data->mac_addrs[0]); 2715c176fd86SManish Chopra 2716c176fd86SManish Chopra rte_ether_addr_copy(ð_dev->data->mac_addrs[0], 2717c176fd86SManish Chopra &adapter->primary_mac); 2718c176fd86SManish Chopra } 271986a2265eSRasesh Mody } 27202ea6f76aSRasesh Mody 272186a2265eSRasesh Mody eth_dev->dev_ops = (is_vf) ? &qede_eth_vf_dev_ops : &qede_eth_dev_ops; 2722cbfc6111SFerruh Yigit eth_dev->rx_descriptor_status = qede_rx_descriptor_status; 27232ea6f76aSRasesh Mody 27244c4bdadfSHarish Patil adapter->num_tx_queues = 0; 27254c4bdadfSHarish Patil adapter->num_rx_queues = 0; 2726f5765f66SShahed Shaikh SLIST_INIT(&adapter->arfs_info.arfs_list_head); 27274c4bdadfSHarish Patil SLIST_INIT(&adapter->vlan_list_head); 27284c4bdadfSHarish Patil SLIST_INIT(&adapter->uc_list_head); 2729413ecf29SHarish Patil SLIST_INIT(&adapter->mc_list_head); 273035b2d13fSOlivier Matz adapter->mtu = RTE_ETHER_MTU; 2731dd28bc8cSHarish Patil adapter->vport_started = false; 2732dd28bc8cSHarish Patil 2733c8b34b7eSHarish Patil /* VF tunnel offloads is enabled by default in PF driver */ 2734c8b34b7eSHarish Patil adapter->vxlan.num_filters = 0; 27357cf0f102SHarish Patil adapter->geneve.num_filters = 0; 2736e1e38962SHarish Patil adapter->ipgre.num_filters = 0; 27377cf0f102SHarish Patil if (is_vf) { 27387cf0f102SHarish Patil adapter->vxlan.enable = true; 2739c8b34b7eSHarish Patil adapter->vxlan.filter_type = ETH_TUNNEL_FILTER_IMAC | 2740c8b34b7eSHarish Patil ETH_TUNNEL_FILTER_IVLAN; 2741c8b34b7eSHarish Patil adapter->vxlan.udp_port = QEDE_VXLAN_DEF_PORT; 2742c8b34b7eSHarish Patil adapter->geneve.enable = true; 27437cf0f102SHarish Patil adapter->geneve.filter_type = ETH_TUNNEL_FILTER_IMAC | 2744c8b34b7eSHarish Patil ETH_TUNNEL_FILTER_IVLAN; 27457cf0f102SHarish Patil adapter->geneve.udp_port = QEDE_GENEVE_DEF_PORT; 2746e1e38962SHarish Patil adapter->ipgre.enable = true; 2747e1e38962SHarish Patil adapter->ipgre.filter_type = ETH_TUNNEL_FILTER_IMAC | 2748e1e38962SHarish Patil ETH_TUNNEL_FILTER_IVLAN; 27497cf0f102SHarish Patil } else { 27507cf0f102SHarish Patil adapter->vxlan.enable = false; 27517cf0f102SHarish Patil adapter->geneve.enable = false; 2752e1e38962SHarish Patil adapter->ipgre.enable = false; 27539ffe2a15SManish Chopra qed_ops->sriov_configure(edev, pci_dev->max_vfs); 27547cf0f102SHarish Patil } 2755dbac54c2SHarish Patil 27564ffa2af9SRasesh Mody DP_INFO(edev, "MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n", 27572ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[0], 27582ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[1], 27592ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[2], 27602ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[3], 27612ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[4], 27622ea6f76aSRasesh Mody adapter->primary_mac.addr_bytes[5]); 27632ea6f76aSRasesh Mody 27644c4bdadfSHarish Patil DP_INFO(edev, "Device initialized\n"); 27654c4bdadfSHarish Patil 27664c4bdadfSHarish Patil return 0; 27672b5243d7SRasesh Mody 27682b5243d7SRasesh Mody err: 27692b5243d7SRasesh Mody if (do_once) { 2770f97b56f9SRasesh Mody qede_print_adapter_info(eth_dev); 27712b5243d7SRasesh Mody do_once = false; 27722b5243d7SRasesh Mody } 27732b5243d7SRasesh Mody return rc; 27742ea6f76aSRasesh Mody } 27752ea6f76aSRasesh Mody 27762ea6f76aSRasesh Mody static int qedevf_eth_dev_init(struct rte_eth_dev *eth_dev) 27772ea6f76aSRasesh Mody { 27782ea6f76aSRasesh Mody return qede_common_dev_init(eth_dev, 1); 27792ea6f76aSRasesh Mody } 27802ea6f76aSRasesh Mody 27812ea6f76aSRasesh Mody static int qede_eth_dev_init(struct rte_eth_dev *eth_dev) 27822ea6f76aSRasesh Mody { 27832ea6f76aSRasesh Mody return qede_common_dev_init(eth_dev, 0); 27842ea6f76aSRasesh Mody } 27852ea6f76aSRasesh Mody 27862ea6f76aSRasesh Mody static int qede_dev_common_uninit(struct rte_eth_dev *eth_dev) 27872ea6f76aSRasesh Mody { 2788e8fb98d6SRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 2789e8fb98d6SRasesh Mody struct ecore_dev *edev = &qdev->edev; 2790e8fb98d6SRasesh Mody PMD_INIT_FUNC_TRACE(edev); 27912ea6f76aSRasesh Mody qede_dev_close(eth_dev); 27922ea6f76aSRasesh Mody return 0; 27932ea6f76aSRasesh Mody } 27942ea6f76aSRasesh Mody 27952ea6f76aSRasesh Mody static int qede_eth_dev_uninit(struct rte_eth_dev *eth_dev) 27962ea6f76aSRasesh Mody { 27972ea6f76aSRasesh Mody return qede_dev_common_uninit(eth_dev); 27982ea6f76aSRasesh Mody } 27992ea6f76aSRasesh Mody 28002ea6f76aSRasesh Mody static int qedevf_eth_dev_uninit(struct rte_eth_dev *eth_dev) 28012ea6f76aSRasesh Mody { 28022ea6f76aSRasesh Mody return qede_dev_common_uninit(eth_dev); 28032ea6f76aSRasesh Mody } 28042ea6f76aSRasesh Mody 280528a1fd4fSFerruh Yigit static const struct rte_pci_id pci_id_qedevf_map[] = { 28062ea6f76aSRasesh Mody #define QEDEVF_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev) 28072ea6f76aSRasesh Mody { 280877f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_VF) 28092ea6f76aSRasesh Mody }, 28102ea6f76aSRasesh Mody { 281177f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_IOV) 281277f72221SRasesh Mody }, 281377f72221SRasesh Mody { 281477f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_IOV) 28152ea6f76aSRasesh Mody }, 28162ea6f76aSRasesh Mody {.vendor_id = 0,} 28172ea6f76aSRasesh Mody }; 28182ea6f76aSRasesh Mody 281928a1fd4fSFerruh Yigit static const struct rte_pci_id pci_id_qede_map[] = { 28202ea6f76aSRasesh Mody #define QEDE_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev) 28212ea6f76aSRasesh Mody { 282277f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980E) 28232ea6f76aSRasesh Mody }, 28242ea6f76aSRasesh Mody { 282577f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980S) 28262ea6f76aSRasesh Mody }, 28272ea6f76aSRasesh Mody { 282877f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_40) 28292ea6f76aSRasesh Mody }, 28302ea6f76aSRasesh Mody { 283177f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_25) 28322ea6f76aSRasesh Mody }, 28332af14ca7SHarish Patil { 283477f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_100) 283577f72221SRasesh Mody }, 283677f72221SRasesh Mody { 2837e6512107SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_50) 2838e6512107SRasesh Mody }, 2839e6512107SRasesh Mody { 284077f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_50G) 284177f72221SRasesh Mody }, 284277f72221SRasesh Mody { 284377f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_10G) 284477f72221SRasesh Mody }, 284577f72221SRasesh Mody { 284677f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_40G) 284777f72221SRasesh Mody }, 284877f72221SRasesh Mody { 284977f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_25G) 28502af14ca7SHarish Patil }, 28512ea6f76aSRasesh Mody {.vendor_id = 0,} 28522ea6f76aSRasesh Mody }; 28532ea6f76aSRasesh Mody 2854fdf91e0fSJan Blunck static int qedevf_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 2855fdf91e0fSJan Blunck struct rte_pci_device *pci_dev) 2856fdf91e0fSJan Blunck { 2857fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_probe(pci_dev, 2858fdf91e0fSJan Blunck sizeof(struct qede_dev), qedevf_eth_dev_init); 2859fdf91e0fSJan Blunck } 2860fdf91e0fSJan Blunck 2861fdf91e0fSJan Blunck static int qedevf_eth_dev_pci_remove(struct rte_pci_device *pci_dev) 2862fdf91e0fSJan Blunck { 2863fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_remove(pci_dev, qedevf_eth_dev_uninit); 2864fdf91e0fSJan Blunck } 2865fdf91e0fSJan Blunck 2866fdf91e0fSJan Blunck static struct rte_pci_driver rte_qedevf_pmd = { 28672ea6f76aSRasesh Mody .id_table = pci_id_qedevf_map, 2868b76fafb1SDavid Marchand .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 2869fdf91e0fSJan Blunck .probe = qedevf_eth_dev_pci_probe, 2870fdf91e0fSJan Blunck .remove = qedevf_eth_dev_pci_remove, 28712ea6f76aSRasesh Mody }; 28722ea6f76aSRasesh Mody 2873fdf91e0fSJan Blunck static int qede_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 2874fdf91e0fSJan Blunck struct rte_pci_device *pci_dev) 2875fdf91e0fSJan Blunck { 2876fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_probe(pci_dev, 2877fdf91e0fSJan Blunck sizeof(struct qede_dev), qede_eth_dev_init); 2878fdf91e0fSJan Blunck } 2879fdf91e0fSJan Blunck 2880fdf91e0fSJan Blunck static int qede_eth_dev_pci_remove(struct rte_pci_device *pci_dev) 2881fdf91e0fSJan Blunck { 2882fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_remove(pci_dev, qede_eth_dev_uninit); 2883fdf91e0fSJan Blunck } 2884fdf91e0fSJan Blunck 2885fdf91e0fSJan Blunck static struct rte_pci_driver rte_qede_pmd = { 28862ea6f76aSRasesh Mody .id_table = pci_id_qede_map, 2887b76fafb1SDavid Marchand .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 2888fdf91e0fSJan Blunck .probe = qede_eth_dev_pci_probe, 2889fdf91e0fSJan Blunck .remove = qede_eth_dev_pci_remove, 28902ea6f76aSRasesh Mody }; 28912ea6f76aSRasesh Mody 2892fdf91e0fSJan Blunck RTE_PMD_REGISTER_PCI(net_qede, rte_qede_pmd); 289301f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_qede, pci_id_qede_map); 289406e81dc9SDavid Marchand RTE_PMD_REGISTER_KMOD_DEP(net_qede, "* igb_uio | uio_pci_generic | vfio-pci"); 2895fdf91e0fSJan Blunck RTE_PMD_REGISTER_PCI(net_qede_vf, rte_qedevf_pmd); 289601f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_qede_vf, pci_id_qedevf_map); 289706e81dc9SDavid Marchand RTE_PMD_REGISTER_KMOD_DEP(net_qede_vf, "* igb_uio | vfio-pci"); 28989c99878aSJerin Jacob RTE_LOG_REGISTER(qede_logtype_init, pmd.net.qede.init, NOTICE); 28999c99878aSJerin Jacob RTE_LOG_REGISTER(qede_logtype_driver, pmd.net.qede.driver, NOTICE); 2900