136cf85c8SOleksandr Kolomeiets /* 236cf85c8SOleksandr Kolomeiets * SPDX-License-Identifier: BSD-3-Clause 336cf85c8SOleksandr Kolomeiets * Copyright(c) 2023 Napatech A/S 436cf85c8SOleksandr Kolomeiets */ 536cf85c8SOleksandr Kolomeiets 636cf85c8SOleksandr Kolomeiets #ifndef _FLOW_API_H_ 736cf85c8SOleksandr Kolomeiets #define _FLOW_API_H_ 836cf85c8SOleksandr Kolomeiets 92407c755SSerhii Iliushyk #include <rte_spinlock.h> 101d3f62a0SOleksandr Kolomeiets 110ea00f33SOleksandr Kolomeiets #include "ntlog.h" 120ea00f33SOleksandr Kolomeiets 131d3f62a0SOleksandr Kolomeiets #include "flow_api_engine.h" 148df4a5f8SOleksandr Kolomeiets #include "hw_mod_backend.h" 151d3f62a0SOleksandr Kolomeiets #include "stream_binary_flow_api.h" 161d3f62a0SOleksandr Kolomeiets 171d3f62a0SOleksandr Kolomeiets /* 181d3f62a0SOleksandr Kolomeiets * Flow NIC and Eth port device management 191d3f62a0SOleksandr Kolomeiets */ 201d3f62a0SOleksandr Kolomeiets 211d3f62a0SOleksandr Kolomeiets struct hw_mod_resource_s { 221d3f62a0SOleksandr Kolomeiets uint8_t *alloc_bm; /* allocation bitmap */ 231d3f62a0SOleksandr Kolomeiets uint32_t *ref; /* reference counter for each resource element */ 241d3f62a0SOleksandr Kolomeiets uint32_t resource_count;/* number of total available entries */ 251d3f62a0SOleksandr Kolomeiets }; 261d3f62a0SOleksandr Kolomeiets 271d3f62a0SOleksandr Kolomeiets /* 281d3f62a0SOleksandr Kolomeiets * Device Management API 291d3f62a0SOleksandr Kolomeiets */ 301d3f62a0SOleksandr Kolomeiets int flow_delete_eth_dev(struct flow_eth_dev *eth_dev); 311d3f62a0SOleksandr Kolomeiets 327fa0bf29SDanylo Vodopianov /** 337fa0bf29SDanylo Vodopianov * A structure used to configure the Receive Side Scaling (RSS) feature 347fa0bf29SDanylo Vodopianov * of an Ethernet port. 357fa0bf29SDanylo Vodopianov */ 367fa0bf29SDanylo Vodopianov struct nt_eth_rss_conf { 377fa0bf29SDanylo Vodopianov /** 387fa0bf29SDanylo Vodopianov * In rte_eth_dev_rss_hash_conf_get(), the *rss_key_len* should be 397fa0bf29SDanylo Vodopianov * greater than or equal to the *hash_key_size* which get from 407fa0bf29SDanylo Vodopianov * rte_eth_dev_info_get() API. And the *rss_key* should contain at least 417fa0bf29SDanylo Vodopianov * *hash_key_size* bytes. If not meet these requirements, the query 427fa0bf29SDanylo Vodopianov * result is unreliable even if the operation returns success. 437fa0bf29SDanylo Vodopianov * 447fa0bf29SDanylo Vodopianov * In rte_eth_dev_rss_hash_update() or rte_eth_dev_configure(), if 457fa0bf29SDanylo Vodopianov * *rss_key* is not NULL, the *rss_key_len* indicates the length of the 467fa0bf29SDanylo Vodopianov * *rss_key* in bytes and it should be equal to *hash_key_size*. 477fa0bf29SDanylo Vodopianov * If *rss_key* is NULL, drivers are free to use a random or a default key. 487fa0bf29SDanylo Vodopianov */ 497fa0bf29SDanylo Vodopianov uint8_t rss_key[MAX_RSS_KEY_LEN]; 507fa0bf29SDanylo Vodopianov /** 517fa0bf29SDanylo Vodopianov * Indicates the type of packets or the specific part of packets to 527fa0bf29SDanylo Vodopianov * which RSS hashing is to be applied. 537fa0bf29SDanylo Vodopianov */ 547fa0bf29SDanylo Vodopianov uint64_t rss_hf; 557fa0bf29SDanylo Vodopianov /** 567fa0bf29SDanylo Vodopianov * Hash algorithm. 577fa0bf29SDanylo Vodopianov */ 587fa0bf29SDanylo Vodopianov enum rte_eth_hash_function algorithm; 597fa0bf29SDanylo Vodopianov }; 607fa0bf29SDanylo Vodopianov 617fa0bf29SDanylo Vodopianov int sprint_nt_rss_mask(char *str, uint16_t str_len, const char *prefix, uint64_t hash_mask); 627fa0bf29SDanylo Vodopianov 631d3f62a0SOleksandr Kolomeiets struct flow_eth_dev { 641d3f62a0SOleksandr Kolomeiets /* NIC that owns this port device */ 651d3f62a0SOleksandr Kolomeiets struct flow_nic_dev *ndev; 661d3f62a0SOleksandr Kolomeiets /* NIC port id */ 671d3f62a0SOleksandr Kolomeiets uint8_t port; 68b01eb812SDanylo Vodopianov /* App assigned port_id - may be DPDK port_id */ 69b01eb812SDanylo Vodopianov uint32_t port_id; 701d3f62a0SOleksandr Kolomeiets 711d3f62a0SOleksandr Kolomeiets /* 0th for exception */ 721d3f62a0SOleksandr Kolomeiets struct flow_queue_id_s rx_queue[FLOW_MAX_QUEUES + 1]; 731d3f62a0SOleksandr Kolomeiets 741d3f62a0SOleksandr Kolomeiets /* VSWITCH has exceptions sent on queue 0 per design */ 751d3f62a0SOleksandr Kolomeiets int num_queues; 761d3f62a0SOleksandr Kolomeiets 77b01eb812SDanylo Vodopianov /* QSL_HSH index if RSS needed QSL v6+ */ 78b01eb812SDanylo Vodopianov int rss_target_id; 79b01eb812SDanylo Vodopianov 80e7e01fd1SDanylo Vodopianov /* The size of buffer for aged out flow list */ 81e7e01fd1SDanylo Vodopianov uint32_t nb_aging_objects; 82e7e01fd1SDanylo Vodopianov 831d3f62a0SOleksandr Kolomeiets struct flow_eth_dev *next; 841d3f62a0SOleksandr Kolomeiets }; 858df4a5f8SOleksandr Kolomeiets 867fa0bf29SDanylo Vodopianov enum flow_nic_hash_e { 877fa0bf29SDanylo Vodopianov HASH_ALGO_ROUND_ROBIN = 0, 887fa0bf29SDanylo Vodopianov HASH_ALGO_5TUPLE, 897fa0bf29SDanylo Vodopianov }; 907fa0bf29SDanylo Vodopianov 9136cf85c8SOleksandr Kolomeiets /* registered NIC backends */ 928df4a5f8SOleksandr Kolomeiets struct flow_nic_dev { 937917b0d3SOleksandr Kolomeiets uint8_t adapter_no; /* physical adapter no in the host system */ 947917b0d3SOleksandr Kolomeiets uint16_t ports; /* number of in-ports addressable on this NIC */ 95b01eb812SDanylo Vodopianov /* flow profile this NIC is initially prepared for */ 96b01eb812SDanylo Vodopianov enum flow_eth_dev_profile flow_profile; 972005c549SSerhii Iliushyk int flow_mgnt_prepared; 987917b0d3SOleksandr Kolomeiets 991d3f62a0SOleksandr Kolomeiets struct hw_mod_resource_s res[RES_COUNT];/* raw NIC resource allocation table */ 1001d3f62a0SOleksandr Kolomeiets void *km_res_handle; 1011d3f62a0SOleksandr Kolomeiets void *kcc_res_handle; 1021d3f62a0SOleksandr Kolomeiets 1034033e053SDanylo Vodopianov void *flm_mtr_handle; 1048385ba0eSSerhii Iliushyk void *group_handle; 1058385ba0eSSerhii Iliushyk void *hw_db_handle; 1068385ba0eSSerhii Iliushyk void *id_table_handle; 1078385ba0eSSerhii Iliushyk 1081d3f62a0SOleksandr Kolomeiets uint32_t flow_unique_id_counter; 1091d3f62a0SOleksandr Kolomeiets /* linked list of all flows created on this NIC */ 1101d3f62a0SOleksandr Kolomeiets struct flow_handle *flow_base; 111e02fdb65SSerhii Iliushyk /* linked list of all FLM flows created on this NIC */ 112e02fdb65SSerhii Iliushyk struct flow_handle *flow_base_flm; 1132407c755SSerhii Iliushyk rte_spinlock_t flow_mtx; 1141d3f62a0SOleksandr Kolomeiets 1158df4a5f8SOleksandr Kolomeiets /* NIC backend API */ 1168df4a5f8SOleksandr Kolomeiets struct flow_api_backend_s be; 1171d3f62a0SOleksandr Kolomeiets /* linked list of created eth-port devices on this NIC */ 1181d3f62a0SOleksandr Kolomeiets struct flow_eth_dev *eth_base; 1192407c755SSerhii Iliushyk rte_spinlock_t mtx; 1201d3f62a0SOleksandr Kolomeiets 1218eed292bSSerhii Iliushyk /* RSS hashing configuration */ 1228eed292bSSerhii Iliushyk struct nt_eth_rss_conf rss_conf; 1231d3f62a0SOleksandr Kolomeiets /* next NIC linked list */ 1241d3f62a0SOleksandr Kolomeiets struct flow_nic_dev *next; 1258df4a5f8SOleksandr Kolomeiets }; 12636cf85c8SOleksandr Kolomeiets 12711ea9780SSerhii Iliushyk enum flow_nic_err_msg_e { 12811ea9780SSerhii Iliushyk ERR_SUCCESS = 0, 12911ea9780SSerhii Iliushyk ERR_FAILED = 1, 1306fec9a9aSSerhii Iliushyk ERR_MEMORY = 2, 13111ea9780SSerhii Iliushyk ERR_OUTPUT_TOO_MANY = 3, 1326fec9a9aSSerhii Iliushyk ERR_RSS_TOO_MANY_QUEUES = 4, 1336fec9a9aSSerhii Iliushyk ERR_VLAN_TYPE_NOT_SUPPORTED = 5, 1346fec9a9aSSerhii Iliushyk ERR_VXLAN_HEADER_NOT_ACCEPTED = 6, 1356fec9a9aSSerhii Iliushyk ERR_VXLAN_POP_INVALID_RECIRC_PORT = 7, 1366fec9a9aSSerhii Iliushyk ERR_VXLAN_POP_FAILED_CREATING_VTEP = 8, 1376fec9a9aSSerhii Iliushyk ERR_MATCH_VLAN_TOO_MANY = 9, 1386fec9a9aSSerhii Iliushyk ERR_MATCH_INVALID_IPV6_HDR = 10, 1396fec9a9aSSerhii Iliushyk ERR_MATCH_TOO_MANY_TUNNEL_PORTS = 11, 14011ea9780SSerhii Iliushyk ERR_MATCH_INVALID_OR_UNSUPPORTED_ELEM = 12, 1416fec9a9aSSerhii Iliushyk ERR_MATCH_FAILED_BY_HW_LIMITS = 13, 14211ea9780SSerhii Iliushyk ERR_MATCH_RESOURCE_EXHAUSTION = 14, 1436fec9a9aSSerhii Iliushyk ERR_MATCH_FAILED_TOO_COMPLEX = 15, 1446fec9a9aSSerhii Iliushyk ERR_ACTION_REPLICATION_FAILED = 16, 1456fec9a9aSSerhii Iliushyk ERR_ACTION_OUTPUT_RESOURCE_EXHAUSTION = 17, 1466fec9a9aSSerhii Iliushyk ERR_ACTION_TUNNEL_HEADER_PUSH_OUTPUT_LIMIT = 18, 1476fec9a9aSSerhii Iliushyk ERR_ACTION_INLINE_MOD_RESOURCE_EXHAUSTION = 19, 1486fec9a9aSSerhii Iliushyk ERR_ACTION_RETRANSMIT_RESOURCE_EXHAUSTION = 20, 1496fec9a9aSSerhii Iliushyk ERR_ACTION_FLOW_COUNTER_EXHAUSTION = 21, 1506fec9a9aSSerhii Iliushyk ERR_ACTION_INTERNAL_RESOURCE_EXHAUSTION = 22, 1516fec9a9aSSerhii Iliushyk ERR_INTERNAL_QSL_COMPARE_FAILED = 23, 1526fec9a9aSSerhii Iliushyk ERR_INTERNAL_CAT_FUNC_REUSE_FAILED = 24, 1536fec9a9aSSerhii Iliushyk ERR_MATCH_ENTROPHY_FAILED = 25, 1546fec9a9aSSerhii Iliushyk ERR_MATCH_CAM_EXHAUSTED = 26, 1556fec9a9aSSerhii Iliushyk ERR_INTERNAL_VIRTUAL_PORT_CREATION_FAILED = 27, 15611ea9780SSerhii Iliushyk ERR_ACTION_UNSUPPORTED = 28, 15711ea9780SSerhii Iliushyk ERR_REMOVE_FLOW_FAILED = 29, 1586fec9a9aSSerhii Iliushyk ERR_ACTION_NO_OUTPUT_DEFINED_USE_DEFAULT = 30, 1596fec9a9aSSerhii Iliushyk ERR_ACTION_NO_OUTPUT_QUEUE_FOUND = 31, 1606fec9a9aSSerhii Iliushyk ERR_MATCH_UNSUPPORTED_ETHER_TYPE = 32, 16111ea9780SSerhii Iliushyk ERR_OUTPUT_INVALID = 33, 1626fec9a9aSSerhii Iliushyk ERR_MATCH_PARTIAL_OFFLOAD_NOT_SUPPORTED = 34, 1636fec9a9aSSerhii Iliushyk ERR_MATCH_CAT_CAM_EXHAUSTED = 35, 1646fec9a9aSSerhii Iliushyk ERR_MATCH_KCC_KEY_CLASH = 36, 1656fec9a9aSSerhii Iliushyk ERR_MATCH_CAT_CAM_FAILED = 37, 1666fec9a9aSSerhii Iliushyk ERR_PARTIAL_FLOW_MARK_TOO_BIG = 38, 1676fec9a9aSSerhii Iliushyk ERR_FLOW_PRIORITY_VALUE_INVALID = 39, 16811ea9780SSerhii Iliushyk ERR_ACTION_MULTIPLE_PORT_ID_UNSUPPORTED = 40, 1696fec9a9aSSerhii Iliushyk ERR_RSS_TOO_LONG_KEY = 41, 1706fec9a9aSSerhii Iliushyk ERR_ACTION_AGE_UNSUPPORTED_GROUP_0 = 42, 171*c4e84cd7SSerhii Iliushyk ERR_MSG_NO_MSG = 43, 172*c4e84cd7SSerhii Iliushyk ERR_MSG_END 17311ea9780SSerhii Iliushyk }; 17411ea9780SSerhii Iliushyk 17511ea9780SSerhii Iliushyk void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error); 17611ea9780SSerhii Iliushyk 1771d3f62a0SOleksandr Kolomeiets /* 1781d3f62a0SOleksandr Kolomeiets * Resources 1791d3f62a0SOleksandr Kolomeiets */ 1801d3f62a0SOleksandr Kolomeiets 1811d3f62a0SOleksandr Kolomeiets extern const char *dbg_res_descr[]; 1821d3f62a0SOleksandr Kolomeiets 183b01eb812SDanylo Vodopianov #define flow_nic_set_bit(arr, x) \ 184b01eb812SDanylo Vodopianov do { \ 185b01eb812SDanylo Vodopianov uint8_t *_temp_arr = (arr); \ 186b01eb812SDanylo Vodopianov size_t _temp_x = (x); \ 187b01eb812SDanylo Vodopianov _temp_arr[_temp_x / 8] = \ 188b01eb812SDanylo Vodopianov (uint8_t)(_temp_arr[_temp_x / 8] | (uint8_t)(1 << (_temp_x % 8))); \ 189b01eb812SDanylo Vodopianov } while (0) 190b01eb812SDanylo Vodopianov 1911d3f62a0SOleksandr Kolomeiets #define flow_nic_unset_bit(arr, x) \ 1921d3f62a0SOleksandr Kolomeiets do { \ 1931d3f62a0SOleksandr Kolomeiets size_t _temp_x = (x); \ 1941d3f62a0SOleksandr Kolomeiets arr[_temp_x / 8] &= (uint8_t)(~(1 << (_temp_x % 8))); \ 1951d3f62a0SOleksandr Kolomeiets } while (0) 1961d3f62a0SOleksandr Kolomeiets 1971d3f62a0SOleksandr Kolomeiets #define flow_nic_is_bit_set(arr, x) \ 1981d3f62a0SOleksandr Kolomeiets ({ \ 1991d3f62a0SOleksandr Kolomeiets size_t _temp_x = (x); \ 2001d3f62a0SOleksandr Kolomeiets (arr[_temp_x / 8] & (uint8_t)(1 << (_temp_x % 8))); \ 2011d3f62a0SOleksandr Kolomeiets }) 2021d3f62a0SOleksandr Kolomeiets 203b01eb812SDanylo Vodopianov #define flow_nic_mark_resource_used(_ndev, res_type, index) \ 204b01eb812SDanylo Vodopianov do { \ 205b01eb812SDanylo Vodopianov struct flow_nic_dev *_temp_ndev = (_ndev); \ 206b01eb812SDanylo Vodopianov typeof(res_type) _temp_res_type = (res_type); \ 207b01eb812SDanylo Vodopianov size_t _temp_index = (index); \ 208b01eb812SDanylo Vodopianov NT_LOG(DBG, FILTER, "mark resource used: %s idx %zu", \ 209b01eb812SDanylo Vodopianov dbg_res_descr[_temp_res_type], _temp_index); \ 210b01eb812SDanylo Vodopianov assert(flow_nic_is_bit_set(_temp_ndev->res[_temp_res_type].alloc_bm, \ 211b01eb812SDanylo Vodopianov _temp_index) == 0); \ 212b01eb812SDanylo Vodopianov flow_nic_set_bit(_temp_ndev->res[_temp_res_type].alloc_bm, _temp_index); \ 213b01eb812SDanylo Vodopianov } while (0) 214b01eb812SDanylo Vodopianov 2151d3f62a0SOleksandr Kolomeiets #define flow_nic_mark_resource_unused(_ndev, res_type, index) \ 2161d3f62a0SOleksandr Kolomeiets do { \ 2171d3f62a0SOleksandr Kolomeiets typeof(res_type) _temp_res_type = (res_type); \ 2181d3f62a0SOleksandr Kolomeiets size_t _temp_index = (index); \ 2191d3f62a0SOleksandr Kolomeiets NT_LOG(DBG, FILTER, "mark resource unused: %s idx %zu", \ 2201d3f62a0SOleksandr Kolomeiets dbg_res_descr[_temp_res_type], _temp_index); \ 2211d3f62a0SOleksandr Kolomeiets flow_nic_unset_bit((_ndev)->res[_temp_res_type].alloc_bm, _temp_index); \ 2221d3f62a0SOleksandr Kolomeiets } while (0) 2231d3f62a0SOleksandr Kolomeiets 2241d3f62a0SOleksandr Kolomeiets #define flow_nic_is_resource_used(_ndev, res_type, index) \ 2251d3f62a0SOleksandr Kolomeiets (!!flow_nic_is_bit_set((_ndev)->res[res_type].alloc_bm, index)) 2261d3f62a0SOleksandr Kolomeiets 227b01eb812SDanylo Vodopianov int flow_nic_alloc_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, 228b01eb812SDanylo Vodopianov uint32_t alignment); 229b01eb812SDanylo Vodopianov 23098e40f83SDanylo Vodopianov int flow_nic_alloc_resource_config(struct flow_nic_dev *ndev, enum res_type_e res_type, 23198e40f83SDanylo Vodopianov unsigned int num, uint32_t alignment); 2321d3f62a0SOleksandr Kolomeiets void flow_nic_free_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int idx); 2331d3f62a0SOleksandr Kolomeiets 23498e40f83SDanylo Vodopianov int flow_nic_ref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index); 2351d3f62a0SOleksandr Kolomeiets int flow_nic_deref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index); 2361d3f62a0SOleksandr Kolomeiets 2377fa0bf29SDanylo Vodopianov int flow_nic_set_hasher(struct flow_nic_dev *ndev, int hsh_idx, enum flow_nic_hash_e algorithm); 2387fa0bf29SDanylo Vodopianov int flow_nic_set_hasher_fields(struct flow_nic_dev *ndev, int hsh_idx, 2397fa0bf29SDanylo Vodopianov struct nt_eth_rss_conf rss_conf); 2407fa0bf29SDanylo Vodopianov 241971245aaSDanylo Vodopianov int flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size); 242971245aaSDanylo Vodopianov 24336cf85c8SOleksandr Kolomeiets #endif 244