1 /* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * Copyright(c) 2023 Napatech A/S 4 */ 5 6 #ifndef _FLOW_API_H_ 7 #define _FLOW_API_H_ 8 9 #include <rte_spinlock.h> 10 11 #include "ntlog.h" 12 13 #include "flow_api_engine.h" 14 #include "hw_mod_backend.h" 15 #include "stream_binary_flow_api.h" 16 17 /* 18 * Flow NIC and Eth port device management 19 */ 20 21 struct hw_mod_resource_s { 22 uint8_t *alloc_bm; /* allocation bitmap */ 23 uint32_t *ref; /* reference counter for each resource element */ 24 uint32_t resource_count;/* number of total available entries */ 25 }; 26 27 /* 28 * Device Management API 29 */ 30 int flow_delete_eth_dev(struct flow_eth_dev *eth_dev); 31 32 /** 33 * A structure used to configure the Receive Side Scaling (RSS) feature 34 * of an Ethernet port. 35 */ 36 struct nt_eth_rss_conf { 37 /** 38 * In rte_eth_dev_rss_hash_conf_get(), the *rss_key_len* should be 39 * greater than or equal to the *hash_key_size* which get from 40 * rte_eth_dev_info_get() API. And the *rss_key* should contain at least 41 * *hash_key_size* bytes. If not meet these requirements, the query 42 * result is unreliable even if the operation returns success. 43 * 44 * In rte_eth_dev_rss_hash_update() or rte_eth_dev_configure(), if 45 * *rss_key* is not NULL, the *rss_key_len* indicates the length of the 46 * *rss_key* in bytes and it should be equal to *hash_key_size*. 47 * If *rss_key* is NULL, drivers are free to use a random or a default key. 48 */ 49 uint8_t rss_key[MAX_RSS_KEY_LEN]; 50 /** 51 * Indicates the type of packets or the specific part of packets to 52 * which RSS hashing is to be applied. 53 */ 54 uint64_t rss_hf; 55 /** 56 * Hash algorithm. 57 */ 58 enum rte_eth_hash_function algorithm; 59 }; 60 61 int sprint_nt_rss_mask(char *str, uint16_t str_len, const char *prefix, uint64_t hash_mask); 62 63 struct flow_eth_dev { 64 /* NIC that owns this port device */ 65 struct flow_nic_dev *ndev; 66 /* NIC port id */ 67 uint8_t port; 68 /* App assigned port_id - may be DPDK port_id */ 69 uint32_t port_id; 70 71 /* 0th for exception */ 72 struct flow_queue_id_s rx_queue[FLOW_MAX_QUEUES + 1]; 73 74 /* VSWITCH has exceptions sent on queue 0 per design */ 75 int num_queues; 76 77 /* QSL_HSH index if RSS needed QSL v6+ */ 78 int rss_target_id; 79 80 /* The size of buffer for aged out flow list */ 81 uint32_t nb_aging_objects; 82 83 struct flow_eth_dev *next; 84 }; 85 86 enum flow_nic_hash_e { 87 HASH_ALGO_ROUND_ROBIN = 0, 88 HASH_ALGO_5TUPLE, 89 }; 90 91 /* registered NIC backends */ 92 struct flow_nic_dev { 93 uint8_t adapter_no; /* physical adapter no in the host system */ 94 uint16_t ports; /* number of in-ports addressable on this NIC */ 95 /* flow profile this NIC is initially prepared for */ 96 enum flow_eth_dev_profile flow_profile; 97 int flow_mgnt_prepared; 98 99 struct hw_mod_resource_s res[RES_COUNT];/* raw NIC resource allocation table */ 100 void *km_res_handle; 101 void *kcc_res_handle; 102 103 void *flm_mtr_handle; 104 void *group_handle; 105 void *hw_db_handle; 106 void *id_table_handle; 107 108 uint32_t flow_unique_id_counter; 109 /* linked list of all flows created on this NIC */ 110 struct flow_handle *flow_base; 111 /* linked list of all FLM flows created on this NIC */ 112 struct flow_handle *flow_base_flm; 113 rte_spinlock_t flow_mtx; 114 115 /* NIC backend API */ 116 struct flow_api_backend_s be; 117 /* linked list of created eth-port devices on this NIC */ 118 struct flow_eth_dev *eth_base; 119 rte_spinlock_t mtx; 120 121 /* RSS hashing configuration */ 122 struct nt_eth_rss_conf rss_conf; 123 /* next NIC linked list */ 124 struct flow_nic_dev *next; 125 }; 126 127 enum flow_nic_err_msg_e { 128 ERR_SUCCESS = 0, 129 ERR_FAILED = 1, 130 ERR_MEMORY = 2, 131 ERR_OUTPUT_TOO_MANY = 3, 132 ERR_RSS_TOO_MANY_QUEUES = 4, 133 ERR_VLAN_TYPE_NOT_SUPPORTED = 5, 134 ERR_VXLAN_HEADER_NOT_ACCEPTED = 6, 135 ERR_VXLAN_POP_INVALID_RECIRC_PORT = 7, 136 ERR_VXLAN_POP_FAILED_CREATING_VTEP = 8, 137 ERR_MATCH_VLAN_TOO_MANY = 9, 138 ERR_MATCH_INVALID_IPV6_HDR = 10, 139 ERR_MATCH_TOO_MANY_TUNNEL_PORTS = 11, 140 ERR_MATCH_INVALID_OR_UNSUPPORTED_ELEM = 12, 141 ERR_MATCH_FAILED_BY_HW_LIMITS = 13, 142 ERR_MATCH_RESOURCE_EXHAUSTION = 14, 143 ERR_MATCH_FAILED_TOO_COMPLEX = 15, 144 ERR_ACTION_REPLICATION_FAILED = 16, 145 ERR_ACTION_OUTPUT_RESOURCE_EXHAUSTION = 17, 146 ERR_ACTION_TUNNEL_HEADER_PUSH_OUTPUT_LIMIT = 18, 147 ERR_ACTION_INLINE_MOD_RESOURCE_EXHAUSTION = 19, 148 ERR_ACTION_RETRANSMIT_RESOURCE_EXHAUSTION = 20, 149 ERR_ACTION_FLOW_COUNTER_EXHAUSTION = 21, 150 ERR_ACTION_INTERNAL_RESOURCE_EXHAUSTION = 22, 151 ERR_INTERNAL_QSL_COMPARE_FAILED = 23, 152 ERR_INTERNAL_CAT_FUNC_REUSE_FAILED = 24, 153 ERR_MATCH_ENTROPHY_FAILED = 25, 154 ERR_MATCH_CAM_EXHAUSTED = 26, 155 ERR_INTERNAL_VIRTUAL_PORT_CREATION_FAILED = 27, 156 ERR_ACTION_UNSUPPORTED = 28, 157 ERR_REMOVE_FLOW_FAILED = 29, 158 ERR_ACTION_NO_OUTPUT_DEFINED_USE_DEFAULT = 30, 159 ERR_ACTION_NO_OUTPUT_QUEUE_FOUND = 31, 160 ERR_MATCH_UNSUPPORTED_ETHER_TYPE = 32, 161 ERR_OUTPUT_INVALID = 33, 162 ERR_MATCH_PARTIAL_OFFLOAD_NOT_SUPPORTED = 34, 163 ERR_MATCH_CAT_CAM_EXHAUSTED = 35, 164 ERR_MATCH_KCC_KEY_CLASH = 36, 165 ERR_MATCH_CAT_CAM_FAILED = 37, 166 ERR_PARTIAL_FLOW_MARK_TOO_BIG = 38, 167 ERR_FLOW_PRIORITY_VALUE_INVALID = 39, 168 ERR_ACTION_MULTIPLE_PORT_ID_UNSUPPORTED = 40, 169 ERR_RSS_TOO_LONG_KEY = 41, 170 ERR_ACTION_AGE_UNSUPPORTED_GROUP_0 = 42, 171 ERR_MSG_NO_MSG = 43, 172 ERR_MSG_END 173 }; 174 175 void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error); 176 177 /* 178 * Resources 179 */ 180 181 extern const char *dbg_res_descr[]; 182 183 #define flow_nic_set_bit(arr, x) \ 184 do { \ 185 uint8_t *_temp_arr = (arr); \ 186 size_t _temp_x = (x); \ 187 _temp_arr[_temp_x / 8] = \ 188 (uint8_t)(_temp_arr[_temp_x / 8] | (uint8_t)(1 << (_temp_x % 8))); \ 189 } while (0) 190 191 #define flow_nic_unset_bit(arr, x) \ 192 do { \ 193 size_t _temp_x = (x); \ 194 arr[_temp_x / 8] &= (uint8_t)(~(1 << (_temp_x % 8))); \ 195 } while (0) 196 197 #define flow_nic_is_bit_set(arr, x) \ 198 ({ \ 199 size_t _temp_x = (x); \ 200 (arr[_temp_x / 8] & (uint8_t)(1 << (_temp_x % 8))); \ 201 }) 202 203 #define flow_nic_mark_resource_used(_ndev, res_type, index) \ 204 do { \ 205 struct flow_nic_dev *_temp_ndev = (_ndev); \ 206 typeof(res_type) _temp_res_type = (res_type); \ 207 size_t _temp_index = (index); \ 208 NT_LOG(DBG, FILTER, "mark resource used: %s idx %zu", \ 209 dbg_res_descr[_temp_res_type], _temp_index); \ 210 assert(flow_nic_is_bit_set(_temp_ndev->res[_temp_res_type].alloc_bm, \ 211 _temp_index) == 0); \ 212 flow_nic_set_bit(_temp_ndev->res[_temp_res_type].alloc_bm, _temp_index); \ 213 } while (0) 214 215 #define flow_nic_mark_resource_unused(_ndev, res_type, index) \ 216 do { \ 217 typeof(res_type) _temp_res_type = (res_type); \ 218 size_t _temp_index = (index); \ 219 NT_LOG(DBG, FILTER, "mark resource unused: %s idx %zu", \ 220 dbg_res_descr[_temp_res_type], _temp_index); \ 221 flow_nic_unset_bit((_ndev)->res[_temp_res_type].alloc_bm, _temp_index); \ 222 } while (0) 223 224 #define flow_nic_is_resource_used(_ndev, res_type, index) \ 225 (!!flow_nic_is_bit_set((_ndev)->res[res_type].alloc_bm, index)) 226 227 int flow_nic_alloc_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, 228 uint32_t alignment); 229 230 int flow_nic_alloc_resource_config(struct flow_nic_dev *ndev, enum res_type_e res_type, 231 unsigned int num, uint32_t alignment); 232 void flow_nic_free_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int idx); 233 234 int flow_nic_ref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index); 235 int flow_nic_deref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index); 236 237 int flow_nic_set_hasher(struct flow_nic_dev *ndev, int hsh_idx, enum flow_nic_hash_e algorithm); 238 int flow_nic_set_hasher_fields(struct flow_nic_dev *ndev, int hsh_idx, 239 struct nt_eth_rss_conf rss_conf); 240 241 int flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size); 242 243 #endif 244