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 (IS_PF(edev)) 241f97b56f9SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 242f97b56f9SRasesh Mody QEDE_PMD_FW_VERSION); 243f97b56f9SRasesh Mody else 244f97b56f9SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%d.%d.%d.%d", 245f97b56f9SRasesh Mody info->fw_major, info->fw_minor, 246f97b56f9SRasesh Mody info->fw_rev, info->fw_eng); 247f97b56f9SRasesh Mody size = strlen(ver_str); 248f97b56f9SRasesh Mody if (size + 1 <= fw_size) /* Add 1 byte for "\0" */ 249f97b56f9SRasesh Mody strlcpy(fw_ver, ver_str, fw_size); 250f97b56f9SRasesh Mody else 251f97b56f9SRasesh Mody return (size + 1); 252f97b56f9SRasesh Mody 253f97b56f9SRasesh Mody snprintf(ver_str + size, (QEDE_PMD_DRV_VER_STR_SIZE - size), 254f97b56f9SRasesh Mody " MFW: %d.%d.%d.%d", 255f97b56f9SRasesh Mody GET_MFW_FIELD(info->mfw_rev, QED_MFW_VERSION_3), 256f97b56f9SRasesh Mody GET_MFW_FIELD(info->mfw_rev, QED_MFW_VERSION_2), 257f97b56f9SRasesh Mody GET_MFW_FIELD(info->mfw_rev, QED_MFW_VERSION_1), 258f97b56f9SRasesh Mody GET_MFW_FIELD(info->mfw_rev, QED_MFW_VERSION_0)); 259f97b56f9SRasesh Mody size = strlen(ver_str); 260f97b56f9SRasesh Mody if (size + 1 <= fw_size) 261f97b56f9SRasesh Mody strlcpy(fw_ver, ver_str, fw_size); 262f97b56f9SRasesh Mody 263f97b56f9SRasesh Mody if (fw_size <= 32) 264f97b56f9SRasesh Mody goto out; 265f97b56f9SRasesh Mody 266f97b56f9SRasesh Mody snprintf(ver_str + size, (QEDE_PMD_DRV_VER_STR_SIZE - size), 267f97b56f9SRasesh Mody " MBI: %d.%d.%d", 268f97b56f9SRasesh Mody GET_MFW_FIELD(info->mbi_version, QED_MBI_VERSION_2), 269f97b56f9SRasesh Mody GET_MFW_FIELD(info->mbi_version, QED_MBI_VERSION_1), 270f97b56f9SRasesh Mody GET_MFW_FIELD(info->mbi_version, QED_MBI_VERSION_0)); 271f97b56f9SRasesh Mody size = strlen(ver_str); 272f97b56f9SRasesh Mody if (size + 1 <= fw_size) 273f97b56f9SRasesh Mody strlcpy(fw_ver, ver_str, fw_size); 274f97b56f9SRasesh Mody 275f97b56f9SRasesh Mody out: 276f97b56f9SRasesh Mody return 0; 277f97b56f9SRasesh Mody } 278f97b56f9SRasesh Mody 2792ea6f76aSRasesh Mody static void qede_interrupt_action(struct ecore_hwfn *p_hwfn) 2802ea6f76aSRasesh Mody { 281d459b043SManish Chopra OSAL_SPIN_LOCK(&p_hwfn->spq_lock); 2822ea6f76aSRasesh Mody ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn)); 283d459b043SManish Chopra OSAL_SPIN_UNLOCK(&p_hwfn->spq_lock); 2842ea6f76aSRasesh Mody } 2852ea6f76aSRasesh Mody 2862ea6f76aSRasesh Mody static void 287245aec28SShahed Shaikh qede_interrupt_handler_intx(void *param) 288245aec28SShahed Shaikh { 289245aec28SShahed Shaikh struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 290245aec28SShahed Shaikh struct qede_dev *qdev = eth_dev->data->dev_private; 291245aec28SShahed Shaikh struct ecore_dev *edev = &qdev->edev; 292245aec28SShahed Shaikh u64 status; 293245aec28SShahed Shaikh 294245aec28SShahed Shaikh /* Check if our device actually raised an interrupt */ 295245aec28SShahed Shaikh status = ecore_int_igu_read_sisr_reg(ECORE_LEADING_HWFN(edev)); 296245aec28SShahed Shaikh if (status & 0x1) { 297245aec28SShahed Shaikh qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 298245aec28SShahed Shaikh 2996bee9d5fSNithin Dabilpuram if (rte_intr_ack(eth_dev->intr_handle)) 3006bee9d5fSNithin Dabilpuram DP_ERR(edev, "rte_intr_ack failed\n"); 301245aec28SShahed Shaikh } 302245aec28SShahed Shaikh } 303245aec28SShahed Shaikh 304245aec28SShahed Shaikh static void 305c23a1a30SQi Zhang qede_interrupt_handler(void *param) 3062ea6f76aSRasesh Mody { 3072ea6f76aSRasesh Mody struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 3082ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 3092ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 3102ea6f76aSRasesh Mody 3112ea6f76aSRasesh Mody qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 3126bee9d5fSNithin Dabilpuram if (rte_intr_ack(eth_dev->intr_handle)) 3136bee9d5fSNithin Dabilpuram DP_ERR(edev, "rte_intr_ack failed\n"); 3142ea6f76aSRasesh Mody } 3152ea6f76aSRasesh Mody 3162ea6f76aSRasesh Mody static void 317a60704d1SRasesh Mody qede_assign_rxtx_handlers(struct rte_eth_dev *dev, bool is_dummy) 31881f88049SShahed Shaikh { 31974e5a25dSShahed Shaikh uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads; 32081f88049SShahed Shaikh struct qede_dev *qdev = dev->data->dev_private; 32181f88049SShahed Shaikh struct ecore_dev *edev = &qdev->edev; 32274e5a25dSShahed Shaikh bool use_tx_offload = false; 32381f88049SShahed Shaikh 324a60704d1SRasesh Mody if (is_dummy) { 325*a41f593fSFerruh Yigit dev->rx_pkt_burst = rte_eth_pkt_burst_dummy; 326*a41f593fSFerruh Yigit dev->tx_pkt_burst = rte_eth_pkt_burst_dummy; 327a60704d1SRasesh Mody return; 328a60704d1SRasesh Mody } 329a60704d1SRasesh Mody 33081f88049SShahed Shaikh if (ECORE_IS_CMT(edev)) { 33181f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts_cmt; 33281f88049SShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts_cmt; 33381f88049SShahed Shaikh return; 33481f88049SShahed Shaikh } 33581f88049SShahed Shaikh 33681f88049SShahed Shaikh if (dev->data->lro || dev->data->scattered_rx) { 33781f88049SShahed Shaikh DP_INFO(edev, "Assigning qede_recv_pkts\n"); 33881f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts; 33981f88049SShahed Shaikh } else { 34081f88049SShahed Shaikh DP_INFO(edev, "Assigning qede_recv_pkts_regular\n"); 34181f88049SShahed Shaikh dev->rx_pkt_burst = qede_recv_pkts_regular; 34281f88049SShahed Shaikh } 34381f88049SShahed Shaikh 34474e5a25dSShahed Shaikh use_tx_offload = !!(tx_offloads & 345295968d1SFerruh Yigit (RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | /* tunnel */ 346295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_TCP_TSO | /* tso */ 347295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_VLAN_INSERT)); /* vlan insert */ 34874e5a25dSShahed Shaikh 34974e5a25dSShahed Shaikh if (use_tx_offload) { 35074e5a25dSShahed Shaikh DP_INFO(edev, "Assigning qede_xmit_pkts\n"); 35181f88049SShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts; 35274e5a25dSShahed Shaikh } else { 35374e5a25dSShahed Shaikh DP_INFO(edev, "Assigning qede_xmit_pkts_regular\n"); 35474e5a25dSShahed Shaikh dev->tx_pkt_burst = qede_xmit_pkts_regular; 35574e5a25dSShahed Shaikh } 35681f88049SShahed Shaikh } 35781f88049SShahed Shaikh 35881f88049SShahed Shaikh static void 3592ea6f76aSRasesh Mody qede_alloc_etherdev(struct qede_dev *qdev, struct qed_dev_eth_info *info) 3602ea6f76aSRasesh Mody { 3612ea6f76aSRasesh Mody rte_memcpy(&qdev->dev_info, info, sizeof(*info)); 3622ea6f76aSRasesh Mody qdev->ops = qed_ops; 3632ea6f76aSRasesh Mody } 3642ea6f76aSRasesh Mody 365f97b56f9SRasesh Mody static void qede_print_adapter_info(struct rte_eth_dev *dev) 3662ea6f76aSRasesh Mody { 367f97b56f9SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 3682ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 3697eca78ceSHarish Patil static char ver_str[QEDE_PMD_DRV_VER_STR_SIZE]; 3702ea6f76aSRasesh Mody 3712b5243d7SRasesh Mody DP_INFO(edev, "**************************************************\n"); 372f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "DPDK version", rte_version()); 373f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s %c%d\n", "Chip details", 3742ea6f76aSRasesh Mody ECORE_IS_BB(edev) ? "BB" : "AH", 3753818ac22SRasesh Mody 'A' + edev->chip_rev, 3763818ac22SRasesh Mody (int)edev->chip_metal); 3772b5243d7SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 3782b5243d7SRasesh Mody QEDE_PMD_DRV_VERSION); 379f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "Driver version", ver_str); 3802b5243d7SRasesh Mody snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", 3812b5243d7SRasesh Mody QEDE_PMD_BASE_VERSION); 382f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "Base version", ver_str); 383f97b56f9SRasesh Mody qede_fw_version_get(dev, ver_str, sizeof(ver_str)); 384f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "Firmware version", ver_str); 385f97b56f9SRasesh Mody DP_INFO(edev, " %-20s: %s\n", "Firmware file", qede_fw_file); 3862b5243d7SRasesh Mody DP_INFO(edev, "**************************************************\n"); 3872ea6f76aSRasesh Mody } 3882ea6f76aSRasesh Mody 389ce26be6eSRasesh Mody static void qede_reset_queue_stats(struct qede_dev *qdev, bool xstats) 390ce26be6eSRasesh Mody { 3918de0c420SShahed Shaikh struct rte_eth_dev *dev = (struct rte_eth_dev *)qdev->ethdev; 392ce26be6eSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 393ce26be6eSRasesh Mody unsigned int i = 0, j = 0, qid; 394ce26be6eSRasesh Mody unsigned int rxq_stat_cntrs, txq_stat_cntrs; 395ce26be6eSRasesh Mody struct qede_tx_queue *txq; 396ce26be6eSRasesh Mody 397ce26be6eSRasesh Mody DP_VERBOSE(edev, ECORE_MSG_DEBUG, "Clearing queue stats\n"); 398ce26be6eSRasesh Mody 3998de0c420SShahed Shaikh rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(dev), 400ce26be6eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 4018de0c420SShahed Shaikh txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(dev), 402ce26be6eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 403ce26be6eSRasesh Mody 4048de0c420SShahed Shaikh for (qid = 0; qid < qdev->num_rx_queues; qid++) { 405ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 406ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rcv_pkts), 0, 407ce26be6eSRasesh Mody sizeof(uint64_t)); 408ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 409ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rx_hw_errors), 0, 410ce26be6eSRasesh Mody sizeof(uint64_t)); 411ce26be6eSRasesh Mody OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) + 412ce26be6eSRasesh Mody offsetof(struct qede_rx_queue, rx_alloc_errors), 0, 413ce26be6eSRasesh Mody sizeof(uint64_t)); 414ce26be6eSRasesh Mody 415ce26be6eSRasesh Mody if (xstats) 416ce26be6eSRasesh Mody for (j = 0; j < RTE_DIM(qede_rxq_xstats_strings); j++) 417ce26be6eSRasesh Mody OSAL_MEMSET((((char *) 418ce26be6eSRasesh Mody (qdev->fp_array[qid].rxq)) + 419ce26be6eSRasesh Mody qede_rxq_xstats_strings[j].offset), 420ce26be6eSRasesh Mody 0, 421ce26be6eSRasesh Mody sizeof(uint64_t)); 422ce26be6eSRasesh Mody 423ce26be6eSRasesh Mody i++; 424ce26be6eSRasesh Mody if (i == rxq_stat_cntrs) 425ce26be6eSRasesh Mody break; 426ce26be6eSRasesh Mody } 427ce26be6eSRasesh Mody 428ce26be6eSRasesh Mody i = 0; 429ce26be6eSRasesh Mody 4308de0c420SShahed Shaikh for (qid = 0; qid < qdev->num_tx_queues; qid++) { 431ce26be6eSRasesh Mody txq = qdev->fp_array[qid].txq; 432ce26be6eSRasesh Mody 433ce26be6eSRasesh Mody OSAL_MEMSET((uint64_t *)(uintptr_t) 434ce26be6eSRasesh Mody (((uint64_t)(uintptr_t)(txq)) + 435ce26be6eSRasesh Mody offsetof(struct qede_tx_queue, xmit_pkts)), 0, 436ce26be6eSRasesh Mody sizeof(uint64_t)); 437ce26be6eSRasesh Mody 438ce26be6eSRasesh Mody i++; 439ce26be6eSRasesh Mody if (i == txq_stat_cntrs) 440ce26be6eSRasesh Mody break; 441ce26be6eSRasesh Mody } 442ce26be6eSRasesh Mody } 443ce26be6eSRasesh Mody 4449a6d30aeSHarish Patil static int 4459a6d30aeSHarish Patil qede_stop_vport(struct ecore_dev *edev) 4469a6d30aeSHarish Patil { 4479a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 4489a6d30aeSHarish Patil uint8_t vport_id; 4499a6d30aeSHarish Patil int rc; 4509a6d30aeSHarish Patil int i; 4519a6d30aeSHarish Patil 4529a6d30aeSHarish Patil vport_id = 0; 4539a6d30aeSHarish Patil for_each_hwfn(edev, i) { 4549a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 4559a6d30aeSHarish Patil rc = ecore_sp_vport_stop(p_hwfn, p_hwfn->hw_info.opaque_fid, 4569a6d30aeSHarish Patil vport_id); 4579a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 4589a6d30aeSHarish Patil DP_ERR(edev, "Stop V-PORT failed rc = %d\n", rc); 4599a6d30aeSHarish Patil return rc; 4609a6d30aeSHarish Patil } 4619a6d30aeSHarish Patil } 4629a6d30aeSHarish Patil 463dd28bc8cSHarish Patil DP_INFO(edev, "vport stopped\n"); 464dd28bc8cSHarish Patil 465dd28bc8cSHarish Patil return 0; 466dd28bc8cSHarish Patil } 467dd28bc8cSHarish Patil 468dd28bc8cSHarish Patil static int 469dd28bc8cSHarish Patil qede_start_vport(struct qede_dev *qdev, uint16_t mtu) 470dd28bc8cSHarish Patil { 471dd28bc8cSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 472dd28bc8cSHarish Patil struct ecore_sp_vport_start_params params; 473dd28bc8cSHarish Patil struct ecore_hwfn *p_hwfn; 474dd28bc8cSHarish Patil int rc; 475dd28bc8cSHarish Patil int i; 476dd28bc8cSHarish Patil 477dd28bc8cSHarish Patil if (qdev->vport_started) 478dd28bc8cSHarish Patil qede_stop_vport(edev); 479dd28bc8cSHarish Patil 480dd28bc8cSHarish Patil memset(¶ms, 0, sizeof(params)); 481dd28bc8cSHarish Patil params.vport_id = 0; 482dd28bc8cSHarish Patil params.mtu = mtu; 483dd28bc8cSHarish Patil /* @DPDK - Disable FW placement */ 484dd28bc8cSHarish Patil params.zero_placement_offset = 1; 485dd28bc8cSHarish Patil for_each_hwfn(edev, i) { 486dd28bc8cSHarish Patil p_hwfn = &edev->hwfns[i]; 487dd28bc8cSHarish Patil params.concrete_fid = p_hwfn->hw_info.concrete_fid; 488dd28bc8cSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 489dd28bc8cSHarish Patil rc = ecore_sp_vport_start(p_hwfn, ¶ms); 490dd28bc8cSHarish Patil if (rc != ECORE_SUCCESS) { 491dd28bc8cSHarish Patil DP_ERR(edev, "Start V-PORT failed %d\n", rc); 492dd28bc8cSHarish Patil return rc; 493dd28bc8cSHarish Patil } 494dd28bc8cSHarish Patil } 495dd28bc8cSHarish Patil ecore_reset_vport_stats(edev); 496dd28bc8cSHarish Patil qdev->vport_started = true; 497dd28bc8cSHarish Patil DP_INFO(edev, "VPORT started with MTU = %u\n", mtu); 498dd28bc8cSHarish Patil 4999a6d30aeSHarish Patil return 0; 5009a6d30aeSHarish Patil } 5019a6d30aeSHarish Patil 502612ce81bSRasesh Mody #define QEDE_NPAR_TX_SWITCHING "npar_tx_switching" 503612ce81bSRasesh Mody #define QEDE_VF_TX_SWITCHING "vf_tx_switching" 504612ce81bSRasesh Mody 5059a6d30aeSHarish Patil /* Activate or deactivate vport via vport-update */ 5069a6d30aeSHarish Patil int qede_activate_vport(struct rte_eth_dev *eth_dev, bool flg) 5079a6d30aeSHarish Patil { 5089a6d30aeSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 5099a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 5109a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 5119a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 5129a6d30aeSHarish Patil uint8_t i; 5139a6d30aeSHarish Patil int rc = -1; 5149a6d30aeSHarish Patil 5159a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 5169a6d30aeSHarish Patil params.vport_id = 0; 5179a6d30aeSHarish Patil params.update_vport_active_rx_flg = 1; 5189a6d30aeSHarish Patil params.update_vport_active_tx_flg = 1; 5199a6d30aeSHarish Patil params.vport_active_rx_flg = flg; 5209a6d30aeSHarish Patil params.vport_active_tx_flg = flg; 521d0ef40a1SDharmik Thakkar if ((qdev->enable_tx_switching == false) && (flg == true)) { 522f07aa795SHarish Patil params.update_tx_switching_flg = 1; 523f07aa795SHarish Patil params.tx_switching_flg = !flg; 524f64b91b0SRasesh Mody } 5259a6d30aeSHarish Patil for_each_hwfn(edev, i) { 5269a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 5279a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 5289a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 5299a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 5309a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 5319a6d30aeSHarish Patil DP_ERR(edev, "Failed to update vport\n"); 5329a6d30aeSHarish Patil break; 5339a6d30aeSHarish Patil } 5349a6d30aeSHarish Patil } 5351282943aSHarish Patil DP_INFO(edev, "vport is %s\n", flg ? "activated" : "deactivated"); 5361282943aSHarish Patil 5379a6d30aeSHarish Patil return rc; 5389a6d30aeSHarish Patil } 5399a6d30aeSHarish Patil 5409a6d30aeSHarish Patil static void 5419a6d30aeSHarish Patil qede_update_sge_tpa_params(struct ecore_sge_tpa_params *sge_tpa_params, 5429a6d30aeSHarish Patil uint16_t mtu, bool enable) 5439a6d30aeSHarish Patil { 5449a6d30aeSHarish Patil /* Enable LRO in split mode */ 5459a6d30aeSHarish Patil sge_tpa_params->tpa_ipv4_en_flg = enable; 5469a6d30aeSHarish Patil sge_tpa_params->tpa_ipv6_en_flg = enable; 547749d2329SHarish Patil sge_tpa_params->tpa_ipv4_tunn_en_flg = enable; 548749d2329SHarish Patil sge_tpa_params->tpa_ipv6_tunn_en_flg = enable; 5499a6d30aeSHarish Patil /* set if tpa enable changes */ 5509a6d30aeSHarish Patil sge_tpa_params->update_tpa_en_flg = 1; 5519a6d30aeSHarish Patil /* set if tpa parameters should be handled */ 5529a6d30aeSHarish Patil sge_tpa_params->update_tpa_param_flg = enable; 5539a6d30aeSHarish Patil 5549a6d30aeSHarish Patil sge_tpa_params->max_buffers_per_cqe = 20; 5559a6d30aeSHarish Patil /* Enable TPA in split mode. In this mode each TPA segment 5569a6d30aeSHarish Patil * starts on the new BD, so there is one BD per segment. 5579a6d30aeSHarish Patil */ 5589a6d30aeSHarish Patil sge_tpa_params->tpa_pkt_split_flg = 1; 5599a6d30aeSHarish Patil sge_tpa_params->tpa_hdr_data_split_flg = 0; 5609a6d30aeSHarish Patil sge_tpa_params->tpa_gro_consistent_flg = 0; 5619a6d30aeSHarish Patil sge_tpa_params->tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM; 5629a6d30aeSHarish Patil sge_tpa_params->tpa_max_size = 0x7FFF; 5639a6d30aeSHarish Patil sge_tpa_params->tpa_min_size_to_start = mtu / 2; 5649a6d30aeSHarish Patil sge_tpa_params->tpa_min_size_to_cont = mtu / 2; 5659a6d30aeSHarish Patil } 5669a6d30aeSHarish Patil 5679a6d30aeSHarish Patil /* Enable/disable LRO via vport-update */ 5689a6d30aeSHarish Patil int qede_enable_tpa(struct rte_eth_dev *eth_dev, bool flg) 5699a6d30aeSHarish Patil { 5709a6d30aeSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 5719a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 5729a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 5739a6d30aeSHarish Patil struct ecore_sge_tpa_params tpa_params; 5749a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 5759a6d30aeSHarish Patil int rc; 5769a6d30aeSHarish Patil int i; 5779a6d30aeSHarish Patil 5789a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 5799a6d30aeSHarish Patil memset(&tpa_params, 0, sizeof(struct ecore_sge_tpa_params)); 5809a6d30aeSHarish Patil qede_update_sge_tpa_params(&tpa_params, qdev->mtu, flg); 5819a6d30aeSHarish Patil params.vport_id = 0; 5829a6d30aeSHarish Patil params.sge_tpa_params = &tpa_params; 5839a6d30aeSHarish Patil for_each_hwfn(edev, i) { 5849a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 5859a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 5869a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 5879a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 5889a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 5899a6d30aeSHarish Patil DP_ERR(edev, "Failed to update LRO\n"); 5909a6d30aeSHarish Patil return -1; 5919a6d30aeSHarish Patil } 5929a6d30aeSHarish Patil } 593daee4e07SHarish Patil qdev->enable_lro = flg; 594946dfd18SHarish Patil eth_dev->data->lro = flg; 595946dfd18SHarish Patil 5969a6d30aeSHarish Patil DP_INFO(edev, "LRO is %s\n", flg ? "enabled" : "disabled"); 5979a6d30aeSHarish Patil 5989a6d30aeSHarish Patil return 0; 5999a6d30aeSHarish Patil } 6009a6d30aeSHarish Patil 6014c4bdadfSHarish Patil static int 6024c4bdadfSHarish Patil qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev, 6034c4bdadfSHarish Patil enum qed_filter_rx_mode_type type) 6044c4bdadfSHarish Patil { 6054c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 6064c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 6074c4bdadfSHarish Patil struct ecore_filter_accept_flags flags; 6084c4bdadfSHarish Patil 6094c4bdadfSHarish Patil memset(&flags, 0, sizeof(flags)); 6104c4bdadfSHarish Patil 6114c4bdadfSHarish Patil flags.update_rx_mode_config = 1; 6124c4bdadfSHarish Patil flags.update_tx_mode_config = 1; 6134c4bdadfSHarish Patil flags.rx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 6144c4bdadfSHarish Patil ECORE_ACCEPT_MCAST_MATCHED | 6154c4bdadfSHarish Patil ECORE_ACCEPT_BCAST; 6164c4bdadfSHarish Patil 6174c4bdadfSHarish Patil flags.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 6184c4bdadfSHarish Patil ECORE_ACCEPT_MCAST_MATCHED | 6194c4bdadfSHarish Patil ECORE_ACCEPT_BCAST; 6204c4bdadfSHarish Patil 6214c4bdadfSHarish Patil if (type == QED_FILTER_RX_MODE_TYPE_PROMISC) { 622b10231aeSDevendra Singh Rawat flags.rx_accept_filter |= (ECORE_ACCEPT_UCAST_UNMATCHED | 623b10231aeSDevendra Singh Rawat ECORE_ACCEPT_MCAST_UNMATCHED); 6244c4bdadfSHarish Patil if (IS_VF(edev)) { 625b10231aeSDevendra Singh Rawat flags.tx_accept_filter |= 626b10231aeSDevendra Singh Rawat (ECORE_ACCEPT_UCAST_UNMATCHED | 627b10231aeSDevendra Singh Rawat ECORE_ACCEPT_MCAST_UNMATCHED); 628b10231aeSDevendra Singh Rawat DP_INFO(edev, "Enabling Tx unmatched flags for VF\n"); 6294c4bdadfSHarish Patil } 6304c4bdadfSHarish Patil } else if (type == QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC) { 6314c4bdadfSHarish Patil flags.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 6324c4bdadfSHarish Patil } 6334c4bdadfSHarish Patil 6344c4bdadfSHarish Patil return ecore_filter_accept_cmd(edev, 0, flags, false, false, 6354c4bdadfSHarish Patil ECORE_SPQ_MODE_CB, NULL); 6364c4bdadfSHarish Patil } 637e0947ed9SHarish Patil 638eb54ba75SShahed Shaikh int 63977fac1b5SHarish Patil qede_ucast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast, 64077fac1b5SHarish Patil bool add) 64177fac1b5SHarish Patil { 64277fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 64377fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 64477fac1b5SHarish Patil struct qede_ucast_entry *tmp = NULL; 64577fac1b5SHarish Patil struct qede_ucast_entry *u; 6466d13ea8eSOlivier Matz struct rte_ether_addr *mac_addr; 64777fac1b5SHarish Patil 6486d13ea8eSOlivier Matz mac_addr = (struct rte_ether_addr *)ucast->mac; 64977fac1b5SHarish Patil if (add) { 65077fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->uc_list_head, list) { 65177fac1b5SHarish Patil if ((memcmp(mac_addr, &tmp->mac, 65235b2d13fSOlivier Matz RTE_ETHER_ADDR_LEN) == 0) && 653d2a2468eSRasesh Mody ucast->vni == tmp->vni && 65477fac1b5SHarish Patil ucast->vlan == tmp->vlan) { 655f8d2581eSShahed Shaikh DP_INFO(edev, "Unicast MAC is already added" 65677fac1b5SHarish Patil " with vlan = %u, vni = %u\n", 65777fac1b5SHarish Patil ucast->vlan, ucast->vni); 658f8d2581eSShahed Shaikh return 0; 65977fac1b5SHarish Patil } 66077fac1b5SHarish Patil } 66177fac1b5SHarish Patil u = rte_malloc(NULL, sizeof(struct qede_ucast_entry), 66277fac1b5SHarish Patil RTE_CACHE_LINE_SIZE); 66377fac1b5SHarish Patil if (!u) { 66477fac1b5SHarish Patil DP_ERR(edev, "Did not allocate memory for ucast\n"); 66577fac1b5SHarish Patil return -ENOMEM; 66677fac1b5SHarish Patil } 667538da7a1SOlivier Matz rte_ether_addr_copy(mac_addr, &u->mac); 66877fac1b5SHarish Patil u->vlan = ucast->vlan; 66952d94b57SHarish Patil u->vni = ucast->vni; 67077fac1b5SHarish Patil SLIST_INSERT_HEAD(&qdev->uc_list_head, u, list); 67177fac1b5SHarish Patil qdev->num_uc_addr++; 67277fac1b5SHarish Patil } else { 67377fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->uc_list_head, list) { 67477fac1b5SHarish Patil if ((memcmp(mac_addr, &tmp->mac, 67535b2d13fSOlivier Matz RTE_ETHER_ADDR_LEN) == 0) && 67652d94b57SHarish Patil ucast->vlan == tmp->vlan && 67752d94b57SHarish Patil ucast->vni == tmp->vni) 67877fac1b5SHarish Patil break; 67977fac1b5SHarish Patil } 68077fac1b5SHarish Patil if (tmp == NULL) { 68177fac1b5SHarish Patil DP_INFO(edev, "Unicast MAC is not found\n"); 68277fac1b5SHarish Patil return -EINVAL; 68377fac1b5SHarish Patil } 68477fac1b5SHarish Patil SLIST_REMOVE(&qdev->uc_list_head, tmp, qede_ucast_entry, list); 68577fac1b5SHarish Patil qdev->num_uc_addr--; 68677fac1b5SHarish Patil } 68777fac1b5SHarish Patil 68877fac1b5SHarish Patil return 0; 68977fac1b5SHarish Patil } 69077fac1b5SHarish Patil 69177fac1b5SHarish Patil static int 6926d13ea8eSOlivier Matz qede_add_mcast_filters(struct rte_eth_dev *eth_dev, 6936d13ea8eSOlivier Matz struct rte_ether_addr *mc_addrs, 694413ecf29SHarish Patil uint32_t mc_addrs_num) 69577fac1b5SHarish Patil { 69677fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 69777fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 698413ecf29SHarish Patil struct ecore_filter_mcast mcast; 699413ecf29SHarish Patil struct qede_mcast_entry *m = NULL; 700413ecf29SHarish Patil uint8_t i; 701413ecf29SHarish Patil int rc; 70277fac1b5SHarish Patil 703413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) { 70477fac1b5SHarish Patil m = rte_malloc(NULL, sizeof(struct qede_mcast_entry), 70577fac1b5SHarish Patil RTE_CACHE_LINE_SIZE); 70677fac1b5SHarish Patil if (!m) { 707413ecf29SHarish Patil DP_ERR(edev, "Did not allocate memory for mcast\n"); 70877fac1b5SHarish Patil return -ENOMEM; 70977fac1b5SHarish Patil } 710538da7a1SOlivier Matz rte_ether_addr_copy(&mc_addrs[i], &m->mac); 71177fac1b5SHarish Patil SLIST_INSERT_HEAD(&qdev->mc_list_head, m, list); 712413ecf29SHarish Patil } 713413ecf29SHarish Patil memset(&mcast, 0, sizeof(mcast)); 714413ecf29SHarish Patil mcast.num_mc_addrs = mc_addrs_num; 715413ecf29SHarish Patil mcast.opcode = ECORE_FILTER_ADD; 716413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) 717538da7a1SOlivier Matz rte_ether_addr_copy(&mc_addrs[i], (struct rte_ether_addr *) 718413ecf29SHarish Patil &mcast.mac[i]); 719413ecf29SHarish Patil rc = ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL); 720413ecf29SHarish Patil if (rc != ECORE_SUCCESS) { 721413ecf29SHarish Patil DP_ERR(edev, "Failed to add multicast filter (rc = %d\n)", rc); 722413ecf29SHarish Patil return -1; 723413ecf29SHarish Patil } 724413ecf29SHarish Patil 725413ecf29SHarish Patil return 0; 726413ecf29SHarish Patil } 727413ecf29SHarish Patil 728413ecf29SHarish Patil static int qede_del_mcast_filters(struct rte_eth_dev *eth_dev) 729413ecf29SHarish Patil { 730413ecf29SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 731413ecf29SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 732413ecf29SHarish Patil struct qede_mcast_entry *tmp = NULL; 733413ecf29SHarish Patil struct ecore_filter_mcast mcast; 734413ecf29SHarish Patil int j; 735413ecf29SHarish Patil int rc; 736413ecf29SHarish Patil 737413ecf29SHarish Patil memset(&mcast, 0, sizeof(mcast)); 738413ecf29SHarish Patil mcast.num_mc_addrs = qdev->num_mc_addr; 739413ecf29SHarish Patil mcast.opcode = ECORE_FILTER_REMOVE; 740413ecf29SHarish Patil j = 0; 74177fac1b5SHarish Patil SLIST_FOREACH(tmp, &qdev->mc_list_head, list) { 742538da7a1SOlivier Matz rte_ether_addr_copy(&tmp->mac, 7436d13ea8eSOlivier Matz (struct rte_ether_addr *)&mcast.mac[j]); 744413ecf29SHarish Patil j++; 74577fac1b5SHarish Patil } 746413ecf29SHarish Patil rc = ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL); 747413ecf29SHarish Patil if (rc != ECORE_SUCCESS) { 748413ecf29SHarish Patil DP_ERR(edev, "Failed to delete multicast filter\n"); 749413ecf29SHarish Patil return -1; 75077fac1b5SHarish Patil } 751413ecf29SHarish Patil /* Init the list */ 752413ecf29SHarish Patil while (!SLIST_EMPTY(&qdev->mc_list_head)) { 753413ecf29SHarish Patil tmp = SLIST_FIRST(&qdev->mc_list_head); 754413ecf29SHarish Patil SLIST_REMOVE_HEAD(&qdev->mc_list_head, list); 75577fac1b5SHarish Patil } 756413ecf29SHarish Patil SLIST_INIT(&qdev->mc_list_head); 75777fac1b5SHarish Patil 75877fac1b5SHarish Patil return 0; 75977fac1b5SHarish Patil } 76077fac1b5SHarish Patil 761eb54ba75SShahed Shaikh enum _ecore_status_t 76277fac1b5SHarish Patil qede_mac_int_ops(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast, 76377fac1b5SHarish Patil bool add) 76477fac1b5SHarish Patil { 76577fac1b5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 76677fac1b5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 767413ecf29SHarish Patil enum _ecore_status_t rc = ECORE_INVAL; 76877fac1b5SHarish Patil 769413ecf29SHarish Patil if (add && (qdev->num_uc_addr >= qdev->dev_info.num_mac_filters)) { 770413ecf29SHarish Patil DP_ERR(edev, "Ucast filter table limit exceeded," 77177fac1b5SHarish Patil " Please enable promisc mode\n"); 772413ecf29SHarish Patil return ECORE_INVAL; 77377fac1b5SHarish Patil } 774413ecf29SHarish Patil 77577fac1b5SHarish Patil rc = qede_ucast_filter(eth_dev, ucast, add); 77677fac1b5SHarish Patil if (rc == 0) 77777fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, ucast, 77877fac1b5SHarish Patil ECORE_SPQ_MODE_CB, NULL); 7797e3060a3SShahed Shaikh /* Indicate error only for add filter operation. 7807e3060a3SShahed Shaikh * Delete filter operations are not severe. 7817e3060a3SShahed Shaikh */ 7827e3060a3SShahed Shaikh if ((rc != ECORE_SUCCESS) && add) 78377fac1b5SHarish Patil DP_ERR(edev, "MAC filter failed, rc = %d, op = %d\n", 78477fac1b5SHarish Patil rc, add); 78577fac1b5SHarish Patil 78677fac1b5SHarish Patil return rc; 7872ea6f76aSRasesh Mody } 7882ea6f76aSRasesh Mody 7896d01e580SWei Dai static int 7906d13ea8eSOlivier Matz qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr, 791af785e47SRasesh Mody __rte_unused uint32_t index, __rte_unused uint32_t pool) 7922ea6f76aSRasesh Mody { 79377fac1b5SHarish Patil struct ecore_filter_ucast ucast; 7946d01e580SWei Dai int re; 7952ea6f76aSRasesh Mody 796538da7a1SOlivier Matz if (!rte_is_valid_assigned_ether_addr(mac_addr)) 797c7641841SShahed Shaikh return -EINVAL; 798c7641841SShahed Shaikh 79977fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 800c7641841SShahed Shaikh ucast.opcode = ECORE_FILTER_ADD; 80177fac1b5SHarish Patil ucast.type = ECORE_FILTER_MAC; 802538da7a1SOlivier Matz rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)&ucast.mac); 8036d01e580SWei Dai re = (int)qede_mac_int_ops(eth_dev, &ucast, 1); 8046d01e580SWei Dai return re; 8052ea6f76aSRasesh Mody } 8062ea6f76aSRasesh Mody 8072ea6f76aSRasesh Mody static void 8082ea6f76aSRasesh Mody qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index) 8092ea6f76aSRasesh Mody { 8102ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 8112ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 81277fac1b5SHarish Patil struct ecore_filter_ucast ucast; 8132ea6f76aSRasesh Mody 8142ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 8152ea6f76aSRasesh Mody 8163320ca8cSRasesh Mody if (index >= qdev->dev_info.num_mac_filters) { 8172ea6f76aSRasesh Mody DP_ERR(edev, "Index %u is above MAC filter limit %u\n", 8183320ca8cSRasesh Mody index, qdev->dev_info.num_mac_filters); 8192ea6f76aSRasesh Mody return; 8202ea6f76aSRasesh Mody } 8212ea6f76aSRasesh Mody 822538da7a1SOlivier Matz if (!rte_is_valid_assigned_ether_addr(ð_dev->data->mac_addrs[index])) 823c7641841SShahed Shaikh return; 824c7641841SShahed Shaikh 82577fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 82677fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_REMOVE; 82777fac1b5SHarish Patil ucast.type = ECORE_FILTER_MAC; 82877fac1b5SHarish Patil 8292ea6f76aSRasesh Mody /* Use the index maintained by rte */ 830538da7a1SOlivier Matz rte_ether_addr_copy(ð_dev->data->mac_addrs[index], 8316d13ea8eSOlivier Matz (struct rte_ether_addr *)&ucast.mac); 83277fac1b5SHarish Patil 83383ade1ebSRasesh Mody qede_mac_int_ops(eth_dev, &ucast, false); 8342ea6f76aSRasesh Mody } 8352ea6f76aSRasesh Mody 836caccf8b3SOlivier Matz static int 8376d13ea8eSOlivier Matz qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr) 8382ea6f76aSRasesh Mody { 8392ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 8402ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8412ea6f76aSRasesh Mody 84286a2265eSRasesh Mody if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev), 84386a2265eSRasesh Mody mac_addr->addr_bytes)) { 84486a2265eSRasesh Mody DP_ERR(edev, "Setting MAC address is not allowed\n"); 845caccf8b3SOlivier Matz return -EPERM; 84686a2265eSRasesh Mody } 84786a2265eSRasesh Mody 848c7641841SShahed Shaikh qede_mac_addr_remove(eth_dev, 0); 849c7641841SShahed Shaikh 850c7641841SShahed Shaikh return qede_mac_addr_add(eth_dev, mac_addr, 0, 0); 8512ea6f76aSRasesh Mody } 8522ea6f76aSRasesh Mody 853eb54ba75SShahed Shaikh void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg) 8542ea6f76aSRasesh Mody { 8559a6d30aeSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8569a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 8579a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 8589a6d30aeSHarish Patil uint8_t i; 8592ea6f76aSRasesh Mody int rc; 8602ea6f76aSRasesh Mody 8619a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 8629a6d30aeSHarish Patil params.vport_id = 0; 8639a6d30aeSHarish Patil params.update_accept_any_vlan_flg = 1; 8649a6d30aeSHarish Patil params.accept_any_vlan = flg; 8659a6d30aeSHarish Patil for_each_hwfn(edev, i) { 8669a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 8679a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 8689a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 8699a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 8709a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 8719a6d30aeSHarish Patil DP_ERR(edev, "Failed to configure accept-any-vlan\n"); 8722ea6f76aSRasesh Mody return; 8732ea6f76aSRasesh Mody } 8742ea6f76aSRasesh Mody } 8752ea6f76aSRasesh Mody 8769a6d30aeSHarish Patil DP_INFO(edev, "%s accept-any-vlan\n", flg ? "enabled" : "disabled"); 8779a6d30aeSHarish Patil } 8789a6d30aeSHarish Patil 8799a6d30aeSHarish Patil static int qede_vlan_stripping(struct rte_eth_dev *eth_dev, bool flg) 8802ea6f76aSRasesh Mody { 8812ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 8822ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 8839a6d30aeSHarish Patil struct ecore_sp_vport_update_params params; 8849a6d30aeSHarish Patil struct ecore_hwfn *p_hwfn; 8859a6d30aeSHarish Patil uint8_t i; 8862ea6f76aSRasesh Mody int rc; 8872ea6f76aSRasesh Mody 8889a6d30aeSHarish Patil memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 8899a6d30aeSHarish Patil params.vport_id = 0; 8909a6d30aeSHarish Patil params.update_inner_vlan_removal_flg = 1; 8919a6d30aeSHarish Patil params.inner_vlan_removal_flg = flg; 8929a6d30aeSHarish Patil for_each_hwfn(edev, i) { 8939a6d30aeSHarish Patil p_hwfn = &edev->hwfns[i]; 8949a6d30aeSHarish Patil params.opaque_fid = p_hwfn->hw_info.opaque_fid; 8959a6d30aeSHarish Patil rc = ecore_sp_vport_update(p_hwfn, ¶ms, 8969a6d30aeSHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 8979a6d30aeSHarish Patil if (rc != ECORE_SUCCESS) { 8989a6d30aeSHarish Patil DP_ERR(edev, "Failed to update vport\n"); 8999a6d30aeSHarish Patil return -1; 9002ea6f76aSRasesh Mody } 9019a6d30aeSHarish Patil } 9022ea6f76aSRasesh Mody 90330b170b4SShahed Shaikh qdev->vlan_strip_flg = flg; 90430b170b4SShahed Shaikh 9059a6d30aeSHarish Patil DP_INFO(edev, "VLAN stripping %s\n", flg ? "enabled" : "disabled"); 9062ea6f76aSRasesh Mody return 0; 9072ea6f76aSRasesh Mody } 9082ea6f76aSRasesh Mody 9092ea6f76aSRasesh Mody static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev, 9102ea6f76aSRasesh Mody uint16_t vlan_id, int on) 9112ea6f76aSRasesh Mody { 9122ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 9132ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 9142ea6f76aSRasesh Mody struct qed_dev_eth_info *dev_info = &qdev->dev_info; 915d6cb1753SHarish Patil struct qede_vlan_entry *tmp = NULL; 916d6cb1753SHarish Patil struct qede_vlan_entry *vlan; 91777fac1b5SHarish Patil struct ecore_filter_ucast ucast; 9182ea6f76aSRasesh Mody int rc; 9192ea6f76aSRasesh Mody 920bec02288SSony Chacko if (on) { 921d6cb1753SHarish Patil if (qdev->configured_vlans == dev_info->num_vlan_filters) { 92261a8429fSRasesh Mody DP_ERR(edev, "Reached max VLAN filter limit" 9232ea6f76aSRasesh Mody " enabling accept_any_vlan\n"); 9242ea6f76aSRasesh Mody qede_config_accept_any_vlan(qdev, true); 9252ea6f76aSRasesh Mody return 0; 9262ea6f76aSRasesh Mody } 9272ea6f76aSRasesh Mody 928d6cb1753SHarish Patil SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) { 929d6cb1753SHarish Patil if (tmp->vid == vlan_id) { 930f8d2581eSShahed Shaikh DP_INFO(edev, "VLAN %u already configured\n", 9312ea6f76aSRasesh Mody vlan_id); 932f8d2581eSShahed Shaikh return 0; 933d6cb1753SHarish Patil } 9342ea6f76aSRasesh Mody } 9352ea6f76aSRasesh Mody 936d6cb1753SHarish Patil vlan = rte_malloc(NULL, sizeof(struct qede_vlan_entry), 937d6cb1753SHarish Patil RTE_CACHE_LINE_SIZE); 938d6cb1753SHarish Patil 939d6cb1753SHarish Patil if (!vlan) { 940d6cb1753SHarish Patil DP_ERR(edev, "Did not allocate memory for VLAN\n"); 941d6cb1753SHarish Patil return -ENOMEM; 942d6cb1753SHarish Patil } 943d6cb1753SHarish Patil 94477fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 94577fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_ADD; 94677fac1b5SHarish Patil ucast.type = ECORE_FILTER_VLAN; 94777fac1b5SHarish Patil ucast.vlan = vlan_id; 94877fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, 94977fac1b5SHarish Patil NULL); 95077fac1b5SHarish Patil if (rc != 0) { 951d6cb1753SHarish Patil DP_ERR(edev, "Failed to add VLAN %u rc %d\n", vlan_id, 952d6cb1753SHarish Patil rc); 953d6cb1753SHarish Patil rte_free(vlan); 954d6cb1753SHarish Patil } else { 955d6cb1753SHarish Patil vlan->vid = vlan_id; 956d6cb1753SHarish Patil SLIST_INSERT_HEAD(&qdev->vlan_list_head, vlan, list); 957d6cb1753SHarish Patil qdev->configured_vlans++; 958d6cb1753SHarish Patil DP_INFO(edev, "VLAN %u added, configured_vlans %u\n", 959d6cb1753SHarish Patil vlan_id, qdev->configured_vlans); 960d6cb1753SHarish Patil } 961d6cb1753SHarish Patil } else { 962d6cb1753SHarish Patil SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) { 963d6cb1753SHarish Patil if (tmp->vid == vlan_id) 964d6cb1753SHarish Patil break; 965d6cb1753SHarish Patil } 966d6cb1753SHarish Patil 967d6cb1753SHarish Patil if (!tmp) { 968d6cb1753SHarish Patil if (qdev->configured_vlans == 0) { 969d6cb1753SHarish Patil DP_INFO(edev, 970d6cb1753SHarish Patil "No VLAN filters configured yet\n"); 971d6cb1753SHarish Patil return 0; 972d6cb1753SHarish Patil } 973d6cb1753SHarish Patil 974d6cb1753SHarish Patil DP_ERR(edev, "VLAN %u not configured\n", vlan_id); 975d6cb1753SHarish Patil return -EINVAL; 976d6cb1753SHarish Patil } 977d6cb1753SHarish Patil 978d6cb1753SHarish Patil SLIST_REMOVE(&qdev->vlan_list_head, tmp, qede_vlan_entry, list); 979d6cb1753SHarish Patil 98077fac1b5SHarish Patil qede_set_ucast_cmn_params(&ucast); 98177fac1b5SHarish Patil ucast.opcode = ECORE_FILTER_REMOVE; 98277fac1b5SHarish Patil ucast.type = ECORE_FILTER_VLAN; 98377fac1b5SHarish Patil ucast.vlan = vlan_id; 98477fac1b5SHarish Patil rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, 98577fac1b5SHarish Patil NULL); 98677fac1b5SHarish Patil if (rc != 0) { 987d6cb1753SHarish Patil DP_ERR(edev, "Failed to delete VLAN %u rc %d\n", 988d6cb1753SHarish Patil vlan_id, rc); 989d6cb1753SHarish Patil } else { 990d6cb1753SHarish Patil qdev->configured_vlans--; 991d6cb1753SHarish Patil DP_INFO(edev, "VLAN %u removed configured_vlans %u\n", 992d6cb1753SHarish Patil vlan_id, qdev->configured_vlans); 993d6cb1753SHarish Patil } 994d6cb1753SHarish Patil } 9952ea6f76aSRasesh Mody 9962ea6f76aSRasesh Mody return rc; 9972ea6f76aSRasesh Mody } 9982ea6f76aSRasesh Mody 999289ba0c0SDavid Harton static int qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) 1000af785e47SRasesh Mody { 1001af785e47SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1002af785e47SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1003946dfd18SHarish Patil uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; 1004af785e47SRasesh Mody 1005295968d1SFerruh Yigit if (mask & RTE_ETH_VLAN_STRIP_MASK) { 1006295968d1SFerruh Yigit if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) 1007af785e47SRasesh Mody (void)qede_vlan_stripping(eth_dev, 1); 1008af785e47SRasesh Mody else 1009af785e47SRasesh Mody (void)qede_vlan_stripping(eth_dev, 0); 1010af785e47SRasesh Mody } 1011af785e47SRasesh Mody 1012295968d1SFerruh Yigit if (mask & RTE_ETH_VLAN_FILTER_MASK) { 1013af785e47SRasesh Mody /* VLAN filtering kicks in when a VLAN is added */ 1014295968d1SFerruh Yigit if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) { 1015af785e47SRasesh Mody qede_vlan_filter_set(eth_dev, 0, 1); 1016af785e47SRasesh Mody } else { 1017af785e47SRasesh Mody if (qdev->configured_vlans > 1) { /* Excluding VLAN0 */ 1018af785e47SRasesh Mody DP_ERR(edev, 1019af785e47SRasesh Mody " Please remove existing VLAN filters" 1020af785e47SRasesh Mody " before disabling VLAN filtering\n"); 1021af785e47SRasesh Mody /* Signal app that VLAN filtering is still 1022af785e47SRasesh Mody * enabled 1023af785e47SRasesh Mody */ 1024946dfd18SHarish Patil eth_dev->data->dev_conf.rxmode.offloads |= 1025295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_FILTER; 1026af785e47SRasesh Mody } else { 1027af785e47SRasesh Mody qede_vlan_filter_set(eth_dev, 0, 0); 1028af785e47SRasesh Mody } 1029af785e47SRasesh Mody } 1030af785e47SRasesh Mody } 1031af785e47SRasesh Mody 1032dd28bc8cSHarish Patil qdev->vlan_offload_mask = mask; 1033dd28bc8cSHarish Patil 1034946dfd18SHarish Patil DP_INFO(edev, "VLAN offload mask %d\n", mask); 1035289ba0c0SDavid Harton 1036289ba0c0SDavid Harton return 0; 1037af785e47SRasesh Mody } 1038af785e47SRasesh Mody 10397ab35bf6SHarish Patil static void qede_prandom_bytes(uint32_t *buff) 10407ab35bf6SHarish Patil { 10417ab35bf6SHarish Patil uint8_t i; 10427ab35bf6SHarish Patil 10437ab35bf6SHarish Patil srand((unsigned int)time(NULL)); 10447ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_KEY_SIZE; i++) 10457ab35bf6SHarish Patil buff[i] = rand(); 10467ab35bf6SHarish Patil } 10477ab35bf6SHarish Patil 10488130abb3SHarish Patil int qede_config_rss(struct rte_eth_dev *eth_dev) 10497ab35bf6SHarish Patil { 10507ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 10517ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 10527ab35bf6SHarish Patil uint32_t def_rss_key[ECORE_RSS_KEY_SIZE]; 10537ab35bf6SHarish Patil struct rte_eth_rss_reta_entry64 reta_conf[2]; 10547ab35bf6SHarish Patil struct rte_eth_rss_conf rss_conf; 10557ab35bf6SHarish Patil uint32_t i, id, pos, q; 10567ab35bf6SHarish Patil 10577ab35bf6SHarish Patil rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf; 10587ab35bf6SHarish Patil if (!rss_conf.rss_key) { 10597ab35bf6SHarish Patil DP_INFO(edev, "Applying driver default key\n"); 10607ab35bf6SHarish Patil rss_conf.rss_key_len = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); 10617ab35bf6SHarish Patil qede_prandom_bytes(&def_rss_key[0]); 10627ab35bf6SHarish Patil rss_conf.rss_key = (uint8_t *)&def_rss_key[0]; 10637ab35bf6SHarish Patil } 10647ab35bf6SHarish Patil 10657ab35bf6SHarish Patil /* Configure RSS hash */ 10667ab35bf6SHarish Patil if (qede_rss_hash_update(eth_dev, &rss_conf)) 10677ab35bf6SHarish Patil return -EINVAL; 10687ab35bf6SHarish Patil 10697ab35bf6SHarish Patil /* Configure default RETA */ 10707ab35bf6SHarish Patil memset(reta_conf, 0, sizeof(reta_conf)); 10717ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) 1072295968d1SFerruh Yigit reta_conf[i / RTE_ETH_RETA_GROUP_SIZE].mask = UINT64_MAX; 10737ab35bf6SHarish Patil 10747ab35bf6SHarish Patil for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) { 1075295968d1SFerruh Yigit id = i / RTE_ETH_RETA_GROUP_SIZE; 1076295968d1SFerruh Yigit pos = i % RTE_ETH_RETA_GROUP_SIZE; 10778de0c420SShahed Shaikh q = i % QEDE_RSS_COUNT(eth_dev); 10787ab35bf6SHarish Patil reta_conf[id].reta[pos] = q; 10797ab35bf6SHarish Patil } 10807ab35bf6SHarish Patil if (qede_rss_reta_update(eth_dev, &reta_conf[0], 10817ab35bf6SHarish Patil ECORE_RSS_IND_TABLE_SIZE)) 10827ab35bf6SHarish Patil return -EINVAL; 10837ab35bf6SHarish Patil 10847ab35bf6SHarish Patil return 0; 10857ab35bf6SHarish Patil } 10867ab35bf6SHarish Patil 10874c4bdadfSHarish Patil static void qede_fastpath_start(struct ecore_dev *edev) 10884c4bdadfSHarish Patil { 10894c4bdadfSHarish Patil struct ecore_hwfn *p_hwfn; 10904c4bdadfSHarish Patil int i; 10914c4bdadfSHarish Patil 10924c4bdadfSHarish Patil for_each_hwfn(edev, i) { 10934c4bdadfSHarish Patil p_hwfn = &edev->hwfns[i]; 10944c4bdadfSHarish Patil ecore_hw_start_fastpath(p_hwfn); 10954c4bdadfSHarish Patil } 10964c4bdadfSHarish Patil } 10974c4bdadfSHarish Patil 10984c4bdadfSHarish Patil static int qede_dev_start(struct rte_eth_dev *eth_dev) 10994c4bdadfSHarish Patil { 11004c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 11014c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1102946dfd18SHarish Patil struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode; 11034c4bdadfSHarish Patil 11044c4bdadfSHarish Patil PMD_INIT_FUNC_TRACE(edev); 11054c4bdadfSHarish Patil 1106d121a6b5SRasesh Mody /* Update MTU only if it has changed */ 110729bb154fSShahed Shaikh if (qdev->new_mtu && qdev->new_mtu != qdev->mtu) { 110829bb154fSShahed Shaikh if (qede_update_mtu(eth_dev, qdev->new_mtu)) 1109d121a6b5SRasesh Mody goto err; 111029bb154fSShahed Shaikh qdev->mtu = qdev->new_mtu; 111129bb154fSShahed Shaikh qdev->new_mtu = 0; 1112d121a6b5SRasesh Mody } 1113d121a6b5SRasesh Mody 1114daee4e07SHarish Patil /* Configure TPA parameters */ 1115295968d1SFerruh Yigit if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) { 11164c4bdadfSHarish Patil if (qede_enable_tpa(eth_dev, true)) 1117daee4e07SHarish Patil return -EINVAL; 1118daee4e07SHarish Patil /* Enable scatter mode for LRO */ 1119946dfd18SHarish Patil if (!eth_dev->data->scattered_rx) 1120295968d1SFerruh Yigit rxmode->offloads |= RTE_ETH_RX_OFFLOAD_SCATTER; 11214c4bdadfSHarish Patil } 11224c4bdadfSHarish Patil 11234c4bdadfSHarish Patil /* Start queues */ 11244c4bdadfSHarish Patil if (qede_start_queues(eth_dev)) 11254c4bdadfSHarish Patil goto err; 11264c4bdadfSHarish Patil 1127dd28bc8cSHarish Patil if (IS_PF(edev)) 1128dd28bc8cSHarish Patil qede_reset_queue_stats(qdev, true); 1129dd28bc8cSHarish Patil 11304c4bdadfSHarish Patil /* Newer SR-IOV PF driver expects RX/TX queues to be started before 11314c4bdadfSHarish Patil * enabling RSS. Hence RSS configuration is deferred up to this point. 11324c4bdadfSHarish Patil * Also, we would like to retain similar behavior in PF case, so we 11334c4bdadfSHarish Patil * don't do PF/VF specific check here. 11344c4bdadfSHarish Patil */ 1135295968d1SFerruh Yigit if (eth_dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_RSS) 11364c4bdadfSHarish Patil if (qede_config_rss(eth_dev)) 11374c4bdadfSHarish Patil goto err; 11384c4bdadfSHarish Patil 11394c4bdadfSHarish Patil /* Enable vport*/ 11404c4bdadfSHarish Patil if (qede_activate_vport(eth_dev, true)) 11414c4bdadfSHarish Patil goto err; 11424c4bdadfSHarish Patil 1143d7897058SRasesh Mody /* Bring-up the link */ 1144d7897058SRasesh Mody qede_dev_set_link_state(eth_dev, true); 1145d7897058SRasesh Mody 11468aab5d6fSRasesh Mody /* Update link status */ 11478aab5d6fSRasesh Mody qede_link_update(eth_dev, 0); 11488aab5d6fSRasesh Mody 11494c4bdadfSHarish Patil /* Start/resume traffic */ 11504c4bdadfSHarish Patil qede_fastpath_start(edev); 11514c4bdadfSHarish Patil 1152a60704d1SRasesh Mody /* Assign I/O handlers */ 1153a60704d1SRasesh Mody qede_assign_rxtx_handlers(eth_dev, false); 1154a60704d1SRasesh Mody 11554c4bdadfSHarish Patil DP_INFO(edev, "Device started\n"); 11564c4bdadfSHarish Patil 11574c4bdadfSHarish Patil return 0; 11584c4bdadfSHarish Patil err: 11594c4bdadfSHarish Patil DP_ERR(edev, "Device start fails\n"); 11604c4bdadfSHarish Patil return -1; /* common error code is < 0 */ 11614c4bdadfSHarish Patil } 11624c4bdadfSHarish Patil 116362024eb8SIvan Ilchenko static int qede_dev_stop(struct rte_eth_dev *eth_dev) 11644c4bdadfSHarish Patil { 11654c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 11664c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 11674c4bdadfSHarish Patil 11684c4bdadfSHarish Patil PMD_INIT_FUNC_TRACE(edev); 1169b8f5d2aeSThomas Monjalon eth_dev->data->dev_started = 0; 11704c4bdadfSHarish Patil 1171d7897058SRasesh Mody /* Bring the link down */ 1172d7897058SRasesh Mody qede_dev_set_link_state(eth_dev, false); 1173d7897058SRasesh Mody 1174d7897058SRasesh Mody /* Update link status */ 1175d7897058SRasesh Mody qede_link_update(eth_dev, 0); 1176d7897058SRasesh Mody 1177a60704d1SRasesh Mody /* Replace I/O functions with dummy ones. It cannot 1178a60704d1SRasesh Mody * be set to NULL because rte_eth_rx_burst() doesn't check for NULL. 1179a60704d1SRasesh Mody */ 1180a60704d1SRasesh Mody qede_assign_rxtx_handlers(eth_dev, true); 1181a60704d1SRasesh Mody 11824c4bdadfSHarish Patil /* Disable vport */ 11834c4bdadfSHarish Patil if (qede_activate_vport(eth_dev, false)) 118462024eb8SIvan Ilchenko return 0; 11854c4bdadfSHarish Patil 11864c4bdadfSHarish Patil if (qdev->enable_lro) 11874c4bdadfSHarish Patil qede_enable_tpa(eth_dev, false); 11884c4bdadfSHarish Patil 11894c4bdadfSHarish Patil /* Stop queues */ 11904c4bdadfSHarish Patil qede_stop_queues(eth_dev); 11914c4bdadfSHarish Patil 11924c4bdadfSHarish Patil /* Disable traffic */ 11934c4bdadfSHarish Patil ecore_hw_stop_fastpath(edev); /* TBD - loop */ 11944c4bdadfSHarish Patil 11954c4bdadfSHarish Patil DP_INFO(edev, "Device is stopped\n"); 119662024eb8SIvan Ilchenko 119762024eb8SIvan Ilchenko return 0; 11984c4bdadfSHarish Patil } 11994c4bdadfSHarish Patil 1200b74fd6b8SFerruh Yigit static const char * const valid_args[] = { 1201612ce81bSRasesh Mody QEDE_NPAR_TX_SWITCHING, 1202612ce81bSRasesh Mody QEDE_VF_TX_SWITCHING, 1203f64b91b0SRasesh Mody NULL, 1204f64b91b0SRasesh Mody }; 1205f64b91b0SRasesh Mody 1206f64b91b0SRasesh Mody static int qede_args_check(const char *key, const char *val, void *opaque) 1207f64b91b0SRasesh Mody { 1208f64b91b0SRasesh Mody unsigned long tmp; 1209f64b91b0SRasesh Mody int ret = 0; 1210f64b91b0SRasesh Mody struct rte_eth_dev *eth_dev = opaque; 1211f64b91b0SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1212f64b91b0SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1213f64b91b0SRasesh Mody 1214f64b91b0SRasesh Mody errno = 0; 1215f64b91b0SRasesh Mody tmp = strtoul(val, NULL, 0); 1216f64b91b0SRasesh Mody if (errno) { 1217f64b91b0SRasesh Mody DP_INFO(edev, "%s: \"%s\" is not a valid integer", key, val); 1218f64b91b0SRasesh Mody return errno; 1219f64b91b0SRasesh Mody } 1220f64b91b0SRasesh Mody 1221612ce81bSRasesh Mody if ((strcmp(QEDE_NPAR_TX_SWITCHING, key) == 0) || 1222a16aef52SRasesh Mody ((strcmp(QEDE_VF_TX_SWITCHING, key) == 0) && IS_VF(edev))) { 1223f64b91b0SRasesh Mody qdev->enable_tx_switching = !!tmp; 1224a16aef52SRasesh Mody DP_INFO(edev, "Disabling %s tx-switching\n", 1225a16aef52SRasesh Mody strcmp(QEDE_NPAR_TX_SWITCHING, key) ? 1226a16aef52SRasesh Mody "VF" : "NPAR"); 1227a16aef52SRasesh Mody } 1228f64b91b0SRasesh Mody 1229f64b91b0SRasesh Mody return ret; 1230f64b91b0SRasesh Mody } 1231f64b91b0SRasesh Mody 1232f64b91b0SRasesh Mody static int qede_args(struct rte_eth_dev *eth_dev) 1233f64b91b0SRasesh Mody { 1234f64b91b0SRasesh Mody struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device); 1235f64b91b0SRasesh Mody struct rte_kvargs *kvlist; 1236f64b91b0SRasesh Mody struct rte_devargs *devargs; 1237f64b91b0SRasesh Mody int ret; 1238f64b91b0SRasesh Mody int i; 1239f64b91b0SRasesh Mody 1240f64b91b0SRasesh Mody devargs = pci_dev->device.devargs; 1241f64b91b0SRasesh Mody if (!devargs) 1242f64b91b0SRasesh Mody return 0; /* return success */ 1243f64b91b0SRasesh Mody 1244f64b91b0SRasesh Mody kvlist = rte_kvargs_parse(devargs->args, valid_args); 1245f64b91b0SRasesh Mody if (kvlist == NULL) 1246f64b91b0SRasesh Mody return -EINVAL; 1247f64b91b0SRasesh Mody 1248f64b91b0SRasesh Mody /* Process parameters. */ 1249f64b91b0SRasesh Mody for (i = 0; (valid_args[i] != NULL); ++i) { 1250f64b91b0SRasesh Mody if (rte_kvargs_count(kvlist, valid_args[i])) { 1251f64b91b0SRasesh Mody ret = rte_kvargs_process(kvlist, valid_args[i], 1252f64b91b0SRasesh Mody qede_args_check, eth_dev); 1253f64b91b0SRasesh Mody if (ret != ECORE_SUCCESS) { 1254f64b91b0SRasesh Mody rte_kvargs_free(kvlist); 1255f64b91b0SRasesh Mody return ret; 1256f64b91b0SRasesh Mody } 1257f64b91b0SRasesh Mody } 1258f64b91b0SRasesh Mody } 1259f64b91b0SRasesh Mody rte_kvargs_free(kvlist); 1260f64b91b0SRasesh Mody 1261f64b91b0SRasesh Mody return 0; 1262f64b91b0SRasesh Mody } 1263f64b91b0SRasesh Mody 12642ea6f76aSRasesh Mody static int qede_dev_configure(struct rte_eth_dev *eth_dev) 12652ea6f76aSRasesh Mody { 12664c4bdadfSHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 12674c4bdadfSHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 12682ea6f76aSRasesh Mody struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode; 126905ccc9d8SRasesh Mody uint8_t num_rxqs; 127005ccc9d8SRasesh Mody uint8_t num_txqs; 1271289ba0c0SDavid Harton int ret; 12722ea6f76aSRasesh Mody 12732ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 12742ea6f76aSRasesh Mody 1275295968d1SFerruh Yigit if (rxmode->mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) 1276295968d1SFerruh Yigit rxmode->offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH; 12778b945a7fSPavan Nikhilesh 1278e60644c4SHarish Patil /* We need to have min 1 RX queue.There is no min check in 1279e60644c4SHarish Patil * rte_eth_dev_configure(), so we are checking it here. 1280e60644c4SHarish Patil */ 1281e60644c4SHarish Patil if (eth_dev->data->nb_rx_queues == 0) { 1282e60644c4SHarish Patil DP_ERR(edev, "Minimum one RX queue is required\n"); 1283e60644c4SHarish Patil return -EINVAL; 1284e60644c4SHarish Patil } 1285e60644c4SHarish Patil 1286f64b91b0SRasesh Mody /* Enable Tx switching by default */ 1287f64b91b0SRasesh Mody qdev->enable_tx_switching = 1; 1288f64b91b0SRasesh Mody 1289f64b91b0SRasesh Mody /* Parse devargs and fix up rxmode */ 1290f64b91b0SRasesh Mody if (qede_args(eth_dev)) 1291a16aef52SRasesh Mody DP_NOTICE(edev, false, 1292a16aef52SRasesh Mody "Invalid devargs supplied, requested change will not take effect\n"); 1293f64b91b0SRasesh Mody 1294295968d1SFerruh Yigit if (!(rxmode->mq_mode == RTE_ETH_MQ_RX_NONE || 1295295968d1SFerruh Yigit rxmode->mq_mode == RTE_ETH_MQ_RX_RSS)) { 12964c4bdadfSHarish Patil DP_ERR(edev, "Unsupported multi-queue mode\n"); 12974c4bdadfSHarish Patil return -ENOTSUP; 129829540be7SHarish Patil } 12994c4bdadfSHarish Patil /* Flow director mode check */ 13004c4bdadfSHarish Patil if (qede_check_fdir_support(eth_dev)) 13014c4bdadfSHarish Patil return -ENOTSUP; 130229540be7SHarish Patil 130305ccc9d8SRasesh Mody /* Allocate/reallocate fastpath resources only for new queue config */ 130405ccc9d8SRasesh Mody num_txqs = eth_dev->data->nb_tx_queues * edev->num_hwfns; 130505ccc9d8SRasesh Mody num_rxqs = eth_dev->data->nb_rx_queues * edev->num_hwfns; 130605ccc9d8SRasesh Mody if (qdev->num_tx_queues != num_txqs || 130705ccc9d8SRasesh Mody qdev->num_rx_queues != num_rxqs) { 13084c4bdadfSHarish Patil qede_dealloc_fp_resc(eth_dev); 130905ccc9d8SRasesh Mody qdev->num_tx_queues = num_txqs; 131005ccc9d8SRasesh Mody qdev->num_rx_queues = num_rxqs; 13114c4bdadfSHarish Patil if (qede_alloc_fp_resc(qdev)) 13124c4bdadfSHarish Patil return -ENOMEM; 131305ccc9d8SRasesh Mody } 13142ea6f76aSRasesh Mody 1315295968d1SFerruh Yigit if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_SCATTER) 1316946dfd18SHarish Patil eth_dev->data->scattered_rx = 1; 1317946dfd18SHarish Patil 13189e334305SRasesh Mody if (qede_start_vport(qdev, eth_dev->data->mtu)) 13199a6d30aeSHarish Patil return -1; 1320946dfd18SHarish Patil 13219e334305SRasesh Mody qdev->mtu = eth_dev->data->mtu; 1322dbac54c2SHarish Patil 1323d87246a4SHarish Patil /* Enable VLAN offloads by default */ 1324295968d1SFerruh Yigit ret = qede_vlan_offload_set(eth_dev, RTE_ETH_VLAN_STRIP_MASK | 1325295968d1SFerruh Yigit RTE_ETH_VLAN_FILTER_MASK); 1326289ba0c0SDavid Harton if (ret) 1327289ba0c0SDavid Harton return ret; 1328d87246a4SHarish Patil 13294c4bdadfSHarish Patil DP_INFO(edev, "Device configured with RSS=%d TSS=%d\n", 13308de0c420SShahed Shaikh QEDE_RSS_COUNT(eth_dev), QEDE_TSS_COUNT(eth_dev)); 13318de0c420SShahed Shaikh 13328de0c420SShahed Shaikh if (ECORE_IS_CMT(edev)) 13338de0c420SShahed Shaikh DP_INFO(edev, "Actual HW queues for CMT mode - RX = %d TX = %d\n", 13348de0c420SShahed Shaikh qdev->num_rx_queues, qdev->num_tx_queues); 13358de0c420SShahed Shaikh 13369c5d0a66SHarish Patil 13372ea6f76aSRasesh Mody return 0; 13382ea6f76aSRasesh Mody } 13392ea6f76aSRasesh Mody 13402ea6f76aSRasesh Mody /* Info about HW descriptor ring limitations */ 13412ea6f76aSRasesh Mody static const struct rte_eth_desc_lim qede_rx_desc_lim = { 1342c008e17bSHarish Patil .nb_max = 0x8000, /* 32K */ 13432ea6f76aSRasesh Mody .nb_min = 128, 13442ea6f76aSRasesh Mody .nb_align = 128 /* lowest common multiple */ 13452ea6f76aSRasesh Mody }; 13462ea6f76aSRasesh Mody 13472ea6f76aSRasesh Mody static const struct rte_eth_desc_lim qede_tx_desc_lim = { 1348c008e17bSHarish Patil .nb_max = 0x8000, /* 32K */ 13492ea6f76aSRasesh Mody .nb_min = 256, 135029540be7SHarish Patil .nb_align = 256, 135129540be7SHarish Patil .nb_seg_max = ETH_TX_MAX_BDS_PER_LSO_PACKET, 135229540be7SHarish Patil .nb_mtu_seg_max = ETH_TX_MAX_BDS_PER_NON_LSO_PACKET 13532ea6f76aSRasesh Mody }; 13542ea6f76aSRasesh Mody 1355bdad90d1SIvan Ilchenko static int 13562ea6f76aSRasesh Mody qede_dev_info_get(struct rte_eth_dev *eth_dev, 13572ea6f76aSRasesh Mody struct rte_eth_dev_info *dev_info) 13582ea6f76aSRasesh Mody { 13592ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 13602ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 136164c239b7SHarish Patil struct qed_link_output link; 13621ea56b80SHarish Patil uint32_t speed_cap = 0; 13632ea6f76aSRasesh Mody 13642ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 13652ea6f76aSRasesh Mody 1366f6033f24SHarish Patil dev_info->min_rx_bufsize = (uint32_t)QEDE_MIN_RX_BUFF_SIZE; 13672ea6f76aSRasesh Mody dev_info->max_rx_pktlen = (uint32_t)ETH_TX_MAX_NON_LSO_PKT_LEN; 13682ea6f76aSRasesh Mody dev_info->rx_desc_lim = qede_rx_desc_lim; 13692ea6f76aSRasesh Mody dev_info->tx_desc_lim = qede_tx_desc_lim; 13702fe6f1b7SDmitry Kozlyuk dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; 1371528fcfabSHarish Patil 1372528fcfabSHarish Patil if (IS_PF(edev)) 1373528fcfabSHarish Patil dev_info->max_rx_queues = (uint16_t)RTE_MIN( 1374528fcfabSHarish Patil QEDE_MAX_RSS_CNT(qdev), QEDE_PF_NUM_CONNS / 2); 1375528fcfabSHarish Patil else 1376528fcfabSHarish Patil dev_info->max_rx_queues = (uint16_t)RTE_MIN( 1377528fcfabSHarish Patil QEDE_MAX_RSS_CNT(qdev), ECORE_MAX_VF_CHAINS_PER_PF); 13788de0c420SShahed Shaikh /* Since CMT mode internally doubles the number of queues */ 13798de0c420SShahed Shaikh if (ECORE_IS_CMT(edev)) 13808de0c420SShahed Shaikh dev_info->max_rx_queues = dev_info->max_rx_queues / 2; 13818de0c420SShahed Shaikh 13822ea6f76aSRasesh Mody dev_info->max_tx_queues = dev_info->max_rx_queues; 1383528fcfabSHarish Patil 13843320ca8cSRasesh Mody dev_info->max_mac_addrs = qdev->dev_info.num_mac_filters; 138586a2265eSRasesh Mody dev_info->max_vfs = 0; 13865cdd769aSRasesh Mody dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE; 13877ab35bf6SHarish Patil dev_info->hash_key_size = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); 13882ea6f76aSRasesh Mody dev_info->flow_type_rss_offloads = (uint64_t)QEDE_RSS_OFFLOAD_ALL; 1389295968d1SFerruh Yigit dev_info->rx_offload_capa = (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | 1390295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_UDP_CKSUM | 1391295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_TCP_CKSUM | 1392295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM | 1393295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_TCP_LRO | 1394295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_KEEP_CRC | 1395295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_SCATTER | 1396295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_FILTER | 1397295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_STRIP | 1398295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_RSS_HASH); 1399946dfd18SHarish Patil dev_info->rx_queue_offload_capa = 0; 140029540be7SHarish Patil 1401946dfd18SHarish Patil /* TX offloads are on a per-packet basis, so it is applicable 1402946dfd18SHarish Patil * to both at port and queue levels. 1403946dfd18SHarish Patil */ 1404295968d1SFerruh Yigit dev_info->tx_offload_capa = (RTE_ETH_TX_OFFLOAD_VLAN_INSERT | 1405295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | 1406295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_UDP_CKSUM | 1407295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_TCP_CKSUM | 1408295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | 1409295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_MULTI_SEGS | 1410295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_TCP_TSO | 1411295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | 1412295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO); 1413946dfd18SHarish Patil dev_info->tx_queue_offload_capa = dev_info->tx_offload_capa; 1414946dfd18SHarish Patil 1415946dfd18SHarish Patil dev_info->default_txconf = (struct rte_eth_txconf) { 1416295968d1SFerruh Yigit .offloads = RTE_ETH_TX_OFFLOAD_MULTI_SEGS, 1417946dfd18SHarish Patil }; 1418946dfd18SHarish Patil 1419946dfd18SHarish Patil dev_info->default_rxconf = (struct rte_eth_rxconf) { 1420946dfd18SHarish Patil /* Packets are always dropped if no descriptors are available */ 1421946dfd18SHarish Patil .rx_drop_en = 1, 1422048a68edSShahed Shaikh .offloads = 0, 1423946dfd18SHarish Patil }; 14242ea6f76aSRasesh Mody 142564c239b7SHarish Patil memset(&link, 0, sizeof(struct qed_link_output)); 142664c239b7SHarish Patil qdev->ops->common->get_link(edev, &link); 14271ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) 1428295968d1SFerruh Yigit speed_cap |= RTE_ETH_LINK_SPEED_1G; 14291ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) 1430295968d1SFerruh Yigit speed_cap |= RTE_ETH_LINK_SPEED_10G; 14311ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) 1432295968d1SFerruh Yigit speed_cap |= RTE_ETH_LINK_SPEED_25G; 14331ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) 1434295968d1SFerruh Yigit speed_cap |= RTE_ETH_LINK_SPEED_40G; 14351ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) 1436295968d1SFerruh Yigit speed_cap |= RTE_ETH_LINK_SPEED_50G; 14371ea56b80SHarish Patil if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) 1438295968d1SFerruh Yigit speed_cap |= RTE_ETH_LINK_SPEED_100G; 14391ea56b80SHarish Patil dev_info->speed_capa = speed_cap; 1440bdad90d1SIvan Ilchenko 1441bdad90d1SIvan Ilchenko return 0; 14422ea6f76aSRasesh Mody } 14432ea6f76aSRasesh Mody 14442ea6f76aSRasesh Mody /* return 0 means link status changed, -1 means not changed */ 14458aab5d6fSRasesh Mody int 14462ea6f76aSRasesh Mody qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete) 14472ea6f76aSRasesh Mody { 14482ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 14492ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 1450c6034a20SShahed Shaikh struct qed_link_output q_link; 1451c6034a20SShahed Shaikh struct rte_eth_link link; 14522ea6f76aSRasesh Mody uint16_t link_duplex; 14532ea6f76aSRasesh Mody 1454c6034a20SShahed Shaikh memset(&q_link, 0, sizeof(q_link)); 1455c6034a20SShahed Shaikh memset(&link, 0, sizeof(link)); 1456c6034a20SShahed Shaikh 1457c6034a20SShahed Shaikh qdev->ops->common->get_link(edev, &q_link); 14582ea6f76aSRasesh Mody 14592ea6f76aSRasesh Mody /* Link Speed */ 1460c6034a20SShahed Shaikh link.link_speed = q_link.speed; 14612ea6f76aSRasesh Mody 14622ea6f76aSRasesh Mody /* Link Mode */ 1463c6034a20SShahed Shaikh switch (q_link.duplex) { 14642ea6f76aSRasesh Mody case QEDE_DUPLEX_HALF: 1465295968d1SFerruh Yigit link_duplex = RTE_ETH_LINK_HALF_DUPLEX; 14662ea6f76aSRasesh Mody break; 14672ea6f76aSRasesh Mody case QEDE_DUPLEX_FULL: 1468295968d1SFerruh Yigit link_duplex = RTE_ETH_LINK_FULL_DUPLEX; 14692ea6f76aSRasesh Mody break; 14702ea6f76aSRasesh Mody case QEDE_DUPLEX_UNKNOWN: 14712ea6f76aSRasesh Mody default: 14722ea6f76aSRasesh Mody link_duplex = -1; 14732ea6f76aSRasesh Mody } 1474c6034a20SShahed Shaikh link.link_duplex = link_duplex; 14752ea6f76aSRasesh Mody 14762ea6f76aSRasesh Mody /* Link Status */ 1477295968d1SFerruh Yigit link.link_status = q_link.link_up ? RTE_ETH_LINK_UP : RTE_ETH_LINK_DOWN; 14782ea6f76aSRasesh Mody 14792ea6f76aSRasesh Mody /* AN */ 1480c6034a20SShahed Shaikh link.link_autoneg = (q_link.supported_caps & QEDE_SUPPORTED_AUTONEG) ? 1481295968d1SFerruh Yigit RTE_ETH_LINK_AUTONEG : RTE_ETH_LINK_FIXED; 14822ea6f76aSRasesh Mody 14832ea6f76aSRasesh Mody DP_INFO(edev, "Link - Speed %u Mode %u AN %u Status %u\n", 1484c6034a20SShahed Shaikh link.link_speed, link.link_duplex, 1485c6034a20SShahed Shaikh link.link_autoneg, link.link_status); 14862ea6f76aSRasesh Mody 1487c6034a20SShahed Shaikh return rte_eth_linkstatus_set(eth_dev, &link); 14882ea6f76aSRasesh Mody } 14892ea6f76aSRasesh Mody 14909039c812SAndrew Rybchenko static int qede_promiscuous_enable(struct rte_eth_dev *eth_dev) 14912ea6f76aSRasesh Mody { 14929039c812SAndrew Rybchenko enum _ecore_status_t ecore_status; 1493b10231aeSDevendra Singh Rawat struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1494b10231aeSDevendra Singh Rawat struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1495b10231aeSDevendra Singh Rawat enum qed_filter_rx_mode_type type = QED_FILTER_RX_MODE_TYPE_PROMISC; 14962ea6f76aSRasesh Mody 14972ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 14982ea6f76aSRasesh Mody 14999039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, type); 15009039c812SAndrew Rybchenko 15019039c812SAndrew Rybchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 15022ea6f76aSRasesh Mody } 15032ea6f76aSRasesh Mody 15049039c812SAndrew Rybchenko static int qede_promiscuous_disable(struct rte_eth_dev *eth_dev) 15052ea6f76aSRasesh Mody { 15062ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 15072ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 15089039c812SAndrew Rybchenko enum _ecore_status_t ecore_status; 15092ea6f76aSRasesh Mody 15102ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 15112ea6f76aSRasesh Mody 15122ea6f76aSRasesh Mody if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1) 15139039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 15142ea6f76aSRasesh Mody QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC); 15152ea6f76aSRasesh Mody else 15169039c812SAndrew Rybchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 151777fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_REGULAR); 15189039c812SAndrew Rybchenko 15199039c812SAndrew Rybchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 15202ea6f76aSRasesh Mody } 15212ea6f76aSRasesh Mody 15222af14ca7SHarish Patil static void qede_poll_sp_sb_cb(void *param) 15232af14ca7SHarish Patil { 15242af14ca7SHarish Patil struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; 15252af14ca7SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 15262af14ca7SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 15272af14ca7SHarish Patil int rc; 15282af14ca7SHarish Patil 15292af14ca7SHarish Patil qede_interrupt_action(ECORE_LEADING_HWFN(edev)); 15302af14ca7SHarish Patil qede_interrupt_action(&edev->hwfns[1]); 15312af14ca7SHarish Patil 15320833120fSShahed Shaikh rc = rte_eal_alarm_set(QEDE_SP_TIMER_PERIOD, 15332af14ca7SHarish Patil qede_poll_sp_sb_cb, 15342af14ca7SHarish Patil (void *)eth_dev); 15352af14ca7SHarish Patil if (rc != 0) { 15362af14ca7SHarish Patil DP_ERR(edev, "Unable to start periodic" 15372af14ca7SHarish Patil " timer rc %d\n", rc); 15382af14ca7SHarish Patil } 15392af14ca7SHarish Patil } 15402af14ca7SHarish Patil 1541b142387bSThomas Monjalon static int qede_dev_close(struct rte_eth_dev *eth_dev) 15422ea6f76aSRasesh Mody { 1543c0802544SFerruh Yigit struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 1544dbac54c2SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1545dbac54c2SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 154662024eb8SIvan Ilchenko int ret = 0; 15472ea6f76aSRasesh Mody 15482ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 15492ea6f76aSRasesh Mody 15501df1bb52SRasesh Mody /* only close in case of the primary process */ 15511df1bb52SRasesh Mody if (rte_eal_process_type() != RTE_PROC_PRIMARY) 15521df1bb52SRasesh Mody return 0; 15531df1bb52SRasesh Mody 15542ea6f76aSRasesh Mody /* dev_stop() shall cleanup fp resources in hw but without releasing 15552ea6f76aSRasesh Mody * dma memories and sw structures so that dev_start() can be called 15562ea6f76aSRasesh Mody * by the app without reconfiguration. However, in dev_close() we 15572ea6f76aSRasesh Mody * can release all the resources and device can be brought up newly 15582ea6f76aSRasesh Mody */ 15594c4bdadfSHarish Patil if (eth_dev->data->dev_started) 156062024eb8SIvan Ilchenko ret = qede_dev_stop(eth_dev); 15612ea6f76aSRasesh Mody 1562bf44e27aSManish Chopra if (qdev->vport_started) 15639a6d30aeSHarish Patil qede_stop_vport(edev); 1564dd28bc8cSHarish Patil qdev->vport_started = false; 15654c4bdadfSHarish Patil qede_fdir_dealloc_resc(eth_dev); 1566dbac54c2SHarish Patil qede_dealloc_fp_resc(eth_dev); 15672ea6f76aSRasesh Mody 15684c4bdadfSHarish Patil eth_dev->data->nb_rx_queues = 0; 15694c4bdadfSHarish Patil eth_dev->data->nb_tx_queues = 0; 15704c4bdadfSHarish Patil 15712ea6f76aSRasesh Mody qdev->ops->common->slowpath_stop(edev); 15722ea6f76aSRasesh Mody qdev->ops->common->remove(edev); 1573d61138d4SHarman Kalra rte_intr_disable(pci_dev->intr_handle); 15744eee1bbfSShahed Shaikh 1575d61138d4SHarman Kalra switch (rte_intr_type_get(pci_dev->intr_handle)) { 15764eee1bbfSShahed Shaikh case RTE_INTR_HANDLE_UIO_INTX: 15774eee1bbfSShahed Shaikh case RTE_INTR_HANDLE_VFIO_LEGACY: 1578d61138d4SHarman Kalra rte_intr_callback_unregister(pci_dev->intr_handle, 15794eee1bbfSShahed Shaikh qede_interrupt_handler_intx, 15804eee1bbfSShahed Shaikh (void *)eth_dev); 15814eee1bbfSShahed Shaikh break; 15824eee1bbfSShahed Shaikh default: 1583d61138d4SHarman Kalra rte_intr_callback_unregister(pci_dev->intr_handle, 15844eee1bbfSShahed Shaikh qede_interrupt_handler, 15854eee1bbfSShahed Shaikh (void *)eth_dev); 15864eee1bbfSShahed Shaikh } 15874eee1bbfSShahed Shaikh 1588c0845c33SRasesh Mody if (ECORE_IS_CMT(edev)) 15892af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, (void *)eth_dev); 1590b142387bSThomas Monjalon 159162024eb8SIvan Ilchenko return ret; 15922ea6f76aSRasesh Mody } 15932ea6f76aSRasesh Mody 1594d5b0924bSMatan Azrad static int 15952ea6f76aSRasesh Mody qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats) 15962ea6f76aSRasesh Mody { 15972ea6f76aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 15982ea6f76aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 15992ea6f76aSRasesh Mody struct ecore_eth_stats stats; 16000aa3e7b9SShahed Shaikh unsigned int i = 0, j = 0, qid, idx, hw_fn; 160106e83c4eSRasesh Mody unsigned int rxq_stat_cntrs, txq_stat_cntrs; 16027634c5f9SRasesh Mody struct qede_tx_queue *txq; 16032ea6f76aSRasesh Mody 16044c4bdadfSHarish Patil ecore_get_vport_stats(edev, &stats); 16052ea6f76aSRasesh Mody 16062ea6f76aSRasesh Mody /* RX Stats */ 16079c1aa3e1SRasesh Mody eth_stats->ipackets = stats.common.rx_ucast_pkts + 16089c1aa3e1SRasesh Mody stats.common.rx_mcast_pkts + stats.common.rx_bcast_pkts; 16092ea6f76aSRasesh Mody 16109c1aa3e1SRasesh Mody eth_stats->ibytes = stats.common.rx_ucast_bytes + 16119c1aa3e1SRasesh Mody stats.common.rx_mcast_bytes + stats.common.rx_bcast_bytes; 16122ea6f76aSRasesh Mody 16139c1aa3e1SRasesh Mody eth_stats->ierrors = stats.common.rx_crc_errors + 16149c1aa3e1SRasesh Mody stats.common.rx_align_errors + 16159c1aa3e1SRasesh Mody stats.common.rx_carrier_errors + 16169c1aa3e1SRasesh Mody stats.common.rx_oversize_packets + 16179c1aa3e1SRasesh Mody stats.common.rx_jabbers + stats.common.rx_undersize_packets; 16182ea6f76aSRasesh Mody 16199c1aa3e1SRasesh Mody eth_stats->rx_nombuf = stats.common.no_buff_discards; 16202ea6f76aSRasesh Mody 16219c1aa3e1SRasesh Mody eth_stats->imissed = stats.common.mftag_filter_discards + 16229c1aa3e1SRasesh Mody stats.common.mac_filter_discards + 16239c1aa3e1SRasesh Mody stats.common.no_buff_discards + 16249c1aa3e1SRasesh Mody stats.common.brb_truncates + stats.common.brb_discards; 16252ea6f76aSRasesh Mody 16262ea6f76aSRasesh Mody /* TX stats */ 16279c1aa3e1SRasesh Mody eth_stats->opackets = stats.common.tx_ucast_pkts + 16289c1aa3e1SRasesh Mody stats.common.tx_mcast_pkts + stats.common.tx_bcast_pkts; 16292ea6f76aSRasesh Mody 16309c1aa3e1SRasesh Mody eth_stats->obytes = stats.common.tx_ucast_bytes + 16319c1aa3e1SRasesh Mody stats.common.tx_mcast_bytes + stats.common.tx_bcast_bytes; 16322ea6f76aSRasesh Mody 16339c1aa3e1SRasesh Mody eth_stats->oerrors = stats.common.tx_err_drop_pkts; 16347634c5f9SRasesh Mody 16357634c5f9SRasesh Mody /* Queue stats */ 16368de0c420SShahed Shaikh rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(eth_dev), 163706e83c4eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 16388de0c420SShahed Shaikh txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(eth_dev), 163906e83c4eSRasesh Mody RTE_ETHDEV_QUEUE_STAT_CNTRS); 16408de0c420SShahed Shaikh if (rxq_stat_cntrs != (unsigned int)QEDE_RSS_COUNT(eth_dev) || 16418de0c420SShahed Shaikh txq_stat_cntrs != (unsigned int)QEDE_TSS_COUNT(eth_dev)) 164206e83c4eSRasesh Mody DP_VERBOSE(edev, ECORE_MSG_DEBUG, 164306e83c4eSRasesh Mody "Not all the queue stats will be displayed. Set" 164406e83c4eSRasesh Mody " RTE_ETHDEV_QUEUE_STAT_CNTRS config param" 164506e83c4eSRasesh Mody " appropriately and retry.\n"); 164606e83c4eSRasesh Mody 16478de0c420SShahed Shaikh for (qid = 0; qid < eth_dev->data->nb_rx_queues; qid++) { 16480aa3e7b9SShahed Shaikh eth_stats->q_ipackets[i] = 0; 16490aa3e7b9SShahed Shaikh eth_stats->q_errors[i] = 0; 16500aa3e7b9SShahed Shaikh 16510aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 16520aa3e7b9SShahed Shaikh idx = qid * edev->num_hwfns + hw_fn; 16530aa3e7b9SShahed Shaikh 16540aa3e7b9SShahed Shaikh eth_stats->q_ipackets[i] += 16550aa3e7b9SShahed Shaikh *(uint64_t *) 16560aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16577634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16587634c5f9SRasesh Mody rcv_pkts)); 16590aa3e7b9SShahed Shaikh eth_stats->q_errors[i] += 16600aa3e7b9SShahed Shaikh *(uint64_t *) 16610aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16627634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16637634c5f9SRasesh Mody rx_hw_errors)) + 16640aa3e7b9SShahed Shaikh *(uint64_t *) 16650aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[idx].rxq)) + 16667634c5f9SRasesh Mody offsetof(struct qede_rx_queue, 16677634c5f9SRasesh Mody rx_alloc_errors)); 16680aa3e7b9SShahed Shaikh } 16690aa3e7b9SShahed Shaikh 16707634c5f9SRasesh Mody i++; 167106e83c4eSRasesh Mody if (i == rxq_stat_cntrs) 167206e83c4eSRasesh Mody break; 167306e83c4eSRasesh Mody } 16747634c5f9SRasesh Mody 16758de0c420SShahed Shaikh for (qid = 0; qid < eth_dev->data->nb_tx_queues; qid++) { 16760aa3e7b9SShahed Shaikh eth_stats->q_opackets[j] = 0; 16770aa3e7b9SShahed Shaikh 16780aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 16790aa3e7b9SShahed Shaikh idx = qid * edev->num_hwfns + hw_fn; 16800aa3e7b9SShahed Shaikh 16810aa3e7b9SShahed Shaikh txq = qdev->fp_array[idx].txq; 16820aa3e7b9SShahed Shaikh eth_stats->q_opackets[j] += 16837634c5f9SRasesh Mody *((uint64_t *)(uintptr_t) 16847634c5f9SRasesh Mody (((uint64_t)(uintptr_t)(txq)) + 16857634c5f9SRasesh Mody offsetof(struct qede_tx_queue, 16867634c5f9SRasesh Mody xmit_pkts))); 16870aa3e7b9SShahed Shaikh } 16880aa3e7b9SShahed Shaikh 16897634c5f9SRasesh Mody j++; 169006e83c4eSRasesh Mody if (j == txq_stat_cntrs) 169106e83c4eSRasesh Mody break; 16927634c5f9SRasesh Mody } 1693d5b0924bSMatan Azrad 1694d5b0924bSMatan Azrad return 0; 16957634c5f9SRasesh Mody } 16967634c5f9SRasesh Mody 16977634c5f9SRasesh Mody static unsigned 16987634c5f9SRasesh Mody qede_get_xstats_count(struct qede_dev *qdev) { 16998de0c420SShahed Shaikh struct rte_eth_dev *dev = (struct rte_eth_dev *)qdev->ethdev; 17008de0c420SShahed Shaikh 17019c1aa3e1SRasesh Mody if (ECORE_IS_BB(&qdev->edev)) 17027634c5f9SRasesh Mody return RTE_DIM(qede_xstats_strings) + 17039c1aa3e1SRasesh Mody RTE_DIM(qede_bb_xstats_strings) + 17049c1aa3e1SRasesh Mody (RTE_DIM(qede_rxq_xstats_strings) * 17058de0c420SShahed Shaikh QEDE_RSS_COUNT(dev) * qdev->edev.num_hwfns); 17069c1aa3e1SRasesh Mody else 17079c1aa3e1SRasesh Mody return RTE_DIM(qede_xstats_strings) + 17089c1aa3e1SRasesh Mody RTE_DIM(qede_ah_xstats_strings) + 170906e83c4eSRasesh Mody (RTE_DIM(qede_rxq_xstats_strings) * 17108de0c420SShahed Shaikh QEDE_RSS_COUNT(dev)); 1711d1216e22SRasesh Mody } 17122ea6f76aSRasesh Mody 1713d1216e22SRasesh Mody static int 1714dd2c630aSFerruh Yigit qede_get_xstats_names(struct rte_eth_dev *dev, 1715af785e47SRasesh Mody struct rte_eth_xstat_name *xstats_names, 1716af785e47SRasesh Mody __rte_unused unsigned int limit) 1717d1216e22SRasesh Mody { 17187634c5f9SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 17199c1aa3e1SRasesh Mody struct ecore_dev *edev = &qdev->edev; 17207634c5f9SRasesh Mody const unsigned int stat_cnt = qede_get_xstats_count(qdev); 17210aa3e7b9SShahed Shaikh unsigned int i, qid, hw_fn, stat_idx = 0; 1722d1216e22SRasesh Mody 17230aa3e7b9SShahed Shaikh if (xstats_names == NULL) 17240aa3e7b9SShahed Shaikh return stat_cnt; 17250aa3e7b9SShahed Shaikh 17267634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) { 17276723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 17286723c0fcSBruce Richardson qede_xstats_strings[i].name, 17296723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 17307634c5f9SRasesh Mody stat_idx++; 17317634c5f9SRasesh Mody } 17327634c5f9SRasesh Mody 17339c1aa3e1SRasesh Mody if (ECORE_IS_BB(edev)) { 17349c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_bb_xstats_strings); i++) { 17356723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 17366723c0fcSBruce Richardson qede_bb_xstats_strings[i].name, 17376723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 17389c1aa3e1SRasesh Mody stat_idx++; 17399c1aa3e1SRasesh Mody } 17409c1aa3e1SRasesh Mody } else { 17419c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_ah_xstats_strings); i++) { 17426723c0fcSBruce Richardson strlcpy(xstats_names[stat_idx].name, 17436723c0fcSBruce Richardson qede_ah_xstats_strings[i].name, 17446723c0fcSBruce Richardson sizeof(xstats_names[stat_idx].name)); 17459c1aa3e1SRasesh Mody stat_idx++; 17469c1aa3e1SRasesh Mody } 17479c1aa3e1SRasesh Mody } 17489c1aa3e1SRasesh Mody 17490aa3e7b9SShahed Shaikh for (qid = 0; qid < QEDE_RSS_COUNT(dev); qid++) { 17500aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 17517634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) { 17527634c5f9SRasesh Mody snprintf(xstats_names[stat_idx].name, 17530aa3e7b9SShahed Shaikh RTE_ETH_XSTATS_NAME_SIZE, 17540aa3e7b9SShahed Shaikh "%.4s%d.%d%s", 17550aa3e7b9SShahed Shaikh qede_rxq_xstats_strings[i].name, 17560aa3e7b9SShahed Shaikh hw_fn, qid, 17577634c5f9SRasesh Mody qede_rxq_xstats_strings[i].name + 4); 17587634c5f9SRasesh Mody stat_idx++; 17597634c5f9SRasesh Mody } 17607634c5f9SRasesh Mody } 17617634c5f9SRasesh Mody } 1762d1216e22SRasesh Mody 1763d1216e22SRasesh Mody return stat_cnt; 1764d1216e22SRasesh Mody } 1765d1216e22SRasesh Mody 1766d1216e22SRasesh Mody static int 1767d1216e22SRasesh Mody qede_get_xstats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, 1768d1216e22SRasesh Mody unsigned int n) 1769d1216e22SRasesh Mody { 1770d1216e22SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 1771d1216e22SRasesh Mody struct ecore_dev *edev = &qdev->edev; 1772d1216e22SRasesh Mody struct ecore_eth_stats stats; 17737634c5f9SRasesh Mody const unsigned int num = qede_get_xstats_count(qdev); 17740aa3e7b9SShahed Shaikh unsigned int i, qid, hw_fn, fpidx, stat_idx = 0; 1775d1216e22SRasesh Mody 1776d1216e22SRasesh Mody if (n < num) 1777d1216e22SRasesh Mody return num; 1778d1216e22SRasesh Mody 17794c4bdadfSHarish Patil ecore_get_vport_stats(edev, &stats); 1780d1216e22SRasesh Mody 17817634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) { 17827634c5f9SRasesh Mody xstats[stat_idx].value = *(uint64_t *)(((char *)&stats) + 17837634c5f9SRasesh Mody qede_xstats_strings[i].offset); 1784513c78aeSOlivier Matz xstats[stat_idx].id = stat_idx; 17857634c5f9SRasesh Mody stat_idx++; 17867634c5f9SRasesh Mody } 1787d1216e22SRasesh Mody 17889c1aa3e1SRasesh Mody if (ECORE_IS_BB(edev)) { 17899c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_bb_xstats_strings); i++) { 17909c1aa3e1SRasesh Mody xstats[stat_idx].value = 17919c1aa3e1SRasesh Mody *(uint64_t *)(((char *)&stats) + 17929c1aa3e1SRasesh Mody qede_bb_xstats_strings[i].offset); 17939c1aa3e1SRasesh Mody xstats[stat_idx].id = stat_idx; 17949c1aa3e1SRasesh Mody stat_idx++; 17959c1aa3e1SRasesh Mody } 17969c1aa3e1SRasesh Mody } else { 17979c1aa3e1SRasesh Mody for (i = 0; i < RTE_DIM(qede_ah_xstats_strings); i++) { 17989c1aa3e1SRasesh Mody xstats[stat_idx].value = 17999c1aa3e1SRasesh Mody *(uint64_t *)(((char *)&stats) + 18009c1aa3e1SRasesh Mody qede_ah_xstats_strings[i].offset); 18019c1aa3e1SRasesh Mody xstats[stat_idx].id = stat_idx; 18029c1aa3e1SRasesh Mody stat_idx++; 18039c1aa3e1SRasesh Mody } 18049c1aa3e1SRasesh Mody } 18059c1aa3e1SRasesh Mody 18060aa3e7b9SShahed Shaikh for (qid = 0; qid < dev->data->nb_rx_queues; qid++) { 18070aa3e7b9SShahed Shaikh for_each_hwfn(edev, hw_fn) { 18087634c5f9SRasesh Mody for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) { 18090aa3e7b9SShahed Shaikh fpidx = qid * edev->num_hwfns + hw_fn; 18108de0c420SShahed Shaikh xstats[stat_idx].value = *(uint64_t *) 18110aa3e7b9SShahed Shaikh (((char *)(qdev->fp_array[fpidx].rxq)) + 18127634c5f9SRasesh Mody qede_rxq_xstats_strings[i].offset); 1813513c78aeSOlivier Matz xstats[stat_idx].id = stat_idx; 18147634c5f9SRasesh Mody stat_idx++; 18157634c5f9SRasesh Mody } 18160aa3e7b9SShahed Shaikh 18170aa3e7b9SShahed Shaikh } 18187634c5f9SRasesh Mody } 18197634c5f9SRasesh Mody 18207634c5f9SRasesh Mody return stat_idx; 1821d1216e22SRasesh Mody } 1822d1216e22SRasesh Mody 18239970a9adSIgor Romanov static int 1824d1216e22SRasesh Mody qede_reset_xstats(struct rte_eth_dev *dev) 1825d1216e22SRasesh Mody { 1826d1216e22SRasesh Mody struct qede_dev *qdev = dev->data->dev_private; 1827d1216e22SRasesh Mody struct ecore_dev *edev = &qdev->edev; 1828d1216e22SRasesh Mody 1829d1216e22SRasesh Mody ecore_reset_vport_stats(edev); 1830ce26be6eSRasesh Mody qede_reset_queue_stats(qdev, true); 18319970a9adSIgor Romanov 18329970a9adSIgor Romanov return 0; 18332ea6f76aSRasesh Mody } 18342ea6f76aSRasesh Mody 18352ea6f76aSRasesh Mody int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up) 18362ea6f76aSRasesh Mody { 18372ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 18382ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 18392ea6f76aSRasesh Mody struct qed_link_params link_params; 18402ea6f76aSRasesh Mody int rc; 18412ea6f76aSRasesh Mody 18422ea6f76aSRasesh Mody DP_INFO(edev, "setting link state %d\n", link_up); 18432ea6f76aSRasesh Mody memset(&link_params, 0, sizeof(link_params)); 18442ea6f76aSRasesh Mody link_params.link_up = link_up; 18452ea6f76aSRasesh Mody rc = qdev->ops->common->set_link(edev, &link_params); 18462ea6f76aSRasesh Mody if (rc != ECORE_SUCCESS) 18472ea6f76aSRasesh Mody DP_ERR(edev, "Unable to set link state %d\n", link_up); 18482ea6f76aSRasesh Mody 18492ea6f76aSRasesh Mody return rc; 18502ea6f76aSRasesh Mody } 18512ea6f76aSRasesh Mody 18522ea6f76aSRasesh Mody static int qede_dev_set_link_up(struct rte_eth_dev *eth_dev) 18532ea6f76aSRasesh Mody { 18542ea6f76aSRasesh Mody return qede_dev_set_link_state(eth_dev, true); 18552ea6f76aSRasesh Mody } 18562ea6f76aSRasesh Mody 18572ea6f76aSRasesh Mody static int qede_dev_set_link_down(struct rte_eth_dev *eth_dev) 18582ea6f76aSRasesh Mody { 18592ea6f76aSRasesh Mody return qede_dev_set_link_state(eth_dev, false); 18602ea6f76aSRasesh Mody } 18612ea6f76aSRasesh Mody 18629970a9adSIgor Romanov static int qede_reset_stats(struct rte_eth_dev *eth_dev) 18635cdd769aSRasesh Mody { 18645cdd769aSRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 18655cdd769aSRasesh Mody struct ecore_dev *edev = &qdev->edev; 18665cdd769aSRasesh Mody 18675cdd769aSRasesh Mody ecore_reset_vport_stats(edev); 1868ce26be6eSRasesh Mody qede_reset_queue_stats(qdev, false); 18699970a9adSIgor Romanov 18709970a9adSIgor Romanov return 0; 18715cdd769aSRasesh Mody } 18725cdd769aSRasesh Mody 1873ca041cd4SIvan Ilchenko static int qede_allmulticast_enable(struct rte_eth_dev *eth_dev) 18742ea6f76aSRasesh Mody { 18752ea6f76aSRasesh Mody enum qed_filter_rx_mode_type type = 18762ea6f76aSRasesh Mody QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC; 1877ca041cd4SIvan Ilchenko enum _ecore_status_t ecore_status; 18782ea6f76aSRasesh Mody 1879a91fb48aSBalazs Nemeth if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1) 1880a91fb48aSBalazs Nemeth type = QED_FILTER_RX_MODE_TYPE_PROMISC; 1881ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, type); 1882ca041cd4SIvan Ilchenko 1883ca041cd4SIvan Ilchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 18842ea6f76aSRasesh Mody } 18852ea6f76aSRasesh Mody 1886ca041cd4SIvan Ilchenko static int qede_allmulticast_disable(struct rte_eth_dev *eth_dev) 18872ea6f76aSRasesh Mody { 1888ca041cd4SIvan Ilchenko enum _ecore_status_t ecore_status; 1889ca041cd4SIvan Ilchenko 18902ea6f76aSRasesh Mody if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1) 1891ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 189277fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_PROMISC); 18932ea6f76aSRasesh Mody else 1894ca041cd4SIvan Ilchenko ecore_status = qed_configure_filter_rx_mode(eth_dev, 189577fac1b5SHarish Patil QED_FILTER_RX_MODE_TYPE_REGULAR); 1896ca041cd4SIvan Ilchenko 1897ca041cd4SIvan Ilchenko return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; 18982ea6f76aSRasesh Mody } 18992ea6f76aSRasesh Mody 1900413ecf29SHarish Patil static int 19016d13ea8eSOlivier Matz qede_set_mc_addr_list(struct rte_eth_dev *eth_dev, 19026d13ea8eSOlivier Matz struct rte_ether_addr *mc_addrs, 1903413ecf29SHarish Patil uint32_t mc_addrs_num) 1904413ecf29SHarish Patil { 1905413ecf29SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1906413ecf29SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1907413ecf29SHarish Patil uint8_t i; 1908413ecf29SHarish Patil 1909413ecf29SHarish Patil if (mc_addrs_num > ECORE_MAX_MC_ADDRS) { 1910413ecf29SHarish Patil DP_ERR(edev, "Reached max multicast filters limit," 1911413ecf29SHarish Patil "Please enable multicast promisc mode\n"); 1912413ecf29SHarish Patil return -ENOSPC; 1913413ecf29SHarish Patil } 1914413ecf29SHarish Patil 1915413ecf29SHarish Patil for (i = 0; i < mc_addrs_num; i++) { 1916538da7a1SOlivier Matz if (!rte_is_multicast_ether_addr(&mc_addrs[i])) { 1917413ecf29SHarish Patil DP_ERR(edev, "Not a valid multicast MAC\n"); 1918413ecf29SHarish Patil return -EINVAL; 1919413ecf29SHarish Patil } 1920413ecf29SHarish Patil } 1921413ecf29SHarish Patil 1922413ecf29SHarish Patil /* Flush all existing entries */ 1923413ecf29SHarish Patil if (qede_del_mcast_filters(eth_dev)) 1924413ecf29SHarish Patil return -1; 1925413ecf29SHarish Patil 1926413ecf29SHarish Patil /* Set new mcast list */ 1927413ecf29SHarish Patil return qede_add_mcast_filters(eth_dev, mc_addrs, mc_addrs_num); 1928413ecf29SHarish Patil } 1929413ecf29SHarish Patil 1930d121a6b5SRasesh Mody /* Update MTU via vport-update without doing port restart. 1931d121a6b5SRasesh Mody * The vport must be deactivated before calling this API. 1932d121a6b5SRasesh Mody */ 1933d121a6b5SRasesh Mody int qede_update_mtu(struct rte_eth_dev *eth_dev, uint16_t mtu) 1934d121a6b5SRasesh Mody { 1935d121a6b5SRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 1936d121a6b5SRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 1937d121a6b5SRasesh Mody struct ecore_hwfn *p_hwfn; 1938d121a6b5SRasesh Mody int rc; 1939d121a6b5SRasesh Mody int i; 1940d121a6b5SRasesh Mody 1941d121a6b5SRasesh Mody if (IS_PF(edev)) { 1942d121a6b5SRasesh Mody struct ecore_sp_vport_update_params params; 1943d121a6b5SRasesh Mody 1944d121a6b5SRasesh Mody memset(¶ms, 0, sizeof(struct ecore_sp_vport_update_params)); 1945d121a6b5SRasesh Mody params.vport_id = 0; 1946d121a6b5SRasesh Mody params.mtu = mtu; 1947d121a6b5SRasesh Mody params.vport_id = 0; 1948d121a6b5SRasesh Mody for_each_hwfn(edev, i) { 1949d121a6b5SRasesh Mody p_hwfn = &edev->hwfns[i]; 1950d121a6b5SRasesh Mody params.opaque_fid = p_hwfn->hw_info.opaque_fid; 1951d121a6b5SRasesh Mody rc = ecore_sp_vport_update(p_hwfn, ¶ms, 1952d121a6b5SRasesh Mody ECORE_SPQ_MODE_EBLOCK, NULL); 1953d121a6b5SRasesh Mody if (rc != ECORE_SUCCESS) 1954d121a6b5SRasesh Mody goto err; 1955d121a6b5SRasesh Mody } 1956d121a6b5SRasesh Mody } else { 1957d121a6b5SRasesh Mody for_each_hwfn(edev, i) { 1958d121a6b5SRasesh Mody p_hwfn = &edev->hwfns[i]; 1959d121a6b5SRasesh Mody rc = ecore_vf_pf_update_mtu(p_hwfn, mtu); 1960d121a6b5SRasesh Mody if (rc == ECORE_INVAL) { 1961d121a6b5SRasesh Mody DP_INFO(edev, "VF MTU Update TLV not supported\n"); 1962d121a6b5SRasesh Mody /* Recreate vport */ 1963d121a6b5SRasesh Mody rc = qede_start_vport(qdev, mtu); 1964d121a6b5SRasesh Mody if (rc != ECORE_SUCCESS) 1965d121a6b5SRasesh Mody goto err; 1966d121a6b5SRasesh Mody 1967d121a6b5SRasesh Mody /* Restore config lost due to vport stop */ 1968d121a6b5SRasesh Mody if (eth_dev->data->promiscuous) 1969d121a6b5SRasesh Mody qede_promiscuous_enable(eth_dev); 1970d121a6b5SRasesh Mody else 1971d121a6b5SRasesh Mody qede_promiscuous_disable(eth_dev); 1972d121a6b5SRasesh Mody 1973d121a6b5SRasesh Mody if (eth_dev->data->all_multicast) 1974d121a6b5SRasesh Mody qede_allmulticast_enable(eth_dev); 1975d121a6b5SRasesh Mody else 1976d121a6b5SRasesh Mody qede_allmulticast_disable(eth_dev); 1977d121a6b5SRasesh Mody 1978d121a6b5SRasesh Mody qede_vlan_offload_set(eth_dev, 1979d121a6b5SRasesh Mody qdev->vlan_offload_mask); 1980d121a6b5SRasesh Mody } else if (rc != ECORE_SUCCESS) { 1981d121a6b5SRasesh Mody goto err; 1982d121a6b5SRasesh Mody } 1983d121a6b5SRasesh Mody } 1984d121a6b5SRasesh Mody } 1985d121a6b5SRasesh Mody DP_INFO(edev, "%s MTU updated to %u\n", IS_PF(edev) ? "PF" : "VF", mtu); 1986d121a6b5SRasesh Mody 1987d121a6b5SRasesh Mody return 0; 1988d121a6b5SRasesh Mody 1989d121a6b5SRasesh Mody err: 1990d121a6b5SRasesh Mody DP_ERR(edev, "Failed to update MTU\n"); 1991d121a6b5SRasesh Mody return -1; 1992d121a6b5SRasesh Mody } 1993d121a6b5SRasesh Mody 19942ea6f76aSRasesh Mody static int qede_flow_ctrl_set(struct rte_eth_dev *eth_dev, 19952ea6f76aSRasesh Mody struct rte_eth_fc_conf *fc_conf) 19962ea6f76aSRasesh Mody { 19972ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 19982ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 19992ea6f76aSRasesh Mody struct qed_link_output current_link; 20002ea6f76aSRasesh Mody struct qed_link_params params; 20012ea6f76aSRasesh Mody 20022ea6f76aSRasesh Mody memset(¤t_link, 0, sizeof(current_link)); 20032ea6f76aSRasesh Mody qdev->ops->common->get_link(edev, ¤t_link); 20042ea6f76aSRasesh Mody 20052ea6f76aSRasesh Mody memset(¶ms, 0, sizeof(params)); 20062ea6f76aSRasesh Mody params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG; 20072ea6f76aSRasesh Mody if (fc_conf->autoneg) { 20082ea6f76aSRasesh Mody if (!(current_link.supported_caps & QEDE_SUPPORTED_AUTONEG)) { 20092ea6f76aSRasesh Mody DP_ERR(edev, "Autoneg not supported\n"); 20102ea6f76aSRasesh Mody return -EINVAL; 20112ea6f76aSRasesh Mody } 20122ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE; 20132ea6f76aSRasesh Mody } 20142ea6f76aSRasesh Mody 20152ea6f76aSRasesh Mody /* Pause is assumed to be supported (SUPPORTED_Pause) */ 2016295968d1SFerruh Yigit if (fc_conf->mode == RTE_ETH_FC_FULL) 20172ea6f76aSRasesh Mody params.pause_config |= (QED_LINK_PAUSE_TX_ENABLE | 20182ea6f76aSRasesh Mody QED_LINK_PAUSE_RX_ENABLE); 2019295968d1SFerruh Yigit if (fc_conf->mode == RTE_ETH_FC_TX_PAUSE) 20202ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_TX_ENABLE; 2021295968d1SFerruh Yigit if (fc_conf->mode == RTE_ETH_FC_RX_PAUSE) 20222ea6f76aSRasesh Mody params.pause_config |= QED_LINK_PAUSE_RX_ENABLE; 20232ea6f76aSRasesh Mody 20242ea6f76aSRasesh Mody params.link_up = true; 20252ea6f76aSRasesh Mody (void)qdev->ops->common->set_link(edev, ¶ms); 20262ea6f76aSRasesh Mody 20272ea6f76aSRasesh Mody return 0; 20282ea6f76aSRasesh Mody } 20292ea6f76aSRasesh Mody 20302ea6f76aSRasesh Mody static int qede_flow_ctrl_get(struct rte_eth_dev *eth_dev, 20312ea6f76aSRasesh Mody struct rte_eth_fc_conf *fc_conf) 20322ea6f76aSRasesh Mody { 20332ea6f76aSRasesh Mody struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 20342ea6f76aSRasesh Mody struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 20352ea6f76aSRasesh Mody struct qed_link_output current_link; 20362ea6f76aSRasesh Mody 20372ea6f76aSRasesh Mody memset(¤t_link, 0, sizeof(current_link)); 20382ea6f76aSRasesh Mody qdev->ops->common->get_link(edev, ¤t_link); 20392ea6f76aSRasesh Mody 20402ea6f76aSRasesh Mody if (current_link.pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE) 20412ea6f76aSRasesh Mody fc_conf->autoneg = true; 20422ea6f76aSRasesh Mody 20432ea6f76aSRasesh Mody if (current_link.pause_config & (QED_LINK_PAUSE_RX_ENABLE | 20442ea6f76aSRasesh Mody QED_LINK_PAUSE_TX_ENABLE)) 2045295968d1SFerruh Yigit fc_conf->mode = RTE_ETH_FC_FULL; 20462ea6f76aSRasesh Mody else if (current_link.pause_config & QED_LINK_PAUSE_RX_ENABLE) 2047295968d1SFerruh Yigit fc_conf->mode = RTE_ETH_FC_RX_PAUSE; 20482ea6f76aSRasesh Mody else if (current_link.pause_config & QED_LINK_PAUSE_TX_ENABLE) 2049295968d1SFerruh Yigit fc_conf->mode = RTE_ETH_FC_TX_PAUSE; 20502ea6f76aSRasesh Mody else 2051295968d1SFerruh Yigit fc_conf->mode = RTE_ETH_FC_NONE; 20522ea6f76aSRasesh Mody 20532ea6f76aSRasesh Mody return 0; 20542ea6f76aSRasesh Mody } 20552ea6f76aSRasesh Mody 20562ea6f76aSRasesh Mody static const uint32_t * 20572ea6f76aSRasesh Mody qede_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev) 20582ea6f76aSRasesh Mody { 20592ea6f76aSRasesh Mody static const uint32_t ptypes[] = { 2060fb88acb5SHarish Patil RTE_PTYPE_L2_ETHER, 2061fb88acb5SHarish Patil RTE_PTYPE_L2_ETHER_VLAN, 20622ea6f76aSRasesh Mody RTE_PTYPE_L3_IPV4, 20632ea6f76aSRasesh Mody RTE_PTYPE_L3_IPV6, 2064fb88acb5SHarish Patil RTE_PTYPE_L4_TCP, 2065fb88acb5SHarish Patil RTE_PTYPE_L4_UDP, 2066fb88acb5SHarish Patil RTE_PTYPE_TUNNEL_VXLAN, 2067fb88acb5SHarish Patil RTE_PTYPE_L4_FRAG, 2068d378cefaSShahed Shaikh RTE_PTYPE_TUNNEL_GENEVE, 2069e1e38962SHarish Patil RTE_PTYPE_TUNNEL_GRE, 2070fb88acb5SHarish Patil /* Inner */ 2071fb88acb5SHarish Patil RTE_PTYPE_INNER_L2_ETHER, 2072fb88acb5SHarish Patil RTE_PTYPE_INNER_L2_ETHER_VLAN, 2073fb88acb5SHarish Patil RTE_PTYPE_INNER_L3_IPV4, 2074fb88acb5SHarish Patil RTE_PTYPE_INNER_L3_IPV6, 2075fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_TCP, 2076fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_UDP, 2077fb88acb5SHarish Patil RTE_PTYPE_INNER_L4_FRAG, 20782ea6f76aSRasesh Mody RTE_PTYPE_UNKNOWN 20792ea6f76aSRasesh Mody }; 20802ea6f76aSRasesh Mody 20818de0c420SShahed Shaikh if (eth_dev->rx_pkt_burst == qede_recv_pkts || 208281f88049SShahed Shaikh eth_dev->rx_pkt_burst == qede_recv_pkts_regular || 20838de0c420SShahed Shaikh eth_dev->rx_pkt_burst == qede_recv_pkts_cmt) 20842ea6f76aSRasesh Mody return ptypes; 20852ea6f76aSRasesh Mody 20862ea6f76aSRasesh Mody return NULL; 20872ea6f76aSRasesh Mody } 20882ea6f76aSRasesh Mody 20897ab35bf6SHarish Patil static void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf) 20909c5d0a66SHarish Patil { 20919c5d0a66SHarish Patil *rss_caps = 0; 2092295968d1SFerruh Yigit *rss_caps |= (hf & RTE_ETH_RSS_IPV4) ? ECORE_RSS_IPV4 : 0; 2093295968d1SFerruh Yigit *rss_caps |= (hf & RTE_ETH_RSS_IPV6) ? ECORE_RSS_IPV6 : 0; 2094295968d1SFerruh Yigit *rss_caps |= (hf & RTE_ETH_RSS_IPV6_EX) ? ECORE_RSS_IPV6 : 0; 2095295968d1SFerruh Yigit *rss_caps |= (hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ? ECORE_RSS_IPV4_TCP : 0; 2096295968d1SFerruh Yigit *rss_caps |= (hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ? ECORE_RSS_IPV6_TCP : 0; 2097295968d1SFerruh Yigit *rss_caps |= (hf & RTE_ETH_RSS_IPV6_TCP_EX) ? ECORE_RSS_IPV6_TCP : 0; 2098295968d1SFerruh Yigit *rss_caps |= (hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ? ECORE_RSS_IPV4_UDP : 0; 2099295968d1SFerruh Yigit *rss_caps |= (hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ? ECORE_RSS_IPV6_UDP : 0; 21009c5d0a66SHarish Patil } 21019c5d0a66SHarish Patil 2102af785e47SRasesh Mody int qede_rss_hash_update(struct rte_eth_dev *eth_dev, 21034c98f276SSony Chacko struct rte_eth_rss_conf *rss_conf) 21044c98f276SSony Chacko { 21057ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 21067ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 21077ab35bf6SHarish Patil struct ecore_sp_vport_update_params vport_update_params; 21087ab35bf6SHarish Patil struct ecore_rss_params rss_params; 21097ab35bf6SHarish Patil struct ecore_hwfn *p_hwfn; 21104c98f276SSony Chacko uint32_t *key = (uint32_t *)rss_conf->rss_key; 21114c98f276SSony Chacko uint64_t hf = rss_conf->rss_hf; 21127ab35bf6SHarish Patil uint8_t len = rss_conf->rss_key_len; 2113235cbe4cSShahed Shaikh uint8_t idx, i, j, fpidx; 21147ab35bf6SHarish Patil int rc; 21154c98f276SSony Chacko 21164c98f276SSony Chacko memset(&vport_update_params, 0, sizeof(vport_update_params)); 21177ab35bf6SHarish Patil memset(&rss_params, 0, sizeof(rss_params)); 21187ab35bf6SHarish Patil 21197ab35bf6SHarish Patil DP_INFO(edev, "RSS hf = 0x%lx len = %u key = %p\n", 21207ab35bf6SHarish Patil (unsigned long)hf, len, key); 21214c98f276SSony Chacko 21229c5d0a66SHarish Patil if (hf != 0) { 21237ab35bf6SHarish Patil /* Enabling RSS */ 21247ab35bf6SHarish Patil DP_INFO(edev, "Enabling rss\n"); 21259c5d0a66SHarish Patil 21267ab35bf6SHarish Patil /* RSS caps */ 21277ab35bf6SHarish Patil qede_init_rss_caps(&rss_params.rss_caps, hf); 21287ab35bf6SHarish Patil rss_params.update_rss_capabilities = 1; 21297ab35bf6SHarish Patil 21307ab35bf6SHarish Patil /* RSS hash key */ 21317ab35bf6SHarish Patil if (key) { 21327ab35bf6SHarish Patil if (len > (ECORE_RSS_KEY_SIZE * sizeof(uint32_t))) { 21336ceb7ab8SIgor Russkikh len = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); 21346ceb7ab8SIgor Russkikh DP_NOTICE(edev, false, 21356ceb7ab8SIgor Russkikh "RSS key length too big, trimmed to %d\n", 21366ceb7ab8SIgor Russkikh len); 21377ab35bf6SHarish Patil } 21387ab35bf6SHarish Patil DP_INFO(edev, "Applying user supplied hash key\n"); 21397ab35bf6SHarish Patil rss_params.update_rss_key = 1; 21407ab35bf6SHarish Patil memcpy(&rss_params.rss_key, key, len); 21417ab35bf6SHarish Patil } 21427ab35bf6SHarish Patil rss_params.rss_enable = 1; 21434c98f276SSony Chacko } 21444c98f276SSony Chacko 21457ab35bf6SHarish Patil rss_params.update_rss_config = 1; 21467ab35bf6SHarish Patil /* tbl_size has to be set with capabilities */ 21477ab35bf6SHarish Patil rss_params.rss_table_size_log = 7; 21487ab35bf6SHarish Patil vport_update_params.vport_id = 0; 21497ab35bf6SHarish Patil 21507ab35bf6SHarish Patil for_each_hwfn(edev, i) { 2151235cbe4cSShahed Shaikh /* pass the L2 handles instead of qids */ 2152235cbe4cSShahed Shaikh for (j = 0 ; j < ECORE_RSS_IND_TABLE_SIZE ; j++) { 2153235cbe4cSShahed Shaikh idx = j % QEDE_RSS_COUNT(eth_dev); 2154235cbe4cSShahed Shaikh fpidx = idx * edev->num_hwfns + i; 2155235cbe4cSShahed Shaikh rss_params.rss_ind_table[j] = 2156235cbe4cSShahed Shaikh qdev->fp_array[fpidx].rxq->handle; 2157235cbe4cSShahed Shaikh } 2158235cbe4cSShahed Shaikh 2159235cbe4cSShahed Shaikh vport_update_params.rss_params = &rss_params; 2160235cbe4cSShahed Shaikh 21617ab35bf6SHarish Patil p_hwfn = &edev->hwfns[i]; 21627ab35bf6SHarish Patil vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid; 21637ab35bf6SHarish Patil rc = ecore_sp_vport_update(p_hwfn, &vport_update_params, 21647ab35bf6SHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 21657ab35bf6SHarish Patil if (rc) { 21667ab35bf6SHarish Patil DP_ERR(edev, "vport-update for RSS failed\n"); 21677ab35bf6SHarish Patil return rc; 21687ab35bf6SHarish Patil } 21697ab35bf6SHarish Patil } 21707ab35bf6SHarish Patil qdev->rss_enable = rss_params.rss_enable; 21717ab35bf6SHarish Patil 21727ab35bf6SHarish Patil /* Update local structure for hash query */ 21737ab35bf6SHarish Patil qdev->rss_conf.rss_hf = hf; 21747ab35bf6SHarish Patil qdev->rss_conf.rss_key_len = len; 21757ab35bf6SHarish Patil if (qdev->rss_enable) { 21767ab35bf6SHarish Patil if (qdev->rss_conf.rss_key == NULL) { 21777ab35bf6SHarish Patil qdev->rss_conf.rss_key = (uint8_t *)malloc(len); 21787ab35bf6SHarish Patil if (qdev->rss_conf.rss_key == NULL) { 21797ab35bf6SHarish Patil DP_ERR(edev, "No memory to store RSS key\n"); 21807ab35bf6SHarish Patil return -ENOMEM; 21817ab35bf6SHarish Patil } 21827ab35bf6SHarish Patil } 21837ab35bf6SHarish Patil if (key && len) { 21847ab35bf6SHarish Patil DP_INFO(edev, "Storing RSS key\n"); 21857ab35bf6SHarish Patil memcpy(qdev->rss_conf.rss_key, key, len); 21867ab35bf6SHarish Patil } 21877ab35bf6SHarish Patil } else if (!qdev->rss_enable && len == 0) { 21887ab35bf6SHarish Patil if (qdev->rss_conf.rss_key) { 21897ab35bf6SHarish Patil free(qdev->rss_conf.rss_key); 21907ab35bf6SHarish Patil qdev->rss_conf.rss_key = NULL; 21917ab35bf6SHarish Patil DP_INFO(edev, "Free RSS key\n"); 21927ab35bf6SHarish Patil } 21937ab35bf6SHarish Patil } 21947ab35bf6SHarish Patil 21957ab35bf6SHarish Patil return 0; 21967ab35bf6SHarish Patil } 21977ab35bf6SHarish Patil 21987ab35bf6SHarish Patil static int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev, 21996d9e26c4SSony Chacko struct rte_eth_rss_conf *rss_conf) 22006d9e26c4SSony Chacko { 22017ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 22026d9e26c4SSony Chacko 22037ab35bf6SHarish Patil rss_conf->rss_hf = qdev->rss_conf.rss_hf; 22047ab35bf6SHarish Patil rss_conf->rss_key_len = qdev->rss_conf.rss_key_len; 22056d9e26c4SSony Chacko 22067ab35bf6SHarish Patil if (rss_conf->rss_key && qdev->rss_conf.rss_key) 22077ab35bf6SHarish Patil memcpy(rss_conf->rss_key, qdev->rss_conf.rss_key, 22087ab35bf6SHarish Patil rss_conf->rss_key_len); 22096d9e26c4SSony Chacko return 0; 22106d9e26c4SSony Chacko } 22116d9e26c4SSony Chacko 2212af785e47SRasesh Mody int qede_rss_reta_update(struct rte_eth_dev *eth_dev, 2213e8876556SSony Chacko struct rte_eth_rss_reta_entry64 *reta_conf, 2214e8876556SSony Chacko uint16_t reta_size) 2215e8876556SSony Chacko { 22167ab35bf6SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); 22177ab35bf6SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 22187ab35bf6SHarish Patil struct ecore_sp_vport_update_params vport_update_params; 22198b3ee85eSRasesh Mody struct ecore_rss_params *params; 2220235cbe4cSShahed Shaikh uint16_t i, j, idx, fid, shift; 22217ab35bf6SHarish Patil struct ecore_hwfn *p_hwfn; 22227ab35bf6SHarish Patil uint8_t entry; 22238b3ee85eSRasesh Mody int rc = 0; 2224e8876556SSony Chacko 2225295968d1SFerruh Yigit if (reta_size > RTE_ETH_RSS_RETA_SIZE_128) { 2226e8876556SSony Chacko DP_ERR(edev, "reta_size %d is not supported by hardware\n", 2227e8876556SSony Chacko reta_size); 2228e8876556SSony Chacko return -EINVAL; 2229e8876556SSony Chacko } 2230e8876556SSony Chacko 2231e8876556SSony Chacko memset(&vport_update_params, 0, sizeof(vport_update_params)); 2232235cbe4cSShahed Shaikh params = rte_zmalloc("qede_rss", sizeof(*params), RTE_CACHE_LINE_SIZE); 2233ef86e67aSRongQiang Xie if (params == NULL) { 2234ef86e67aSRongQiang Xie DP_ERR(edev, "failed to allocate memory\n"); 2235ef86e67aSRongQiang Xie return -ENOMEM; 2236ef86e67aSRongQiang Xie } 2237e8876556SSony Chacko 22388b3ee85eSRasesh Mody params->update_rss_ind_table = 1; 22398b3ee85eSRasesh Mody params->rss_table_size_log = 7; 22408b3ee85eSRasesh Mody params->update_rss_config = 1; 22418b3ee85eSRasesh Mody 2242e8876556SSony Chacko vport_update_params.vport_id = 0; 22437ab35bf6SHarish Patil /* Use the current value of rss_enable */ 22448b3ee85eSRasesh Mody params->rss_enable = qdev->rss_enable; 22458b3ee85eSRasesh Mody vport_update_params.rss_params = params; 2246e8876556SSony Chacko 22477ab35bf6SHarish Patil for_each_hwfn(edev, i) { 2248235cbe4cSShahed Shaikh for (j = 0; j < reta_size; j++) { 2249295968d1SFerruh Yigit idx = j / RTE_ETH_RETA_GROUP_SIZE; 2250295968d1SFerruh Yigit shift = j % RTE_ETH_RETA_GROUP_SIZE; 2251235cbe4cSShahed Shaikh if (reta_conf[idx].mask & (1ULL << shift)) { 2252235cbe4cSShahed Shaikh entry = reta_conf[idx].reta[shift]; 2253235cbe4cSShahed Shaikh fid = entry * edev->num_hwfns + i; 2254235cbe4cSShahed Shaikh /* Pass rxq handles to ecore */ 2255235cbe4cSShahed Shaikh params->rss_ind_table[j] = 2256235cbe4cSShahed Shaikh qdev->fp_array[fid].rxq->handle; 2257235cbe4cSShahed Shaikh /* Update the local copy for RETA query cmd */ 2258235cbe4cSShahed Shaikh qdev->rss_ind_table[j] = entry; 2259235cbe4cSShahed Shaikh } 2260235cbe4cSShahed Shaikh } 2261235cbe4cSShahed Shaikh 22627ab35bf6SHarish Patil p_hwfn = &edev->hwfns[i]; 22637ab35bf6SHarish Patil vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid; 22647ab35bf6SHarish Patil rc = ecore_sp_vport_update(p_hwfn, &vport_update_params, 22657ab35bf6SHarish Patil ECORE_SPQ_MODE_EBLOCK, NULL); 22667ab35bf6SHarish Patil if (rc) { 22677ab35bf6SHarish Patil DP_ERR(edev, "vport-update for RSS failed\n"); 22688b3ee85eSRasesh Mody goto out; 22697ab35bf6SHarish Patil } 2270e8876556SSony Chacko } 2271e8876556SSony Chacko 22728b3ee85eSRasesh Mody out: 22738b3ee85eSRasesh Mody rte_free(params); 22748b3ee85eSRasesh Mody return rc; 22757ab35bf6SHarish Patil } 22767ab35bf6SHarish Patil 22777ab35bf6SHarish Patil static int qede_rss_reta_query(struct rte_eth_dev *eth_dev, 22783dadf73eSSony Chacko struct rte_eth_rss_reta_entry64 *reta_conf, 22793dadf73eSSony Chacko uint16_t reta_size) 22803dadf73eSSony Chacko { 22813dadf73eSSony Chacko struct qede_dev *qdev = eth_dev->data->dev_private; 22827ab35bf6SHarish Patil struct ecore_dev *edev = &qdev->edev; 22833dadf73eSSony Chacko uint16_t i, idx, shift; 22847ab35bf6SHarish Patil uint8_t entry; 22853dadf73eSSony Chacko 2286295968d1SFerruh Yigit if (reta_size > RTE_ETH_RSS_RETA_SIZE_128) { 22873dadf73eSSony Chacko DP_ERR(edev, "reta_size %d is not supported\n", 22883dadf73eSSony Chacko reta_size); 22897ab35bf6SHarish Patil return -EINVAL; 22903dadf73eSSony Chacko } 22913dadf73eSSony Chacko 22923dadf73eSSony Chacko for (i = 0; i < reta_size; i++) { 2293295968d1SFerruh Yigit idx = i / RTE_ETH_RETA_GROUP_SIZE; 2294295968d1SFerruh Yigit shift = i % RTE_ETH_RETA_GROUP_SIZE; 22953dadf73eSSony Chacko if (reta_conf[idx].mask & (1ULL << shift)) { 22967ab35bf6SHarish Patil entry = qdev->rss_ind_table[i]; 22973dadf73eSSony Chacko reta_conf[idx].reta[shift] = entry; 22983dadf73eSSony Chacko } 22993dadf73eSSony Chacko } 23003dadf73eSSony Chacko 23013dadf73eSSony Chacko return 0; 23023dadf73eSSony Chacko } 23033dadf73eSSony Chacko 23044c4bdadfSHarish Patil 23054c4bdadfSHarish Patil 2306af785e47SRasesh Mody static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 2307200645acSSony Chacko { 23081ef4c3a5SHarish Patil struct qede_dev *qdev = QEDE_INIT_QDEV(dev); 23091ef4c3a5SHarish Patil struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); 23101ef4c3a5SHarish Patil struct qede_fastpath *fp; 23111ef4c3a5SHarish Patil uint32_t frame_size; 23121ef4c3a5SHarish Patil uint16_t bufsz; 23139e334305SRasesh Mody bool restart = false; 2314318d7da3SShahed Shaikh int i, rc; 2315200645acSSony Chacko 23161ef4c3a5SHarish Patil PMD_INIT_FUNC_TRACE(edev); 23171bb4a528SFerruh Yigit 23181bb4a528SFerruh Yigit frame_size = mtu + QEDE_MAX_ETHER_HDR_LEN; 2319200645acSSony Chacko if (!dev->data->scattered_rx && 23201ef4c3a5SHarish Patil frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) { 23211ef4c3a5SHarish Patil DP_INFO(edev, "MTU greater than minimum RX buffer size of %u\n", 23221ef4c3a5SHarish Patil dev->data->min_rx_buf_size); 2323200645acSSony Chacko return -EINVAL; 23241ef4c3a5SHarish Patil } 23259e334305SRasesh Mody if (dev->data->dev_started) { 23269e334305SRasesh Mody dev->data->dev_started = 0; 232762024eb8SIvan Ilchenko rc = qede_dev_stop(dev); 232862024eb8SIvan Ilchenko if (rc != 0) 232962024eb8SIvan Ilchenko return rc; 23309e334305SRasesh Mody restart = true; 23319e334305SRasesh Mody } 23321ef4c3a5SHarish Patil rte_delay_ms(1000); 233329bb154fSShahed Shaikh qdev->new_mtu = mtu; 2334dd28bc8cSHarish Patil 23351ef4c3a5SHarish Patil /* Fix up RX buf size for all queues of the port */ 23368de0c420SShahed Shaikh for (i = 0; i < qdev->num_rx_queues; i++) { 23371ef4c3a5SHarish Patil fp = &qdev->fp_array[i]; 23389e334305SRasesh Mody if (fp->rxq != NULL) { 23391ef4c3a5SHarish Patil bufsz = (uint16_t)rte_pktmbuf_data_room_size( 23401ef4c3a5SHarish Patil fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM; 23417be78d02SJosh Soref /* cache align the mbuf size to simplify rx_buf_size 2342318d7da3SShahed Shaikh * calculation 2343318d7da3SShahed Shaikh */ 2344318d7da3SShahed Shaikh bufsz = QEDE_FLOOR_TO_CACHE_LINE_SIZE(bufsz); 2345318d7da3SShahed Shaikh rc = qede_calc_rx_buf_size(dev, bufsz, frame_size); 2346318d7da3SShahed Shaikh if (rc < 0) 2347318d7da3SShahed Shaikh return rc; 2348318d7da3SShahed Shaikh 2349318d7da3SShahed Shaikh fp->rxq->rx_buf_size = rc; 23501ef4c3a5SHarish Patil } 23519e334305SRasesh Mody } 2352dd28bc8cSHarish Patil 23539e334305SRasesh Mody if (!dev->data->dev_started && restart) { 23549e334305SRasesh Mody qede_dev_start(dev); 23559e334305SRasesh Mody dev->data->dev_started = 1; 23569e334305SRasesh Mody } 2357dd28bc8cSHarish Patil 2358200645acSSony Chacko return 0; 2359200645acSSony Chacko } 2360200645acSSony Chacko 2361ad4d092bSShahed Shaikh static int 2362ad4d092bSShahed Shaikh qede_dev_reset(struct rte_eth_dev *dev) 2363ad4d092bSShahed Shaikh { 2364ad4d092bSShahed Shaikh int ret; 2365ad4d092bSShahed Shaikh 2366ad4d092bSShahed Shaikh ret = qede_eth_dev_uninit(dev); 2367ad4d092bSShahed Shaikh if (ret) 2368ad4d092bSShahed Shaikh return ret; 2369ad4d092bSShahed Shaikh 2370ad4d092bSShahed Shaikh return qede_eth_dev_init(dev); 2371ad4d092bSShahed Shaikh } 2372ad4d092bSShahed Shaikh 23737483341aSXueming Li static void 23747483341aSXueming Li qede_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid) 23757483341aSXueming Li { 23767483341aSXueming Li qede_rx_queue_release(dev->data->rx_queues[qid]); 23777483341aSXueming Li } 23787483341aSXueming Li 23797483341aSXueming Li static void 23807483341aSXueming Li qede_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid) 23817483341aSXueming Li { 23827483341aSXueming Li qede_tx_queue_release(dev->data->tx_queues[qid]); 23837483341aSXueming Li } 23847483341aSXueming Li 23852ea6f76aSRasesh Mody static const struct eth_dev_ops qede_eth_dev_ops = { 23862ea6f76aSRasesh Mody .dev_configure = qede_dev_configure, 23872ea6f76aSRasesh Mody .dev_infos_get = qede_dev_info_get, 23882ea6f76aSRasesh Mody .rx_queue_setup = qede_rx_queue_setup, 23897483341aSXueming Li .rx_queue_release = qede_dev_rx_queue_release, 23902ea6f76aSRasesh Mody .tx_queue_setup = qede_tx_queue_setup, 23917483341aSXueming Li .tx_queue_release = qede_dev_tx_queue_release, 23922ea6f76aSRasesh Mody .dev_start = qede_dev_start, 2393ad4d092bSShahed Shaikh .dev_reset = qede_dev_reset, 23942ea6f76aSRasesh Mody .dev_set_link_up = qede_dev_set_link_up, 23952ea6f76aSRasesh Mody .dev_set_link_down = qede_dev_set_link_down, 23962ea6f76aSRasesh Mody .link_update = qede_link_update, 23972ea6f76aSRasesh Mody .promiscuous_enable = qede_promiscuous_enable, 23982ea6f76aSRasesh Mody .promiscuous_disable = qede_promiscuous_disable, 23992ea6f76aSRasesh Mody .allmulticast_enable = qede_allmulticast_enable, 24002ea6f76aSRasesh Mody .allmulticast_disable = qede_allmulticast_disable, 2401413ecf29SHarish Patil .set_mc_addr_list = qede_set_mc_addr_list, 24022ea6f76aSRasesh Mody .dev_stop = qede_dev_stop, 24032ea6f76aSRasesh Mody .dev_close = qede_dev_close, 24042ea6f76aSRasesh Mody .stats_get = qede_get_stats, 24055cdd769aSRasesh Mody .stats_reset = qede_reset_stats, 2406d1216e22SRasesh Mody .xstats_get = qede_get_xstats, 2407d1216e22SRasesh Mody .xstats_reset = qede_reset_xstats, 2408d1216e22SRasesh Mody .xstats_get_names = qede_get_xstats_names, 24092ea6f76aSRasesh Mody .mac_addr_add = qede_mac_addr_add, 24102ea6f76aSRasesh Mody .mac_addr_remove = qede_mac_addr_remove, 24112ea6f76aSRasesh Mody .mac_addr_set = qede_mac_addr_set, 24122ea6f76aSRasesh Mody .vlan_offload_set = qede_vlan_offload_set, 24132ea6f76aSRasesh Mody .vlan_filter_set = qede_vlan_filter_set, 24142ea6f76aSRasesh Mody .flow_ctrl_set = qede_flow_ctrl_set, 24152ea6f76aSRasesh Mody .flow_ctrl_get = qede_flow_ctrl_get, 24162ea6f76aSRasesh Mody .dev_supported_ptypes_get = qede_dev_supported_ptypes_get, 24174c98f276SSony Chacko .rss_hash_update = qede_rss_hash_update, 24186d9e26c4SSony Chacko .rss_hash_conf_get = qede_rss_hash_conf_get, 2419e8876556SSony Chacko .reta_update = qede_rss_reta_update, 24203dadf73eSSony Chacko .reta_query = qede_rss_reta_query, 2421200645acSSony Chacko .mtu_set = qede_set_mtu, 2422fb7ad441SThomas Monjalon .flow_ops_get = qede_dev_flow_ops_get, 242352d94b57SHarish Patil .udp_tunnel_port_add = qede_udp_dst_port_add, 242452d94b57SHarish Patil .udp_tunnel_port_del = qede_udp_dst_port_del, 2425f97b56f9SRasesh Mody .fw_version_get = qede_fw_version_get, 2426a50d7cbbSRasesh Mody .get_reg = qede_get_regs, 24272ea6f76aSRasesh Mody }; 24282ea6f76aSRasesh Mody 242986a2265eSRasesh Mody static const struct eth_dev_ops qede_eth_vf_dev_ops = { 243086a2265eSRasesh Mody .dev_configure = qede_dev_configure, 243186a2265eSRasesh Mody .dev_infos_get = qede_dev_info_get, 243286a2265eSRasesh Mody .rx_queue_setup = qede_rx_queue_setup, 24337483341aSXueming Li .rx_queue_release = qede_dev_rx_queue_release, 243486a2265eSRasesh Mody .tx_queue_setup = qede_tx_queue_setup, 24357483341aSXueming Li .tx_queue_release = qede_dev_tx_queue_release, 243686a2265eSRasesh Mody .dev_start = qede_dev_start, 2437ad4d092bSShahed Shaikh .dev_reset = qede_dev_reset, 243886a2265eSRasesh Mody .dev_set_link_up = qede_dev_set_link_up, 243986a2265eSRasesh Mody .dev_set_link_down = qede_dev_set_link_down, 244086a2265eSRasesh Mody .link_update = qede_link_update, 244186a2265eSRasesh Mody .promiscuous_enable = qede_promiscuous_enable, 244286a2265eSRasesh Mody .promiscuous_disable = qede_promiscuous_disable, 244386a2265eSRasesh Mody .allmulticast_enable = qede_allmulticast_enable, 244486a2265eSRasesh Mody .allmulticast_disable = qede_allmulticast_disable, 2445413ecf29SHarish Patil .set_mc_addr_list = qede_set_mc_addr_list, 244686a2265eSRasesh Mody .dev_stop = qede_dev_stop, 244786a2265eSRasesh Mody .dev_close = qede_dev_close, 244886a2265eSRasesh Mody .stats_get = qede_get_stats, 244986a2265eSRasesh Mody .stats_reset = qede_reset_stats, 2450d1216e22SRasesh Mody .xstats_get = qede_get_xstats, 2451d1216e22SRasesh Mody .xstats_reset = qede_reset_xstats, 2452d1216e22SRasesh Mody .xstats_get_names = qede_get_xstats_names, 245386a2265eSRasesh Mody .vlan_offload_set = qede_vlan_offload_set, 245486a2265eSRasesh Mody .vlan_filter_set = qede_vlan_filter_set, 245586a2265eSRasesh Mody .dev_supported_ptypes_get = qede_dev_supported_ptypes_get, 24564c98f276SSony Chacko .rss_hash_update = qede_rss_hash_update, 24576d9e26c4SSony Chacko .rss_hash_conf_get = qede_rss_hash_conf_get, 2458e8876556SSony Chacko .reta_update = qede_rss_reta_update, 24593dadf73eSSony Chacko .reta_query = qede_rss_reta_query, 2460200645acSSony Chacko .mtu_set = qede_set_mtu, 2461e0947ed9SHarish Patil .udp_tunnel_port_add = qede_udp_dst_port_add, 2462e0947ed9SHarish Patil .udp_tunnel_port_del = qede_udp_dst_port_del, 2463c7641841SShahed Shaikh .mac_addr_add = qede_mac_addr_add, 2464c7641841SShahed Shaikh .mac_addr_remove = qede_mac_addr_remove, 2465c7641841SShahed Shaikh .mac_addr_set = qede_mac_addr_set, 2466f97b56f9SRasesh Mody .fw_version_get = qede_fw_version_get, 246786a2265eSRasesh Mody }; 246886a2265eSRasesh Mody 24692ea6f76aSRasesh Mody static void qede_update_pf_params(struct ecore_dev *edev) 24702ea6f76aSRasesh Mody { 24712ea6f76aSRasesh Mody struct ecore_pf_params pf_params; 2472528fcfabSHarish Patil 24732ea6f76aSRasesh Mody memset(&pf_params, 0, sizeof(struct ecore_pf_params)); 2474528fcfabSHarish Patil pf_params.eth_pf_params.num_cons = QEDE_PF_NUM_CONNS; 247562207535SHarish Patil pf_params.eth_pf_params.num_arfs_filters = QEDE_RFS_MAX_FLTR; 24762ea6f76aSRasesh Mody qed_ops->common->update_pf_params(edev, &pf_params); 24772ea6f76aSRasesh Mody } 24782ea6f76aSRasesh Mody 2479c176fd86SManish Chopra static void qede_generate_random_mac_addr(struct rte_ether_addr *mac_addr) 2480c176fd86SManish Chopra { 2481c176fd86SManish Chopra uint64_t random; 2482c176fd86SManish Chopra 2483c176fd86SManish Chopra /* Set Organizationally Unique Identifier (OUI) prefix. */ 2484c176fd86SManish Chopra mac_addr->addr_bytes[0] = 0x00; 2485c176fd86SManish Chopra mac_addr->addr_bytes[1] = 0x09; 2486c176fd86SManish Chopra mac_addr->addr_bytes[2] = 0xC0; 2487c176fd86SManish Chopra 2488c176fd86SManish Chopra /* Force indication of locally assigned MAC address. */ 2489c176fd86SManish Chopra mac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR; 2490c176fd86SManish Chopra 2491c176fd86SManish Chopra /* Generate the last 3 bytes of the MAC address with a random number. */ 2492c176fd86SManish Chopra random = rte_rand(); 2493c176fd86SManish Chopra 2494c176fd86SManish Chopra memcpy(&mac_addr->addr_bytes[3], &random, 3); 2495c176fd86SManish Chopra } 2496c176fd86SManish Chopra 24972ea6f76aSRasesh Mody static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf) 24982ea6f76aSRasesh Mody { 24992ea6f76aSRasesh Mody struct rte_pci_device *pci_dev; 25002ea6f76aSRasesh Mody struct rte_pci_addr pci_addr; 25012ea6f76aSRasesh Mody struct qede_dev *adapter; 25022ea6f76aSRasesh Mody struct ecore_dev *edev; 25032ea6f76aSRasesh Mody struct qed_dev_eth_info dev_info; 25042ea6f76aSRasesh Mody struct qed_slowpath_params params; 25052ea6f76aSRasesh Mody static bool do_once = true; 25062ea6f76aSRasesh Mody uint8_t bulletin_change; 250735b2d13fSOlivier Matz uint8_t vf_mac[RTE_ETHER_ADDR_LEN]; 25082ea6f76aSRasesh Mody uint8_t is_mac_forced; 2509c176fd86SManish Chopra bool is_mac_exist = false; 25102ea6f76aSRasesh Mody /* Fix up ecore debug level */ 25112ea6f76aSRasesh Mody uint32_t dp_module = ~0 & ~ECORE_MSG_HW; 25122ea6f76aSRasesh Mody uint8_t dp_level = ECORE_LEVEL_VERBOSE; 2513245aec28SShahed Shaikh uint32_t int_mode; 25142ea6f76aSRasesh Mody int rc; 25152ea6f76aSRasesh Mody 25162ea6f76aSRasesh Mody /* Extract key data structures */ 25172ea6f76aSRasesh Mody adapter = eth_dev->data->dev_private; 25188aab5d6fSRasesh Mody adapter->ethdev = eth_dev; 25192ea6f76aSRasesh Mody edev = &adapter->edev; 2520c0802544SFerruh Yigit pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 2521d4b7f673SJan Blunck pci_addr = pci_dev->addr; 25222ea6f76aSRasesh Mody 25232ea6f76aSRasesh Mody PMD_INIT_FUNC_TRACE(edev); 25242ea6f76aSRasesh Mody 25252ea6f76aSRasesh Mody snprintf(edev->name, NAME_SIZE, PCI_SHORT_PRI_FMT ":dpdk-port-%u", 25262ea6f76aSRasesh Mody pci_addr.bus, pci_addr.devid, pci_addr.function, 25272ea6f76aSRasesh Mody eth_dev->data->port_id); 25282ea6f76aSRasesh Mody 25292ea6f76aSRasesh Mody if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 25304ffa2af9SRasesh Mody DP_ERR(edev, "Skipping device init from secondary process\n"); 25312ea6f76aSRasesh Mody return 0; 25322ea6f76aSRasesh Mody } 25332ea6f76aSRasesh Mody 25342ea6f76aSRasesh Mody rte_eth_copy_pci_info(eth_dev, pci_dev); 2535f30e69b4SFerruh Yigit eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 25362ea6f76aSRasesh Mody 2537fb58ad9eSRasesh Mody /* @DPDK */ 2538fb58ad9eSRasesh Mody edev->vendor_id = pci_dev->id.vendor_id; 2539fb58ad9eSRasesh Mody edev->device_id = pci_dev->id.device_id; 2540fb58ad9eSRasesh Mody 25415cdd769aSRasesh Mody qed_ops = qed_get_eth_ops(); 25425cdd769aSRasesh Mody if (!qed_ops) { 25435cdd769aSRasesh Mody DP_ERR(edev, "Failed to get qed_eth_ops_pass\n"); 25442b5243d7SRasesh Mody rc = -EINVAL; 25452b5243d7SRasesh Mody goto err; 25465cdd769aSRasesh Mody } 25475cdd769aSRasesh Mody 25482ea6f76aSRasesh Mody DP_INFO(edev, "Starting qede probe\n"); 25494c4bdadfSHarish Patil rc = qed_ops->common->probe(edev, pci_dev, dp_module, 25504c4bdadfSHarish Patil dp_level, is_vf); 25512ea6f76aSRasesh Mody if (rc != 0) { 25522ea6f76aSRasesh Mody DP_ERR(edev, "qede probe failed rc %d\n", rc); 25532b5243d7SRasesh Mody rc = -ENODEV; 25542b5243d7SRasesh Mody goto err; 25552ea6f76aSRasesh Mody } 25562ea6f76aSRasesh Mody qede_update_pf_params(edev); 2557245aec28SShahed Shaikh 2558d61138d4SHarman Kalra switch (rte_intr_type_get(pci_dev->intr_handle)) { 2559245aec28SShahed Shaikh case RTE_INTR_HANDLE_UIO_INTX: 2560245aec28SShahed Shaikh case RTE_INTR_HANDLE_VFIO_LEGACY: 2561245aec28SShahed Shaikh int_mode = ECORE_INT_MODE_INTA; 2562d61138d4SHarman Kalra rte_intr_callback_register(pci_dev->intr_handle, 2563245aec28SShahed Shaikh qede_interrupt_handler_intx, 2564245aec28SShahed Shaikh (void *)eth_dev); 2565245aec28SShahed Shaikh break; 2566245aec28SShahed Shaikh default: 2567245aec28SShahed Shaikh int_mode = ECORE_INT_MODE_MSIX; 2568d61138d4SHarman Kalra rte_intr_callback_register(pci_dev->intr_handle, 2569245aec28SShahed Shaikh qede_interrupt_handler, 2570245aec28SShahed Shaikh (void *)eth_dev); 2571245aec28SShahed Shaikh } 2572245aec28SShahed Shaikh 2573d61138d4SHarman Kalra if (rte_intr_enable(pci_dev->intr_handle)) { 25742ea6f76aSRasesh Mody DP_ERR(edev, "rte_intr_enable() failed\n"); 25752b5243d7SRasesh Mody rc = -ENODEV; 25762b5243d7SRasesh Mody goto err; 25772ea6f76aSRasesh Mody } 25782ea6f76aSRasesh Mody 25792ea6f76aSRasesh Mody /* Start the Slowpath-process */ 25802ea6f76aSRasesh Mody memset(¶ms, 0, sizeof(struct qed_slowpath_params)); 2581245aec28SShahed Shaikh 2582245aec28SShahed Shaikh params.int_mode = int_mode; 25837eca78ceSHarish Patil params.drv_major = QEDE_PMD_VERSION_MAJOR; 25847eca78ceSHarish Patil params.drv_minor = QEDE_PMD_VERSION_MINOR; 25857eca78ceSHarish Patil params.drv_rev = QEDE_PMD_VERSION_REVISION; 25867eca78ceSHarish Patil params.drv_eng = QEDE_PMD_VERSION_PATCH; 25877eca78ceSHarish Patil strncpy((char *)params.name, QEDE_PMD_VER_PREFIX, 25887eca78ceSHarish Patil QEDE_PMD_DRV_VER_STR_SIZE); 25892ea6f76aSRasesh Mody 2590a60704d1SRasesh Mody qede_assign_rxtx_handlers(eth_dev, true); 25918de0c420SShahed Shaikh eth_dev->tx_pkt_prepare = qede_xmit_prep_pkts; 25928de0c420SShahed Shaikh 25932af14ca7SHarish Patil /* For CMT mode device do periodic polling for slowpath events. 25942af14ca7SHarish Patil * This is required since uio device uses only one MSI-x 25952af14ca7SHarish Patil * interrupt vector but we need one for each engine. 25962af14ca7SHarish Patil */ 2597c0845c33SRasesh Mody if (ECORE_IS_CMT(edev) && IS_PF(edev)) { 25980833120fSShahed Shaikh rc = rte_eal_alarm_set(QEDE_SP_TIMER_PERIOD, 25992af14ca7SHarish Patil qede_poll_sp_sb_cb, 26002af14ca7SHarish Patil (void *)eth_dev); 26012af14ca7SHarish Patil if (rc != 0) { 26022af14ca7SHarish Patil DP_ERR(edev, "Unable to start periodic" 26032af14ca7SHarish Patil " timer rc %d\n", rc); 26042b5243d7SRasesh Mody rc = -EINVAL; 26052b5243d7SRasesh Mody goto err; 26062af14ca7SHarish Patil } 26072af14ca7SHarish Patil } 26082af14ca7SHarish Patil 26092ea6f76aSRasesh Mody rc = qed_ops->common->slowpath_start(edev, ¶ms); 26102ea6f76aSRasesh Mody if (rc) { 26112ea6f76aSRasesh Mody DP_ERR(edev, "Cannot start slowpath rc = %d\n", rc); 26122af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 26132af14ca7SHarish Patil (void *)eth_dev); 26142b5243d7SRasesh Mody rc = -ENODEV; 26152b5243d7SRasesh Mody goto err; 26162ea6f76aSRasesh Mody } 26172ea6f76aSRasesh Mody 26182ea6f76aSRasesh Mody rc = qed_ops->fill_dev_info(edev, &dev_info); 26192ea6f76aSRasesh Mody if (rc) { 26202ea6f76aSRasesh Mody DP_ERR(edev, "Cannot get device_info rc %d\n", rc); 26212ea6f76aSRasesh Mody qed_ops->common->slowpath_stop(edev); 26222ea6f76aSRasesh Mody qed_ops->common->remove(edev); 26232af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 26242af14ca7SHarish Patil (void *)eth_dev); 26252b5243d7SRasesh Mody rc = -ENODEV; 26262b5243d7SRasesh Mody goto err; 26272ea6f76aSRasesh Mody } 26282ea6f76aSRasesh Mody 26292ea6f76aSRasesh Mody qede_alloc_etherdev(adapter, &dev_info); 26302ea6f76aSRasesh Mody 26312b5243d7SRasesh Mody if (do_once) { 2632f97b56f9SRasesh Mody qede_print_adapter_info(eth_dev); 26332b5243d7SRasesh Mody do_once = false; 26342b5243d7SRasesh Mody } 26352b5243d7SRasesh Mody 2636de5588afSRasesh Mody adapter->ops->common->set_name(edev, edev->name); 26372ea6f76aSRasesh Mody 26382ea6f76aSRasesh Mody if (!is_vf) 26393320ca8cSRasesh Mody adapter->dev_info.num_mac_filters = 26402ea6f76aSRasesh Mody (uint32_t)RESC_NUM(ECORE_LEADING_HWFN(edev), 26412ea6f76aSRasesh Mody ECORE_MAC); 26422ea6f76aSRasesh Mody else 264386a2265eSRasesh Mody ecore_vf_get_num_mac_filters(ECORE_LEADING_HWFN(edev), 26443320ca8cSRasesh Mody (uint32_t *)&adapter->dev_info.num_mac_filters); 26452ea6f76aSRasesh Mody 26462ea6f76aSRasesh Mody /* Allocate memory for storing MAC addr */ 26472ea6f76aSRasesh Mody eth_dev->data->mac_addrs = rte_zmalloc(edev->name, 264835b2d13fSOlivier Matz (RTE_ETHER_ADDR_LEN * 26493320ca8cSRasesh Mody adapter->dev_info.num_mac_filters), 26502ea6f76aSRasesh Mody RTE_CACHE_LINE_SIZE); 26512ea6f76aSRasesh Mody 26522ea6f76aSRasesh Mody if (eth_dev->data->mac_addrs == NULL) { 26532ea6f76aSRasesh Mody DP_ERR(edev, "Failed to allocate MAC address\n"); 26542ea6f76aSRasesh Mody qed_ops->common->slowpath_stop(edev); 26552ea6f76aSRasesh Mody qed_ops->common->remove(edev); 26562af14ca7SHarish Patil rte_eal_alarm_cancel(qede_poll_sp_sb_cb, 26572af14ca7SHarish Patil (void *)eth_dev); 26582ea6f76aSRasesh Mody return -ENOMEM; 26592ea6f76aSRasesh Mody } 26602ea6f76aSRasesh Mody 266186a2265eSRasesh Mody if (!is_vf) { 2662538da7a1SOlivier Matz rte_ether_addr_copy((struct rte_ether_addr *)edev->hwfns[0]. 26632ea6f76aSRasesh Mody hw_info.hw_mac_addr, 26642ea6f76aSRasesh Mody ð_dev->data->mac_addrs[0]); 2665538da7a1SOlivier Matz rte_ether_addr_copy(ð_dev->data->mac_addrs[0], 266686a2265eSRasesh Mody &adapter->primary_mac); 266786a2265eSRasesh Mody } else { 266886a2265eSRasesh Mody ecore_vf_read_bulletin(ECORE_LEADING_HWFN(edev), 266986a2265eSRasesh Mody &bulletin_change); 267086a2265eSRasesh Mody if (bulletin_change) { 267186a2265eSRasesh Mody is_mac_exist = 267286a2265eSRasesh Mody ecore_vf_bulletin_get_forced_mac( 267386a2265eSRasesh Mody ECORE_LEADING_HWFN(edev), 267486a2265eSRasesh Mody vf_mac, 267586a2265eSRasesh Mody &is_mac_forced); 2676c7641841SShahed Shaikh if (is_mac_exist) { 267786a2265eSRasesh Mody DP_INFO(edev, "VF macaddr received from PF\n"); 2678538da7a1SOlivier Matz rte_ether_addr_copy( 26796d13ea8eSOlivier Matz (struct rte_ether_addr *)&vf_mac, 268086a2265eSRasesh Mody ð_dev->data->mac_addrs[0]); 2681538da7a1SOlivier Matz rte_ether_addr_copy( 2682538da7a1SOlivier Matz ð_dev->data->mac_addrs[0], 268386a2265eSRasesh Mody &adapter->primary_mac); 268486a2265eSRasesh Mody } else { 26854ffa2af9SRasesh Mody DP_ERR(edev, "No VF macaddr assigned\n"); 268686a2265eSRasesh Mody } 268786a2265eSRasesh Mody } 2688c176fd86SManish Chopra 2689c176fd86SManish Chopra /* If MAC doesn't exist from PF, generate random one */ 2690c176fd86SManish Chopra if (!is_mac_exist) { 2691c176fd86SManish Chopra struct rte_ether_addr *mac_addr; 2692c176fd86SManish Chopra 2693c176fd86SManish Chopra mac_addr = (struct rte_ether_addr *)&vf_mac; 2694c176fd86SManish Chopra qede_generate_random_mac_addr(mac_addr); 2695c176fd86SManish Chopra 2696c176fd86SManish Chopra rte_ether_addr_copy(mac_addr, 2697c176fd86SManish Chopra ð_dev->data->mac_addrs[0]); 2698c176fd86SManish Chopra 2699c176fd86SManish Chopra rte_ether_addr_copy(ð_dev->data->mac_addrs[0], 2700c176fd86SManish Chopra &adapter->primary_mac); 2701c176fd86SManish Chopra } 270286a2265eSRasesh Mody } 27032ea6f76aSRasesh Mody 270486a2265eSRasesh Mody eth_dev->dev_ops = (is_vf) ? &qede_eth_vf_dev_ops : &qede_eth_dev_ops; 2705cbfc6111SFerruh Yigit eth_dev->rx_descriptor_status = qede_rx_descriptor_status; 27062ea6f76aSRasesh Mody 27074c4bdadfSHarish Patil adapter->num_tx_queues = 0; 27084c4bdadfSHarish Patil adapter->num_rx_queues = 0; 2709f5765f66SShahed Shaikh SLIST_INIT(&adapter->arfs_info.arfs_list_head); 27104c4bdadfSHarish Patil SLIST_INIT(&adapter->vlan_list_head); 27114c4bdadfSHarish Patil SLIST_INIT(&adapter->uc_list_head); 2712413ecf29SHarish Patil SLIST_INIT(&adapter->mc_list_head); 271335b2d13fSOlivier Matz adapter->mtu = RTE_ETHER_MTU; 2714dd28bc8cSHarish Patil adapter->vport_started = false; 2715dd28bc8cSHarish Patil 2716c8b34b7eSHarish Patil /* VF tunnel offloads is enabled by default in PF driver */ 2717c8b34b7eSHarish Patil adapter->vxlan.num_filters = 0; 27187cf0f102SHarish Patil adapter->geneve.num_filters = 0; 2719e1e38962SHarish Patil adapter->ipgre.num_filters = 0; 27207cf0f102SHarish Patil if (is_vf) { 27217cf0f102SHarish Patil adapter->vxlan.enable = true; 2722295968d1SFerruh Yigit adapter->vxlan.filter_type = RTE_ETH_TUNNEL_FILTER_IMAC | 2723295968d1SFerruh Yigit RTE_ETH_TUNNEL_FILTER_IVLAN; 2724c8b34b7eSHarish Patil adapter->vxlan.udp_port = QEDE_VXLAN_DEF_PORT; 2725c8b34b7eSHarish Patil adapter->geneve.enable = true; 2726295968d1SFerruh Yigit adapter->geneve.filter_type = RTE_ETH_TUNNEL_FILTER_IMAC | 2727295968d1SFerruh Yigit RTE_ETH_TUNNEL_FILTER_IVLAN; 27287cf0f102SHarish Patil adapter->geneve.udp_port = QEDE_GENEVE_DEF_PORT; 2729e1e38962SHarish Patil adapter->ipgre.enable = true; 2730295968d1SFerruh Yigit adapter->ipgre.filter_type = RTE_ETH_TUNNEL_FILTER_IMAC | 2731295968d1SFerruh Yigit RTE_ETH_TUNNEL_FILTER_IVLAN; 27327cf0f102SHarish Patil } else { 27337cf0f102SHarish Patil adapter->vxlan.enable = false; 27347cf0f102SHarish Patil adapter->geneve.enable = false; 2735e1e38962SHarish Patil adapter->ipgre.enable = false; 27369ffe2a15SManish Chopra qed_ops->sriov_configure(edev, pci_dev->max_vfs); 27377cf0f102SHarish Patil } 2738dbac54c2SHarish Patil 2739c2c4f87bSAman Deep Singh DP_INFO(edev, "MAC address : " RTE_ETHER_ADDR_PRT_FMT "\n", 2740a7db3afcSAman Deep Singh RTE_ETHER_ADDR_BYTES(&adapter->primary_mac)); 27412ea6f76aSRasesh Mody 27424c4bdadfSHarish Patil DP_INFO(edev, "Device initialized\n"); 27434c4bdadfSHarish Patil 27444c4bdadfSHarish Patil return 0; 27452b5243d7SRasesh Mody 27462b5243d7SRasesh Mody err: 27472b5243d7SRasesh Mody if (do_once) { 2748f97b56f9SRasesh Mody qede_print_adapter_info(eth_dev); 27492b5243d7SRasesh Mody do_once = false; 27502b5243d7SRasesh Mody } 27512b5243d7SRasesh Mody return rc; 27522ea6f76aSRasesh Mody } 27532ea6f76aSRasesh Mody 27542ea6f76aSRasesh Mody static int qedevf_eth_dev_init(struct rte_eth_dev *eth_dev) 27552ea6f76aSRasesh Mody { 27562ea6f76aSRasesh Mody return qede_common_dev_init(eth_dev, 1); 27572ea6f76aSRasesh Mody } 27582ea6f76aSRasesh Mody 27592ea6f76aSRasesh Mody static int qede_eth_dev_init(struct rte_eth_dev *eth_dev) 27602ea6f76aSRasesh Mody { 27612ea6f76aSRasesh Mody return qede_common_dev_init(eth_dev, 0); 27622ea6f76aSRasesh Mody } 27632ea6f76aSRasesh Mody 27642ea6f76aSRasesh Mody static int qede_dev_common_uninit(struct rte_eth_dev *eth_dev) 27652ea6f76aSRasesh Mody { 2766e8fb98d6SRasesh Mody struct qede_dev *qdev = eth_dev->data->dev_private; 2767e8fb98d6SRasesh Mody struct ecore_dev *edev = &qdev->edev; 2768e8fb98d6SRasesh Mody PMD_INIT_FUNC_TRACE(edev); 27692ea6f76aSRasesh Mody qede_dev_close(eth_dev); 27702ea6f76aSRasesh Mody return 0; 27712ea6f76aSRasesh Mody } 27722ea6f76aSRasesh Mody 27732ea6f76aSRasesh Mody static int qede_eth_dev_uninit(struct rte_eth_dev *eth_dev) 27742ea6f76aSRasesh Mody { 27752ea6f76aSRasesh Mody return qede_dev_common_uninit(eth_dev); 27762ea6f76aSRasesh Mody } 27772ea6f76aSRasesh Mody 27782ea6f76aSRasesh Mody static int qedevf_eth_dev_uninit(struct rte_eth_dev *eth_dev) 27792ea6f76aSRasesh Mody { 27802ea6f76aSRasesh Mody return qede_dev_common_uninit(eth_dev); 27812ea6f76aSRasesh Mody } 27822ea6f76aSRasesh Mody 278328a1fd4fSFerruh Yigit static const struct rte_pci_id pci_id_qedevf_map[] = { 27842ea6f76aSRasesh Mody #define QEDEVF_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev) 27852ea6f76aSRasesh Mody { 278677f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_VF) 27872ea6f76aSRasesh Mody }, 27882ea6f76aSRasesh Mody { 278977f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_IOV) 279077f72221SRasesh Mody }, 279177f72221SRasesh Mody { 279277f72221SRasesh Mody QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_IOV) 27932ea6f76aSRasesh Mody }, 27942ea6f76aSRasesh Mody {.vendor_id = 0,} 27952ea6f76aSRasesh Mody }; 27962ea6f76aSRasesh Mody 279728a1fd4fSFerruh Yigit static const struct rte_pci_id pci_id_qede_map[] = { 27982ea6f76aSRasesh Mody #define QEDE_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev) 27992ea6f76aSRasesh Mody { 280077f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980E) 28012ea6f76aSRasesh Mody }, 28022ea6f76aSRasesh Mody { 280377f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980S) 28042ea6f76aSRasesh Mody }, 28052ea6f76aSRasesh Mody { 280677f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_40) 28072ea6f76aSRasesh Mody }, 28082ea6f76aSRasesh Mody { 280977f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_25) 28102ea6f76aSRasesh Mody }, 28112af14ca7SHarish Patil { 281277f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_100) 281377f72221SRasesh Mody }, 281477f72221SRasesh Mody { 2815e6512107SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_50) 2816e6512107SRasesh Mody }, 2817e6512107SRasesh Mody { 281877f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_50G) 281977f72221SRasesh Mody }, 282077f72221SRasesh Mody { 282177f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_10G) 282277f72221SRasesh Mody }, 282377f72221SRasesh Mody { 282477f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_40G) 282577f72221SRasesh Mody }, 282677f72221SRasesh Mody { 282777f72221SRasesh Mody QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_25G) 28282af14ca7SHarish Patil }, 28292ea6f76aSRasesh Mody {.vendor_id = 0,} 28302ea6f76aSRasesh Mody }; 28312ea6f76aSRasesh Mody 2832fdf91e0fSJan Blunck static int qedevf_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 2833fdf91e0fSJan Blunck struct rte_pci_device *pci_dev) 2834fdf91e0fSJan Blunck { 2835fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_probe(pci_dev, 2836fdf91e0fSJan Blunck sizeof(struct qede_dev), qedevf_eth_dev_init); 2837fdf91e0fSJan Blunck } 2838fdf91e0fSJan Blunck 2839fdf91e0fSJan Blunck static int qedevf_eth_dev_pci_remove(struct rte_pci_device *pci_dev) 2840fdf91e0fSJan Blunck { 2841fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_remove(pci_dev, qedevf_eth_dev_uninit); 2842fdf91e0fSJan Blunck } 2843fdf91e0fSJan Blunck 2844fdf91e0fSJan Blunck static struct rte_pci_driver rte_qedevf_pmd = { 28452ea6f76aSRasesh Mody .id_table = pci_id_qedevf_map, 2846b76fafb1SDavid Marchand .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 2847fdf91e0fSJan Blunck .probe = qedevf_eth_dev_pci_probe, 2848fdf91e0fSJan Blunck .remove = qedevf_eth_dev_pci_remove, 28492ea6f76aSRasesh Mody }; 28502ea6f76aSRasesh Mody 2851fdf91e0fSJan Blunck static int qede_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 2852fdf91e0fSJan Blunck struct rte_pci_device *pci_dev) 2853fdf91e0fSJan Blunck { 2854fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_probe(pci_dev, 2855fdf91e0fSJan Blunck sizeof(struct qede_dev), qede_eth_dev_init); 2856fdf91e0fSJan Blunck } 2857fdf91e0fSJan Blunck 2858fdf91e0fSJan Blunck static int qede_eth_dev_pci_remove(struct rte_pci_device *pci_dev) 2859fdf91e0fSJan Blunck { 2860fdf91e0fSJan Blunck return rte_eth_dev_pci_generic_remove(pci_dev, qede_eth_dev_uninit); 2861fdf91e0fSJan Blunck } 2862fdf91e0fSJan Blunck 2863fdf91e0fSJan Blunck static struct rte_pci_driver rte_qede_pmd = { 28642ea6f76aSRasesh Mody .id_table = pci_id_qede_map, 2865b76fafb1SDavid Marchand .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 2866fdf91e0fSJan Blunck .probe = qede_eth_dev_pci_probe, 2867fdf91e0fSJan Blunck .remove = qede_eth_dev_pci_remove, 28682ea6f76aSRasesh Mody }; 28692ea6f76aSRasesh Mody 2870fdf91e0fSJan Blunck RTE_PMD_REGISTER_PCI(net_qede, rte_qede_pmd); 287101f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_qede, pci_id_qede_map); 287206e81dc9SDavid Marchand RTE_PMD_REGISTER_KMOD_DEP(net_qede, "* igb_uio | uio_pci_generic | vfio-pci"); 2873fdf91e0fSJan Blunck RTE_PMD_REGISTER_PCI(net_qede_vf, rte_qedevf_pmd); 287401f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_qede_vf, pci_id_qedevf_map); 287506e81dc9SDavid Marchand RTE_PMD_REGISTER_KMOD_DEP(net_qede_vf, "* igb_uio | vfio-pci"); 2876eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(qede_logtype_init, init, NOTICE); 2877eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(qede_logtype_driver, driver, NOTICE); 2878